将端口作为变量传递 - AVR
Passing a Port as a variable - 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 *)((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#寄存器。我可以假设 &DDR# 将始终为 &PORT#-1 吗?
寄存器宏基本上是指向内存位置的指针,相应的寄存器所在的位置,所以是的,您可以使用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();
这就是我的做法,我在 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)
{
}
}
端口只不过是 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)
相关文章:
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 将数组的地址分配给变量并删除
- 为"adjacent"变量赋值时出现问题
- enum是C++中的宏变量还是整数变量
- 在全局变量中保存类的实例以重新创建类(创建"backup")
- 用C++中的一个变量定义一个常量
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 你能重载对象变量名本身返回的内容吗
- 内置函数可查看CPP中的成员变量
- 是否可以初始化不可复制类型的成员变量(或基类)
- 尝试通过多个向量访问变量时,向量下标超出范围
- 试图让变量检查数组中的某些内容
- Cpp-Tuple使用带有变量的get
- 将包含C样式数组的对象初始化为成员变量(C++)
- 当vector是tje全局变量时,c++中vector的内存管理
- 通过多个头文件使用常量变量
- AVR ASM从变量出发到端口
- 将端口作为变量传递 - AVR
- 未定义的参考(对象变量和基础变量),C++AVR