2014-06-19 82 views
1

如何在uart中接收字符串。我使用了AVR Studio 5和brays终端这样一个接收字符串

enter image description here

同这张照片我使用的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封信。我希望有人能为此提供帮助。 谢谢。

+1

我想知道为什么UART接收函数返回'unsigned long long',特别是,在像AVR这样的8位MCU中? –

+0

'_delay_ms(100)的用途是什么? USART_Transmit(数据);'在主程序中? – pingul

+0

你确定上面的代码是正确的吗?你声明'USART_Receive',然后调用'Usart_Receive'。您还可以将'Usart_Receive'的返回值分配给'unsigned char',这很可能是'unsigned long long'。并且你只传递一个字符到'USART_Transmit',但是在函数内部它是一个'unsigned long'转换成关于'_delay_ms(100);'@pingul'的'unsigned long long' –

回答

-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; 
} 

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

3

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

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

当前接收顺序是这样的:

  • Usart_Receive()正在等待第一个char“一”
  • UDR立刻清零通过读
  • 等待100毫秒(UDR不读在这段时间)
  • 100ms的延迟期间(记住,传送5个字符只需要大约5毫秒)
    • “b”被接收到UDR
    • 'C' 被待决的第一个FIFO字节
    • 'd' 的接收序列中还没有任何
    • 'E' 将覆盖 'd'
    • 'F' 将覆盖 'e' 的
  • 100毫秒之后你回声 '一'
  • 'b' 是从UDR读取, 'C' 是从FIFO字节到UDR和 'F' 移动移动到第一FIFO字节
  • 100ms的暂停
  • 回波'b'
  • 'c' 的从UDR读, 'f' 被从FIFO字节移动到UDR
  • 100ms的暂停
  • 回波 'c' 的
  • 'f' 被从UDR
  • 100ms的暂停
  • 回声 'F'

- > ABCF

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