我正在使用avr-gcc为PID控制器开发一个小型库。尽管在头文件中声明了该函数并在.c文件中单独定义了它,编译器仍会抛出以下错误:
Compiling C: pid.c
avr-gcc -c -mmcu=atmega16 -I. -gdwarf-2 -DF_CPU=1000000UL -Os -funsigned-char -
funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-
adhlns=./pid.lst -std=gnu99 -MMD -MP -MF .dep/pid.o.d pid.c -o pid.o
pid.c:5: error: expected declaration specifiers or '...' before '(' token
pid.c:5: warning: function declaration isn't a prototype
pid.c:5: error: 'type name' declared as function returning a function
pid.c:5: error: conflicting types for 'PID_init'
pid.h:23: error: previous declaration of 'PID_init' was here
pid.c: In function 'PID_init':
pid.c:5: error: parameter name omitted
pid.h的头文件内容如下:
#include<avr/io.h>
#include<util/delay.h>
#ifndef PID_CONTROLLER
#define PID_CONTROLLER
struct PIDCONTROL
{
float error;
float prev_error;
float Kp;
float Ki;
float Kd;
float pid;
float P;
float I;
float D;
float setpoint;
};
void PID_init(float,float,float,float,struct PIDCONTROL*);
float PID(float,struct PIDCONTROL*);
#endif
已声明函数的定义是在pid.c中定义的,其中包含以下代码:
#include<avr/io.h>
#include<util/delay.h>
#include "pid.h"
void PID_init(float SP,float Kp,float Ki,float Kd,struct PIDCONTROL *a)
{
a->Kp=Kp;
a->Ki=Ki;
a->Kd=Kd;
a->pid=0;
a->setpoint=SP;
a->prev_error=0;
}
float PID(float PV,struct PIDCONTROL *a)
{
a->error=(a->setpoint)-PV;
a->P=(a->Kp)*(a->error);
(a->I)+=(a->Ki)*(a->error)*1.024;
a->D=(a->Kd)*((a->error)-(a->prev_error))/1.024;
a->pid=(a->P)+(a->I)+(a->D);
a->prev_error=a->error;
return(a->pid);
}
我不知道密码怎么了。如有任何帮助,我们将不胜感激。
最佳答案
avr/io.h
文件还引入了包含以下小片段的avr/common.h
:
/*
Stack pointer register.
AVR architecture 1 has no RAM, thus no stack pointer.
All other architectures do have a stack pointer. Some devices have only
less than 256 bytes of possible RAM locations (128 Bytes of SRAM
and no option for external RAM), thus SPH is officially "reserved"
for them.
*/
# ifndef SP
# define SP _SFR_MEM16(0x3D)
# endif
(事实上,这要复杂得多,有多条路径取决于您的体系结构,但这个简化示例至少显示了实际的问题所在)。
它实际上是为
SP
定义了一个预处理器宏,这意味着,当您试图在代码中使用它时,函数定义的行数如下:void PID_init(float SP,float Kp,float Ki,float Kd,struct PIDCONTROL *a)
实际上你会得到的是:
void PID_init(float _SFR_MEM16(0x3D),float Kp,float Ki,float Kd,struct PIDCONTROL *a)
这将导致编译器阶段的抱怨。
实际上,我非常相信合理地自我描述变量名,因此通常会选择比
SP
更详细的名称,但您可能会发现,即使您将其设置为mySP
,它也会解决眼前的问题。关于c - 错误:"typename"声明为返回函数的函数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25226196/