是否可以将AVR端口用作可以传递的变量?
例如
LED myLed(PORTA,7); //myLED hooked to PORTA, Pin 7
我想让LED能够采用任何PORT / Pin组合,所以我宁愿不用硬编码。
请注意,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构造器的输出? 这将涉及为给定端口#找到相对DDR#寄存器。 我可以假设&amp; DDR#将永远是&amp; PORT#-1?
答案 0 :(得分: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();
答案 1 :(得分:3)
这是我的做法,我对AVR不太了解,
#include <avr/io.h>
void LED(volatile uint8_t* port, uint8_t pin)
{
// First set DDRx ; DDRx on ATmega32 is one address below port address
*(port -1) |= (1<< pin);
// Now set the pin high
*port |= (1<< pin);
}
int main(void)
{
LED(&PORTB,1);
LED(&PORTC,2);
LED(&PORTD,3);
while (1)
{
}
}
答案 2 :(得分: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)