设置PINx时会发生什么?为什么它有时会起作用?

 破背包 发布于 2023-02-03 12:47

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

我注意到他的代码中有一个错误,他将LED设置为高(后来为低)PINB,6.我告诉他使用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);  
}

上面的代码是正确的,led每500ms切换一次

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的设置方式,我只是想了解它为什么会这样做.

1 个回答
  • 您遇到了ATmega系列经常被忽略的功能:在PINx寄存器中设置一个位可以切换PORTx中的相应位.

    从ATmega328P数据表中的第77页开始:

    14.2.2切换销钉

    向PINxn写入逻辑1会切换PORTxn的值,与DDRxn的值无关.请注意,SBI指令可用于在端口中切换一个位.

    2023-02-03 12:49 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有