Получить строку
Как получить строку в 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.