2012-01-05 2 views
0

Я не вижу изменений в памяти в файле .map, когда я пытаюсь сравнить два разных кода. Есть ли «хорошая практика», чтобы следовать здесь? Должен ли я или не должен помещать переменные в заголовок? В качестве примечания, я могу иметь несколько функций PIDUpdate(), у меня уже есть два (если это имеет значение).определить переменные в заголовке вместо функции (не глобальные) в C

Первый пример без переменных в заголовке -> 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); 
     } 

Другой пример с variabels в заголовке вместо -> 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); 
    } 
+0

Что вы пытаетесь достичь? И почему вы используете статические локальные переменные в современном мире? Они были плохими новостями 20 лет назад. Теперь вы просто гарантируете, что у вас может быть только один ПИД-регулятор во всем процессе. –

+0

BTW, суффикс '_t' обычно зарезервирован для typedefs, а не для имен переменных. И использование префикса '_' для переменных, локальных для функции, является нечетным. Большинство стандартов кодирования C используют '_' для указания частной (вместо общедоступной) функции или глобальной переменной. – tomlogic

+0

благодаря tomlogic, Im в процессе обучения;) – Christian

ответ

2

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

1

Фактически, вы определяете только типы данных в своем main.h. На самом деле нет никаких переменных (даже если это похоже на этот отступ).

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

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

foo.h

ехЬегп INT some_global;

foo.c

INT some_global;

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

+0

спасибо, это было обучение. Почему это безумие, чтобы иметь статичность в typedef? Это заставляет мою функцию запоминать эти значения переменных, не создавая новых статических переменных внутри функции (сохранение памяти)? – Christian

+0

@Christian: в декларации внутри вашей функции проще включить 'static'. 'static Pid_Object _StatPID;' Кто-то, читающий эту функцию (может быть, через несколько лет), сразу узнает, что это статическая структура, не обязательно вернувшись к определению 'StaticPid_object'. – tomlogic

+0

А ... так удобнее ехать в Pid_Object Static StatPID? – Christian

1

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

Смежные вопросы