6

渡すことができる変数として AVR ポートを使用することは可能ですか?

例えば

LED myLed(PORTA,7);   //myLED hooked to PORTA, Pin 7

LED を任意の PORT / ピンの組み合わせにできるようにしたいので、ハードコーディングはしたくありません。

PORT は次のように定義されていることに注意してください。

#define PINA  _SFR_IO8(0x00)
#define DDRA  _SFR_IO8(0x01)
#define PORTA _SFR_IO8(0x02)    

PORTA シンボルは (*(volatile uint8_t *)((0x02) + 0x20)) に解決されます

これにより、次のようなことができると思いますが、 volatile キーワードが必要かどうか、実際に期待どおりに機能するかどうかはわかりません

class LED{
public:
    LED(volatile uint8_t* port, uint8_t pin);
    {
        Port=port;
        Pin=pin;
    }
    void write(bool val)
    {
        if(val) (*Port) |= 1 << Pin;
        else    (*Port) &= ~(1 << Pin);
    }

private:
    uint8_t  Pin
    volatile uint8_t* Port;
}

最後に、ポート/ピンを LED コンストラクターからの出力として設定する方法はありますか? これには、指定された PORT# の相対 DDR# レジスタを見つけることが含まれます。&DDR# は常に &PORT#-1 であると想定できますか?

4

3 に答える 3

6

レジスタ マクロは基本的に、適切なレジスタが存在するメモリ位置へのポインタであるため、uint8_t volatile *. ただし、コンパイラはこの方法では最も効率的なコードを生成しません。直接書き込みの代わりに間接アドレッシングを使用します。

これは、代わりにavrlibを使用して行うことです。

#include <avrlib/porta.hpp>
#include <avrlib/pin.hpp>
using namespace avrlib;

typedef pin<porta, 4> led_pin;

led_pin次に、 typedefを使用できます。

led_pin::set();
于 2012-12-04T13:42:22.557 に答える
0

ポートは I/O アドレスにすぎないため、I/O ポートのアドレスを LED コンストラクターに渡すだけです。

LED *light = new LED(&PORTA, 4);

なぜこれが機能するのですか?PORTA は、既に述べたように、ポインターの逆参照に解決されます。

(*(volatile uint8_t *)((0x02) + 0x20))

したがって、演算子のアドレスを前に追加すると、作成されます

&(*(volatile uint8_t *)((0x02) + 0x20))

これは次のように簡略化できます

(volatile uint8_t *)((0x02) + 0x20)
于 2012-12-06T14:50:06.227 に答える