gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-02 21:37:22 27 4
gpt4 key购买 nike

昨晚,我和一个 friend 遇到了一个异常现象,我们试图理解它,但无法理解。当时我们正在使用 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);
}

上面的代码是正确的,LED 每 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 的硬拷贝),第 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/

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