0

ヘッダー ファイルをマクロで簡単に変更できるようにしようとしています。私は自分のコードをデバッグしていますが、これらの MACROS は本来の動作をしていないようです。誰かが次の効果を達成する方法を教えてもらえますか? LED_ID_AMS など

#define LED_NUMBER                  (2)
#define LED_ID_X                    (0)
#define LED_ID_Y                    (1)
#define LED_PIN_X                   (0)
#define LED_PIN_Y                   (3)
#define LED_PORT_X                  (PORTE)
#define LED_PORT_Y                  (PORTG)
#define LED_DD_X                    (DDRE)
#define LED_DD_Y                    (DDRG)
#define LED_PORT(LED_ID_X)          (LED_PORT_X)
#define LED_PORT(LED_ID_Y)          (LED_PORT_Y)
#define LED_PIN(LED_ID_X)           (LED_PIN_X)
#define LED_PIN(LED_ID_Y)           (LED_PIN_Y)
#define LED_DD(LED_ID_X)            (LED_DD_X)
#define LED_DD(LED_ID_Y)            (LED_DD_Y)

私は何を達成しようとしていますか?

次のようにポートの初期化をループできるようにしようとしています。

for(i=0;i<LED_NUMBER;i++){
    /* set data direction to output*/
    LED_DD(i)|=((0x01)<<LED_PIN(i));
    /* turn on led */
    LED_PORT(i)|=((0x01)<<LED_PIN(i));
}
4

3 に答える 3

1

後でマクロを使いすぎたことを後悔するでしょう。実際、それらは機能せず、マクロであるため、デバッグが非常に難しいため、すでに後悔しています。

ほんの数点:

  • あなたのLED_PIN(i)表現は常に広がっています0
  • あなたの表現は常に何にでもLED_PORT(i)広がっていますPORTE

たとえば、LED_PIN(LED_ID_X)に展開されLED_PIN_Xます。マクロ パラメータLED_ID_Xはまったく使用されないことに注意してください。代わりに、LED_PIN_X単純に に展開し0ます。

于 2014-03-16T17:23:53.360 に答える
0

次の少なくとも 1 つを追加する必要があります。

  • 配列
  • インライン関数
  • より複雑なマクロ

また、ハードウェア アドレスの逆参照が必要になると思われます。

たとえば、マクロを使用して、次を定義できます。

#define LED_PORT(i) *(uint16_t *)( \
    (i) == LED_ID_X ? LED_PORT_X : \
    (i) == LED_ID_Y ? LED_PORT_Y : \
    etc)

どこ:

#define LED_ID_X     (0)
#define LED_ID_Y     (1)
#define LED_PORT_X   (PORTE)
#define LED_PORT_Y   (PORTG)
#define PORTE        (0x11112222U) // example only
#define PORTG        (0x33334444U) // example only

uint16_tこれは推測にすぎません: 32 ビットのアドレス空間に 16 ビットのポートがあると想定しています。

または、配列と C99 の指定された初期化子を使用します。

const uint32_t LED_PORT[] = {
    [LED_ID_X] = LED_PORT_X,
    [LED_ID_Y] = LED_PORT_Y
};

#define LED_PORT(i) (*(uint16_t *)LED_PORT[i])

そしてもちろん、C99 がなければ、次のものだけを使用できます。

const uint32_t LED_PORT[] = {LED_PORT_X, LED_PORT_Y};

などであると仮定LED_ID_Xます0

于 2014-03-16T20:11:03.160 に答える
0

LED_PORT(SOME_ARG)たとえば、いくつかの定義があるため、これは警告を発するはずです。そしてLED_PORT(LED_ID_X)LED_ID_Xは単なる仮引数であり、定数とはまったく関係ありませんLED_ID_X

おそらくここでやろうとしているようなマクロから使用される定数配列を使用することで、コードを同等に読みやすくすることができます。

大量のがない限りLED_ID_<foo>、これはせいぜいマイナーな単純化です。そうしないでください。多くのコードがそれらとほぼ同じ方法で処理されている場合、それらのそれぞれに対して何らかのアクションを繰り返すマクロを定義することは理にかなっているかもしれません。

#define FROB_LEDS \\
     action(LED_ID_X); \\
     action(LED_ID_Y); \\
     action(LED_ID_Z);

action(X)LED でアクションを実行するマクロとしてローカルに定義しXFROBそれらをaction再度定義解除します。かなり醜い、本当です。

于 2014-03-16T21:55:28.553 に答える