如何在uart中接收字符串。我用的是avr工作室5和布雷斯终端
和这张照片一样,我使用的波特率是9600。我试着输入"abcdef"
,它只输出"abcf"
。
我的代码是这样的--->
#include <avr/io.h>
void serial_init(void)
{
UBRRH = 0x00;
UBRRL = 95; //baudrate 9600 and F_CPU 14745600UL
UCSRB = (1 << RXEN) | (1 << TXEN) | (1<<RXCIE);
UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0)|(1 << UCSZ1);
}
unsigned long long Usart_Receive(void)
{
while((UCSRA & (1 << RXC)) == 0) {};
return UDR;
}
void USART_Transmit(unsigned long c)
{
PORTD= 0b00000100; //RTS Enable
while ((UCSRA & (1 << UDRE)) ==0) {};
UDR = c;
PORTD= 0b00000000; //RTS Disable
}
int main(void)
{
unsigned char data;
serial_init();
while (1)
{
data = Usart_Receive();
_delay_ms(100);
USART_Transmit(data);
}
return 0;
}
很简单,但我找不到我的问题,为什么它只出现在终端4个字母。我希望有人能帮忙。
谢谢。
最佳答案
正如已经指出的一条注释,您声明了USART_Receive
,但调用了Usart_Receive
。这甚至不应该编译(至少在没有警告的情况下),因为C是区分大小写的。您还应该将返回值更改为char或uint8。
实际问题的原因可能是,只有在实际发送“abcdef”时才接收/回显“abcf”。以9600波特传输一个字符大约需要1毫秒。
AVR控制器只在接收端提供一个非常小的FIFO(一个或两个字节),如果UDR寄存器在适当的间隔(显然取决于传输速度)后没有被读出,这个FIFO就会溢出。
当前接收序列如下:
Usart_Receive()正在等待第一个字符“a”
读取UDR立即清除
等待100毫秒(在此期间不读取UDR)
在100毫秒的延迟期间(记住传输5个字符只需要大约5毫秒)
“b”被接收到UDR中
“c”在第一个FIFO字节中挂起
“d”在接收序列中挂起
“e”将覆盖“d”
“f”将覆盖“e”
100毫秒后你回响“a”
“b”从UDR读取,“c”从FIFO字节移动到UDR,“f”移动到第一个FIFO字节
100毫秒暂停
回音“b”
“c”从UDR读取,“f”从FIFO字节移动到UDR
100毫秒暂停
回声“c”
从UDR中读取“f”
100毫秒暂停
回音“f”
->abcf公司
你必须确保至少每毫秒对UDR进行一次轮询。另一种解决方案是基于中断的方法,即在相应的ISR中处理每个接收到的字符,而不必冒主代码阻塞UDR读取的风险。