在C中定义头中的变量而不是函数(非全局)

时间:2012-01-05 23:11:29

标签: c header struct

当我尝试比较两个不同的代码时,我在.map文件中看不到任何内存更改。 这里有“好的做法”吗?我应该还是不应该将变量放在标题中? 作为一个注释,我可以有多个PIDUpdate()函数,我已经有两个(如果这有任何区别)。

标题中没有变量的第一个示例 - > main.c中

static int16_t PIDUpdate(int16_t target, int16_t feedback) // Valve
{
static float pTerm, iTerm, dTerm;
static float PID;
int16_t CurrentError;
static float LastError, SumError;
uint16_t tick;
static uint16_t elapsed;
float Kp = 0.1, Ki = 0.1, Kd = 0.1;

Kp = (float) pGain/10000.0;
Ki = (float) iGain/10000.0;
Kd = (float) dGain/10000.0;

....
if(elapsed = tick - timestamp, elapsed < TRACKING_PERIOD)
    goto leave;

timestamp = tick;

CurrentError = target - feedback;

pTerm = Kp * CurrentError;

// Calculate the Integral State with appropriate Limiting
....
iTerm = Ki * SumError;

dTerm = Kd * (LastError - CurrentError);

LastError = CurrentError;

PID = pTerm + iTerm + dTerm;

control = PID;
....
    leave:
return (control);
      }

另一个在标题中使用变量标题的示例 - &gt; main.h

typedef struct PID
{
// PID parameters
uint16_t Kp; // pGain
uint16_t Ki; // iGain
uint16_t Kd; // dGain

// PID calculations
float pTerm;
float iTerm;
float dTerm;
float PID;

// Extra variabels
int16_t CurrentError;

// PID Time
uint16_t tick;

   }pid_object;

   typedef static struct staticPID
   {    
// Extra variabels
int16_t control;
float LastError;
float SumError;

// PID Time
uint16_t elapsed;
uint16_t timestamp;

    }StaticPid_object;

现在main.c代码与上面的.h-file

相关联
static int16_t PIDUpdate(int16_t target, int16_t feedback) // Valve
{
pid_object _PID_t;
StaticPid_object _StatPID_t;

_PID_t.Kp = (float) pGain/10000.0;
_PID_t.Ki = (float) iGain/10000.0;
_PID_t.Kd = (float) dGain/10000.0;

if(_StatPID_t.elapsed = _PID_t.tick - _StatPID_t.timestamp, _StatPID_t.elapsed < TRACKING_PERIOD)
    goto leave;

_StatPID_t.timestamp = _PID_t.tick;

_PID_t.CurrentError = target - feedback;

_PID_t.pTerm = _PID_t.Kp * _PID_t.CurrentError;

// Calculate the Integral State with appropriate Limiting
....

_PID_t.iTerm = _PID_t.Ki * _StatPID_t.SumError;

_PID_t.dTerm = _PID_t.Kd * (_StatPID_t.LastError - _PID_t.CurrentError);

_StatPID_t.LastError = _PID_t.CurrentError;

_PID_t.PID = _PID_t.pTerm + _PID_t.iTerm + _PID_t.dTerm;

_StatPID_t.control = 255-_PID_t.PID; // Make it work oposite to Heater

     leave:
return (_StatPID_t.control);
     }

3 个答案:

答案 0 :(得分:2)

代码的位置无关紧要 - 在.h.c中,但如果在多个文件中包含定义静态变量的标头,则每个文件都有不同的实例。重要的是,如果这是你想要的。

答案 1 :(得分:1)

实际上,您只是在main.h中定义数据类型。那里实际上没有任何变量(即使它看起来像是缩进)。

我会说在typedef中包含static是疯狂的,而且没有理由这样做。

传统上,在使用foo.c,bar.c和baz.c的程序中,文件foo.h具有数据类型,函数声明和需要在foo外部看到的全局变量的extern版本。 C。与bar.h和baz.h一样。

foo.h中

  

extern int some_global;

foo.c的

  

int some_global;

所以foo.c会在您的计划关联时提供some_globalbar.cbaz.c会知道它是什么。

答案 2 :(得分:1)

请注意,int foo;是一个定义,它将为变量foo分配存储空间,extern int foo;是一个声明,表示已经给出了变量foo的存储空间。您可以将定义放在头文件中,但如果链接包含该头文件的多个源文件,则可能会出现重定义错误。通常我们只是在需要时将声明放在标题中,并在相应的源文件中定义变量。其他源文件将在链接阶段看到它们。