2012-01-05 6 views
0

2つの異なるコードを比較しようとすると、私の.mapファイルでメモリの変更を見ることができません。 ここには「良い習慣」がありますか?ヘッダーに変数を入れてはいけませんか? メモとして、私は複数のPIDUpdate()関数を持つことができます、私はすでに2つを持っています(違いがあれば)。ヘッダ内の変数無しC言語でfunction(グローバルではなく)の代わりに変数を定義する

第1の例 - > 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年前、彼らは悪い知らせでした。これで、プロセス全体で1つのPIDコントローラしか使用できないことが保証されました。 –

+0

ところで、 '_t'サフィックスは通常、変数名ではなくtypedefのために予約されています。また、関数のローカル変数の '_'接頭辞を使うことは奇妙です。ほとんどのC言語のコーディング標準では、 '_'を使用して、公的関数ではなくプライベート関数またはグローバル変数を示しています。 – tomlogic

+0

おかげさまでmlogic、Imの学習プロセス;) – Christian

答えて

2

あなたのコードがどこにあるかは関係ありません - .hまたは.cにありますが、静的変数を定義するヘッダーを複数のファイルに含めると、ファイルごとに異なるインスタンスが作成されます。ここで重要なのは、これがあなたが望むものならば。

1

実際には、main.h内のデータ型のみを定義しています。実際にそこには変数はありません(その字下げのように見えますが)。

私は、typedefにstaticを含めて狂っていると言いますし、そうする理由はありません。

伝統的に、foo.c、bar.cおよびbaz.cを持つプログラムでは、foo.hファイルにfoo.cの外に見える必要があるグローバル変数のデータ型、関数宣言およびexternバージョンがあります。同様に、bar.hとbaz.hと同様です。 extern int型some_global

がfoo.h

foo.cの

int型some_global。

だから、foo.cあなたのプログラムがリンクされている物資some_global、およびbar.cbaz.cはそれが何であるかを知っているだろう。 int foo;が可変fooextern int foo;にストレージを割り当てる定義であること

+0

ありがとう、それは教育的だった。なぜtypedefで静的にするのは夢中ですか?それは関数内で新しい静的変数を作ることなく(メモリを節約して)それらの変数値を覚えておく機能を果たしますか? – Christian

+0

@Christian:あなたの関数内部の宣言に 'static'を含めることは明らかです。 '静的Pid_Object _StatPID;'誰かが(おそらく数年後に)その関数を読んでいると、確かに 'StaticPid_object'の定義に戻らなくても静的構造であることを直ちに知ることができます。 – tomlogic

+0

ああ... Pid_Object Static StatPIDに行く方が便利ですか? – Christian

1

注変数fooのストレージが既に与えられているという宣言です。ヘッダファイルに定義を入れることができますが、ヘッダファイルを含むいくつかのソースファイルをリンクすると、再定義エラーが発生することがあります。通常、必要に応じてヘッダーに宣言を挿入し、対応するソースファイルに変数を定義します。他のソースファイルにはリンクフェーズ中にそれらが表示されます。

関連する問題