昨晚,我和一位朋友遇到了一个异常现象,我们正在试图理解,但无法理解。当时我们正在使用AVR组件玩ATTiny2313,今天我在ATMega328P上复制了Arduino的完全相同的体验。
我注意到他的代码中有一个错误,他正在使用PINB,6设置一个LED高(后来是低)。我告诉他要使用PORTB,6,而且(出于其他原因)这根本不起作用。整个代码现在都没有了,所以我在Ardunio C++中复制了它,得到了意想不到的结果:当分配正确的时候,所有的东西都能正常工作,但是当分配错误的时候,发光二极管会以一半的速度闪烁。这似乎是一个分阶段的问题。
在我进入代码之前,我知道您不能通过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 is一次。
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 128-因为我这里有一个PDF的硬拷贝),pp66,图30,通用数字I/O。
电路表明PINx是只读的,但你显然可以设置它,尽管它似乎每隔三台就读一次。
有趣的是,如果您只设置了PINx (如下面的代码所示):
void loop(){
PINB |= 1<<5; // turns on the LED
delay(500);
}LED开关!每隔500毫秒。对清除输出进行同样的尝试不起作用,只是设置它。
再说一遍,我知道输出不是这样设置的,我只是想了解它为什么要做它所做的事情。
发布于 2014-01-13 06:41:32
您已经遇到了ATmega行中一个经常被忽略的特性:在PINx寄存器中设置一个位,在PORTx中切换相应的位。
来自ATmega328P数据表中的第77页
14.2.2切换Pin 将逻辑1写入PINxn,可以切换PORTxn的值,这与DDRxn的值无关。注意,SBI指令可以用来切换端口中的一个位。
https://stackoverflow.com/questions/21083552
复制相似问题