2012-12-04 78 views
4

是否可以將AVR端口用作可以傳遞的變量?將端口作爲變量傳遞 - AVR

例如

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

我想使LED能夠採取任何端口/引腳的組合,所以我會英寸

注意,而不是硬編碼的端口被定義爲:

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

PORTA符號解析爲(*(揮發性uint8_t *)((0×02)+ 0×20))

我相信這會讓我像做以下,但我不確定我是否需要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?

+0

你也可以使用一點結構... – neagoegab

+0

你會介意擴展嗎?我不確定你的意思是什麼struct – DanChianucci

+0

'struct port {UINT8 _port_1_0:1; UINT8 _port_1_2:1; ...};' - 這在C中更好/更好。但是如果你有C++和模板,avakar例子會更好。 – neagoegab

回答

5

寄存器宏基本上是指向內存位置的指針,適當的寄存器位於哪裏,所以是的,你可以使用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(); 
+0

我還沒有意識到這些,謝謝,我會研究它們 – DanChianucci

+0

到圖書館的鏈接不再有效(網站已關閉)。 –

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) 
+4

嗯,.....'new'? :) – avakar