2012-01-05 8 views
0

當我嘗試比較兩個不同的代碼時,我看不到在我的.map文件中有任何內存變化。 在這裏遵循「良好做法」嗎?我應該還是不應該將變量放在標題中? 作爲一個說明,我可以有多個PIDUpdate()函數,我已經有兩個(如果這有什麼區別)。在C頭文件中定義變量而不是函數(不是全局的)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代碼togheter與以上.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); 
    } 
+0

你想達到什麼目的?爲什麼你在現代使用靜態局部變量?這是20年前的壞消息。現在你只需要保證你的整個過程只能有一個PID控制器。 – 2012-01-05 23:17:36

+0

順便說一句,'_t'後綴通常保留爲typedefs,而不是變量名稱。在一個函數的本地變量上使用'_'前綴是很奇怪的。大多數C編碼標準使用'_'來表示私有(而不是公共)函數或全局變量。 – tomlogic 2012-01-06 00:41:56

+0

謝謝tomlogic,我在學習過程中;) – Christian 2012-01-06 10:54:55

回答

2

無論您的代碼在哪裏 - 在.h.c,但如果在多個文件中包含定義靜態變量的頭文件,則每個文件都有不同的實例。這裏重要的是如果這是你想要的。

1

實際上,您只是在main.h中定義數據類型。實際上並沒有任何變量(儘管它看起來像是那個縮進)。

我會說,包括static在typedef是瘋狂的,沒有理由這樣做。

傳統上,在帶有foo.c,bar.c和baz.c的程序中,文件foo.h具有數據類型,函數聲明和需要在foo.c之外看到的全局變量版本。同樣與bar.h和baz.h.

foo.h中

的extern INT some_global;

foo.c的

INT some_global;

所以foo.c提供some_global當你的程序鏈接,並bar.cbaz.c就會知道它是什麼。

+0

謝謝,那是在教育。爲什麼在typedef中有static是瘋狂的?它使我的函數記住這些變量值而不在函數內部創建新的靜態變量(保存內存)? – Christian 2012-01-05 23:57:47

+0

@Christian:在函數內的聲明中包含'static'更清晰。 'static Pid_Object _StatPID;'有人讀這個函數(也許你在幾年內)會立即知道它是一個靜態結構,而不必返回到'StaticPid_object'的定義。 – tomlogic 2012-01-06 00:39:30

+0

啊...所以去Pid_Object Static StatPID更方便嗎? – Christian 2012-01-06 10:58:30

1

注意int foo;是這會爲變量fooextern int foo;分配存儲的一個定義是一個宣言,稱變量foo的存儲已經給出。您可以將定義放在頭文件中,但如果鏈接包含該頭文件的多個源文件,則可能會出現重定義錯誤。通常,如果需要,我們只需在頭文件中聲明聲明,並在相應的源文件中定義變量。其他源文件將在鏈接階段看到它們。