gpt4 book ai didi

c - ATmega2560使用UART中断来控制全局标志

转载 作者:行者123 更新时间:2023-11-30 21:07:52 26 4
gpt4 key购买 nike

我最近在玩ATmega2560时遇到了一个问题,我真的不明白它出了什么问题。

这是我的代码。

主要:

#include "Definitions.h"

int main(void) {
Initialization();
while (1) {
//_delay_ms(1); // or printf...
//wait for RXC flag
if (RxFlag) {
//wait for new byte in
//PORTB &= ~(1 << PB7);
PORTB |= (1 << PB7);
rxcount = 0;
UDR0 = 'R';
RxFlag = false;
TxFlag = false;
}
}
}

中断请求:

#include "Definitions.h"

ISR(USART0_RX_vect) {
while(!(UCSR0A & (1 << RXC0)))
//wait for RXC flag
;
/* Loop-back test */
//PORTB |= (1 << PB7);
//test_data = UDR0;
TxFlag = true;
//enableUDRI0();
//PORTB &= ~(1 << PB7);
//PORTB |= (1 << PB7);
RxBuffer[rxcount++] = UDR0;
if(!(rxcount < RX_BUF_SZ)) {
//rxcount = 0;
PORTB |= (1 << PB7);
RxFlag = true;
}
}

ISR(USART0_UDRE_vect) {
while(!(UCSR0A & (1 << UDRE0)))
//wait for udr to be empty
;
/* Loop-back test */
UDR0 = 0x30 + rxcount;
disableUDRI0();
}

问题是,当我从 USART 接收到一些数据时,我尝试设置一个 RxFlag 来激活主循环中的 if 语句。但直到我取消注释 if 语句之前的函数(可能是 _delay_ms() 或 printf())时,它才起作用。

这没有任何意义。我记得的是,我不需要这些函数,它仍然可以设置全局变量来影响主循环。或者是我遗漏了什么细节?请给我一些线索来解决这个问题,我很困惑。

最佳答案

不可能确定,但​​我认为这解释了您的问题,因此很可能是错误。

您没有包含 RXFlag 的声明,但我推测您没有将其声明为 volatile 。除非您这样做,否则编译器可以假设它知道该变量将发生的一切。特别是它知道,除非 main() 调用任何其他函数,否则 RxFlag 的值永远不会改变。因此它可以通过将 if 表达式移到循环之外来优化它。实际上,它正在更改您的代码,如下所示:

#include "Definitions.h"

int main(void)
{
register bool x;

Initialization();

x = RxFlag;

while (1)
{
//wait for RXC flag
if (x) //wait for new byte in
{
//PORTB &= ~(1 << PB7);
PORTB |= (1 << PB7);
rxcount = 0;
UDR0 = 'R';
RxFlag = false;
TxFlag = false;

}
}
}

但是,如果 main() 调用另一个函数,则编译器会放弃尝试通过该调用将 RxFlag 保留在寄存器中。另一个函数可能会更改保存 RxFlag 的寄存器。它必须将其推送到堆栈或其他东西上。再次读取它在代码和时间上都更便宜,因此每次循环时都会读取它。

此错误的正确修复方法是将主线程和 ISR 之间共享的所有变量声明为 volatile

关于c - ATmega2560使用UART中断来控制全局标志,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41549624/

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