gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-02 04:39:53 25 4
gpt4 key购买 nike

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

我注意到他的代码中有一个错误,他使用 PINB,6 将 LED 设置为 HIGH(然后是 LOW)。我告诉他使用 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 的硬拷贝),第 66 页,图 30,通用数字 I/O。

该电路表明 PINx 是只读的,但您显然可以设置它,尽管它似乎需要每三组设置一次。

有趣的是,如果您只设置 PINx(如以下代码所示:)

void loop(){
PINB |= 1<<5; // turns on the LED
delay(500);
}

LED 切换!每 500 毫秒。尝试清除 OUTPUT 是行不通的,只能设置它。

同样,我知道这不是 OUTPUT 的设置方式,我只是想了解它为什么会这样做。

最佳答案

您遇到了 ATmega 系列的一个经常被忽视的特性:在 PINx 寄存器中设置一个位会切换 PORTx 中的相应位。

ATmega328P datasheet 的第 77 页开始:

14.2.2 Toggling the Pin

Writing a logic one to PINxn toggles the value of PORTxn, independent on the value of DDRxn. Note that the SBI instruction can be used to toggle one single bit in a port.

关于assembly - 设置 PINx 时会发生什么?为什么它有时会起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21083552/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com