Получить строку

Как получить строку в UART. Я использую AVR Studio 5 и Brays Terminal, как этот

Так же, как на этой картинке, я использую скорость 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 буквы. Я надеюсь, что кто-нибудь может помочь с этим. ПОБЛАГОДАРИТЬ.

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

Спасибо за тех, кто помогает мне до этого.

Как уже отмечалось в одном из комментариев, вы заявляете USART_Receive но позвони Usart_Receive, Это даже не должно компилироваться (по крайней мере, без предупреждения), так как C чувствителен к регистру. Вы также должны изменить возвращаемое значение на char или uint8_t.

Фактическая причина проблемы, которую вы получаете /echo 'abcf', когда вы фактически отправляете 'abcdef', вероятно, является _delay_ms(100);, Передача символа со скоростью 9600 бод занимает около 1 мс.
Контроллеры AVR предоставляют только очень маленький FIFO (один или два байта) на приемной стороне, который будет переполнен, если регистр UDR не будет считан через соответствующий интервал (очевидно, в зависимости от скорости передачи).

Текущая последовательность приема будет выглядеть примерно так:

  • Usart_Receive () ожидает первый символ 'a'
  • UDR сразу очищается, читая его
  • подождите 100 мс (UDR не читается в течение этого времени)
  • во время задержки 100 мс (помните, что передача 5 символов занимает всего около 5 мс)
    • 'b' получено в UDR
    • 'c' находится в ожидании в первом байте FIFO
    • 'd' находится в состоянии ожидания в получающей последовательности
    • 'e' перезапишет 'd'
    • 'f' перезапишет 'e'
  • через 100 мс вы эхо 'а'
  • "b" читается из UDR, "c" перемещается из байта FIFO в UDR, а "f" перемещается в первый байт FIFO
  • Пауза 100 мс
  • эхо "б"
  • 'c' читается из UDR, 'f' перемещается из байта FIFO в UDR
  • Пауза 100 мс
  • эхо "с"
  • 'f' читается из UDR
  • Пауза 100 мс
  • эхо 'F'

-> abcf

Вы должны убедиться, что UDR опрашивается как минимум каждую миллисекунду. Другим решением будет подход, основанный на прерываниях, где вы обрабатываете каждый полученный символ в соответствующем ISR, не рискуя основным кодом, блокирующим ваше считывание UDR.

Другие вопросы по тегам