首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >设置PINx时会发生什么?为什么有时会工作?

设置PINx时会发生什么?为什么有时会工作?
EN

Stack Overflow用户
提问于 2014-01-13 03:47:26
回答 1查看 247关注 0票数 2

昨晚,我和一位朋友遇到了一个异常现象,我们正在试图理解,但无法理解。当时我们正在使用AVR组件玩ATTiny2313,今天我在ATMega328P上复制了Arduino的完全相同的体验。

我注意到他的代码中有一个错误,他正在使用PINB,6设置一个LED高(后来是低)。我告诉他要使用PORTB,6,而且(出于其他原因)这根本不起作用。整个代码现在都没有了,所以我在Ardunio C++中复制了它,得到了意想不到的结果:当分配正确的时候,所有的东西都能正常工作,但是当分配错误的时候,发光二极管会以一半的速度闪烁。这似乎是一个分阶段的问题。

在我进入代码之前,我知道您不能通过PIN分配输出,问题是我们尝试了(错误的)并且试图理解它是如何工作的。

代码语言:javascript
复制
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一次。

代码语言:javascript
复制
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 (如下面的代码所示):

代码语言:javascript
复制
void loop(){
  PINB |= 1<<5;    // turns on the LED
  delay(500);
}

LED开关!每隔500毫秒。对清除输出进行同样的尝试不起作用,只是设置它。

再说一遍,我知道输出不是这样设置的,我只是想了解它为什么要做它所做的事情。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-01-13 06:41:32

您已经遇到了ATmega行中一个经常被忽略的特性:在PINx寄存器中设置一个位,在PORTx中切换相应的位。

来自ATmega328P数据表中的第77页

14.2.2切换Pin 将逻辑1写入PINxn,可以切换PORTxn的值,这与DDRxn的值无关。注意,SBI指令可以用来切换端口中的一个位。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21083552

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档