определить переменные в заголовке вместо функции (не глобальной) в C - PullRequest
0 голосов
/ 06 января 2012

Я не вижу никаких изменений памяти в моем файле .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);
      }

Другой пример с переменными в заголовке -> 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-файлом

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 ]

2 голосов
/ 06 января 2012

Неважно, где находится ваш код - в .h или .c, но если вы включите заголовок, определяющий статическую переменную, в несколько файлов, у вас будет свой экземпляр для каждого файла.Что здесь важно, так это то, что вы хотите.

1 голос
/ 06 января 2012

Обратите внимание, что int foo; - это определение, которое будет выделять память для переменной foo, а extern int foo; - это объявление, в котором говорится, что хранилище переменной foo уже задано. Вы можете поместить определения в заголовочный файл, но вы можете получить ошибки переопределения, если связываете несколько исходных файлов, которые включают этот заголовочный файл. Обычно мы просто помещаем объявления в заголовок, если это необходимо, и определяем переменные в соответствующем исходном файле. Другие исходные файлы увидят их на этапе компоновки.

1 голос
/ 06 января 2012

На самом деле вы определяете только типы данных в вашем main.h.Там на самом деле нет никаких переменных (хотя это выглядит так с этим отступом).

Я бы сказал, что включение static в typedef - это безумие, и нет никаких причин для этого.

Традиционно, в программе с foo.c, bar.c и baz.c файл foo.h имеет типы данных, объявления функций и extern версии глобальных переменных, которые должны просматриваться вне foo.c.Аналогично с bar.h и baz.h.

foo.h

extern int some_global;

foo.c

int some_global;

Итак, foo.c предоставляет some_global, когда ваша программа связана, и bar.c и baz.c будут знать, что это такое.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...