罗伯特的回答有一些不准确的断言和不完整的答案。
直接写入端口寄存器可能会破坏端口的其他设置,有时还会对控制器造成永久性损坏。
可能会破坏其他设置:确实,您必须知道自己在做什么(例如,您正在操作的端口上有哪些引脚,并且知道您要保留哪些功能。
可能造成永久性损坏:不是真的,或者最好不是因为端口操纵。如果将短路接地,然后将其设置为输出为 1,则无论您使用的是端口寄存器还是数字写入器,都可能会损坏它。你必须在这两个方面都小心。
现在,回到您的问题,枚举是一种方式,但由于 PORTB、PORTC、PORTD 只是值的简称,您可以设置一个变量,然后使用它来间接访问它。
这种变量的类型是一个指向字节的 volatile 指针(volatile 意味着写和读操作不能被编译器优化,因为值可以在两个操作之间改变):
volatile uint8_t *variablePortRegister;
您只需使用要更改的寄存器的地址(因此使用& 符号)加载它:
variablePortRegister = &PORTC;
然后用指针改变值
PORTC = 0x12;
becomes
(*variablePortRegister) = 0x12;
这是一个简短的例子。要使其工作,请在 arduino 引脚 5(PORTD 的第 5 位)上连接一个带电阻的 LED。板上的 LED(标记为 L)连接到引脚 13(PORTB 的第 5 位)。
草图将使两个 LED 中的一个闪烁五次,然后切换到另一个。只用到了端口操作指令,你会发现读端口的方法和写端口的方法是一样的。
volatile uint8_t *myportreg;
unsigned long lastTime;
uint8_t counter;
void setup() {
DDRB |= 0x20;
DDRD |= 0x20;
PORTB = 0;
PORTD = 0;
counter = 99; // trigger the register change immediately
}
void loop() {
if (counter >= 10)
{
counter = 0;
if (myportreg == &PORTD)
myportreg = &PORTB;
else
myportreg = &PORTD;
}
if ((millis() - lastTime) > 500)
{
lastTime = millis();
// change bit 5 of register
*myportreg = 0x20 ^ (*myportreg);
counter++;
}
}
编辑:正如罗伯特指出的那样,最好只“使用”您需要的引脚(在这种情况下,端口 B 和 D 的第 5 位)而不是设置整个端口;通过这种方式,您可以最大限度地减少搞砸其他事情的风险。上面的代码中已经包含了这个编辑,所以代码是正确的