昨晚,我和一位朋友遇到了一个异常,我们正试图理解,但不能。当我们使用AVR组件玩ATTiny2313时,今天我在ATMega328P上复制了与Arduino完全相同的体验。
我注意到他的代码中有一个错误,他使用PINB,6
将LED设置为高(后来为低)。我告诉他使用PORTB,6
和(由于某些其他原因)根本不起作用。整个代码现在已经消失了,所以我在Ardunio C ++中复制了它并得到了意想不到的结果,正确分配时一切正常,但如果分配不正确,LED会以一半的速率闪烁。这似乎是一个阶段性的问题。
在我进入代码之前,我知道你不能通过PIN
分配输出,问题是我们尝试(错误)并试图了解它是如何工作的。
void setup(){
DDRB=0xFF;
}
void loop(){
PORTB |= 1<<5; // turns on the LED
delay(500);
PORTB &= ~(1<<5); // turns off the LED
delay(500);
}
上面的代码是正确的,并且每隔500毫秒就会切换一次
void setup(){
DDRB=0xFF;
}
void loop(){
PINB |= 1<<5; // turns on the LED
delay(500);
PINB &= ~(1<<5); // turns off the LED
delay(500);
}
现在上面的代码实际上偶尔会起作用。它不是每隔500毫秒打开和关闭,而是每秒打开和关闭!
我已经检查了芯片的电路图(实际上是ATMEga128-因为我这里有PDF的硬拷贝),pp66,图30,通用数字I / O.
电路指示PINx是只读的,但你显然可以设置它,虽然它似乎需要每三个设置。
有趣的是,如果你只设置PINx(如下面的代码:):
void loop(){
PINB |= 1<<5; // turns on the LED
delay(500);
}
LED TOGGLES!每500ms。尝试清除OUTPUT不起作用,只能设置它。
同样,我知道这不是OUTPUT的设置方式,我只是想了解它为什么会这样做。
答案 0 :(得分:5)
您遇到了ATmega系列经常被忽略的功能:在PINx寄存器中设置一个位可切换PORTx中的相应位。
的第77页14.2.2切换Pin
向PINxn写入逻辑1可切换PORTxn的值,与DDRxn的值无关。请注意,SBI指令可用于在端口中切换一个位。