是否可以在不检查 AVR ATMega32 中的 UDRE 标志的情况下将 UDR 写入 USART_RXC 中断处理程序?
Can UDR be written inside USART_RXC interrupt handler without checking the UDRE flag in AVR ATMega32?
我一直在努力理解这段代码,它应该使用中断回显在 AVR 的 USART 接口上接收到的每个字节。
#include
#include
#define USART_BAUDRATE 9600
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
int main (void)
{
UCSRB = (1 << RXEN) | (1 << TXEN); // Turn on the transmission and reception circuitry
UCSRC = (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1); // Use 8-bit character sizes
UBRRH = (BAUD_PRESCALE >> 8); // Load upper 8-bits of the baud rate value into the high byte of the UBRR register
UBRRL = BAUD_PRESCALE; // Load lower 8-bits of the baud rate value into the low byte of the UBRR register
UCSRB |= (1 << RCXIE); // Enable the USART Recieve Complete interrupt (USART_RXC)
sei(); // Enable the Global Interrupt Enable flag so that interrupts can be processed
for (;;) // Loop forever
{
// Do nothing - echoing is handled by the ISR instead of in the main loop
}
}
ISR(USART_RXC_vect)
{
char ReceivedByte;
ReceivedByte = UDR; // Fetch the received byte value into the variable "ByteReceived"
UDR = ReceivedByte; // Echo back the received byte back to the computer
}
我无法理解这部分内容
ISR(USART_RXC_vect)
{
char ReceivedByte;
ReceivedByte = UDR; // Fetch the received byte value into the variable "ByteReceived"
UDR = ReceivedByte; // Echo back the received byte back to the computer
}
为什么不在这里检查UDRE 标志以查看是否确实可以写入新数据,而不会覆盖以前的数据?由于我们在相应的轮询方法中做了同样的事情:
while ((UCSRA & (1 << RXC)) == 0) {}; // Do nothing until data have been received and is ready to be read from UDR
ReceivedByte = UDR; // Fetch the received byte value into the variable "ByteReceived"
while ((UCSRA & (1 << UDRE)) == 0) {}; // Do nothing until UDR is ready for more data to be written to it
UDR = ReceivedByte; // Echo back the received byte back to the computer
不应该在 ISR
中的 UDR = ReceivedByte;
行之前检查 UDRE 标志吗?
任何见解将不胜感激。
简短的回答是 - 是:您可以随时编写 UDR,无需任何提前检查。
但是,如果输出缓冲区已满(未设置 UCSRA 中的 UDRE 标志),则写入的数据将被发送器忽略,换句话说,它将丢失。
USART 模块有一个双输出缓冲器。这意味着可以提前两个字节写入:一个正在传输,缓冲区中的一个稍后传输。当缓冲区字节为空时UDRE标志显示,而TXC标志在传输字节被拉出时显示。
因此,如果您有办法确保发送器缓冲区不会溢出,则可以根本不检查该标志。由于字节的接收需要与传输完全相同的时间,您可以确定 RXC 中断不会比字节传输更频繁地发生,因此,如果 UDR 没有写在其他地方,则可以假设输出缓冲区当 RXC 中断发生时,总是可以接受至少一个字节。
不过,如果UDR写在其他地方,输出缓冲区可能不会为空,当RXC中断发生时,传输的回显字节将丢失。
另一方面,良好的编程习惯是尽快离开中断处理程序。将等待循环放在中断处理程序中是个坏主意。在那种情况下,如果您不能确定输出缓冲区在 RXC 事件中是否为空,最好在 RAM 中有某种输出缓冲区,它将在 UDRE 中断中处理,或者在 RXC 中断之外执行回显。
我一直在努力理解这段代码,它应该使用中断回显在 AVR 的 USART 接口上接收到的每个字节。
#include
#include
#define USART_BAUDRATE 9600
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
int main (void)
{
UCSRB = (1 << RXEN) | (1 << TXEN); // Turn on the transmission and reception circuitry
UCSRC = (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1); // Use 8-bit character sizes
UBRRH = (BAUD_PRESCALE >> 8); // Load upper 8-bits of the baud rate value into the high byte of the UBRR register
UBRRL = BAUD_PRESCALE; // Load lower 8-bits of the baud rate value into the low byte of the UBRR register
UCSRB |= (1 << RCXIE); // Enable the USART Recieve Complete interrupt (USART_RXC)
sei(); // Enable the Global Interrupt Enable flag so that interrupts can be processed
for (;;) // Loop forever
{
// Do nothing - echoing is handled by the ISR instead of in the main loop
}
}
ISR(USART_RXC_vect)
{
char ReceivedByte;
ReceivedByte = UDR; // Fetch the received byte value into the variable "ByteReceived"
UDR = ReceivedByte; // Echo back the received byte back to the computer
}
我无法理解这部分内容
ISR(USART_RXC_vect)
{
char ReceivedByte;
ReceivedByte = UDR; // Fetch the received byte value into the variable "ByteReceived"
UDR = ReceivedByte; // Echo back the received byte back to the computer
}
为什么不在这里检查UDRE 标志以查看是否确实可以写入新数据,而不会覆盖以前的数据?由于我们在相应的轮询方法中做了同样的事情:
while ((UCSRA & (1 << RXC)) == 0) {}; // Do nothing until data have been received and is ready to be read from UDR
ReceivedByte = UDR; // Fetch the received byte value into the variable "ByteReceived"
while ((UCSRA & (1 << UDRE)) == 0) {}; // Do nothing until UDR is ready for more data to be written to it
UDR = ReceivedByte; // Echo back the received byte back to the computer
不应该在 ISR
中的 UDR = ReceivedByte;
行之前检查 UDRE 标志吗?
任何见解将不胜感激。
简短的回答是 - 是:您可以随时编写 UDR,无需任何提前检查。
但是,如果输出缓冲区已满(未设置 UCSRA 中的 UDRE 标志),则写入的数据将被发送器忽略,换句话说,它将丢失。
USART 模块有一个双输出缓冲器。这意味着可以提前两个字节写入:一个正在传输,缓冲区中的一个稍后传输。当缓冲区字节为空时UDRE标志显示,而TXC标志在传输字节被拉出时显示。
因此,如果您有办法确保发送器缓冲区不会溢出,则可以根本不检查该标志。由于字节的接收需要与传输完全相同的时间,您可以确定 RXC 中断不会比字节传输更频繁地发生,因此,如果 UDR 没有写在其他地方,则可以假设输出缓冲区当 RXC 中断发生时,总是可以接受至少一个字节。
不过,如果UDR写在其他地方,输出缓冲区可能不会为空,当RXC中断发生时,传输的回显字节将丢失。
另一方面,良好的编程习惯是尽快离开中断处理程序。将等待循环放在中断处理程序中是个坏主意。在那种情况下,如果您不能确定输出缓冲区在 RXC 事件中是否为空,最好在 RAM 中有某种输出缓冲区,它将在 UDRE 中断中处理,或者在 RXC 中断之外执行回显。