1

如何在 uart 中接收字符串。我正在使用 avr studio 5 和 brays 终端,就像这样

在此处输入图像描述

和这张图片一样,我用的是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 个字母。我希望有人可以帮助解决这个问题。感谢。

4

2 回答 2

3

正如已经指出的评论之一,您声明USART_Receive但调用Usart_Receive. 这甚至不应该编译(至少没有警告),因为 C 是区分大小写的。您还应该将返回值更改为 char 或 uint8_t。

实际发送“abcdef”时仅接收/回显“abcf”的问题的实际原因可能是_delay_ms(100);. 传输一个@9600 波特的字符大约需要 1ms。
AVR 控制器仅在接收端提供一个非常小的 FIFO(一个或两个字节),如果在适当的时间间隔后未读取 UDR 寄存器(显然取决于传输速度),它将溢出。

当前的接收序列将类似于:

  • Usart_Receive() 正在等待第一个字符 'a'
  • UDR通过读取立即清除
  • 等待100ms(这段时间不读取UDR)
  • 在 100 毫秒延迟期间(请记住,传输 5 个字符只需要大约 5 毫秒)
    • 'b' 被接收到 UDR
    • 'c' 在第一个 FIFO 字节中挂起
    • 'd' 在接收序列中挂起
    • 'e' 将覆盖 'd'
    • 'f' 将覆盖 'e'
  • 100 毫秒后你回显“a”
  • 'b' 从 UDR 读取,'c' 从 FIFO 字节移动到 UDR,'f' 移动到第一个 FIFO 字节
  • 100ms 暂停
  • 回声'b'
  • 'c' 从 UDR 读取,'f' 从 FIFO 字节移动到 UDR
  • 100ms 暂停
  • 回声'c'
  • 'f' 从 UDR 中读取
  • 100ms 暂停
  • 回声'f'

-> abcf

您必须确保至少每毫秒轮询一次 UDR。另一种解决方案是基于中断的方法,您可以在相应的 ISR 中处理每个接收到的字符,而不会冒主代码阻塞您的 UDR 读数的风险。

于 2014-06-19T12:03:05.617 回答
-2

这是有效的答案。

int main(void)
 {

    char data[1][40];   
    int i1 = 0;
    int i2 = 0;
        serial_init();

        while (1)
    {

        for (i1=0;i1<1;i1++) 
            { 
               for (i2=0;i2<40;i2++) 
               { 
                  data[i1][i2] = Usart_Receive(); 
               } 
            } 

           for (i1=0;i1<1;i1++) 
           { 
               for (i2=0;i2<40;i2++) 
               { 
                  Usart_Transmit(data[i1][i2]); 
               } 
           }       

      }  
    return 0;   
}

感谢那些在此之前帮助我的人。

于 2014-06-24T07:03:47.243 回答