Свежие обсуждения
Микроконтроллеры

Не получается производить передачу по USART

Только начал заниматься данным вопросом. Код пишу CodeVision и
эмулирую на AVR Studio. ВОзникла такая проблема:

При передаче по USART циклом :
unsigned char x=1;
while (1)
{
USART_SendChar(x);
x++;
};

код подпрограммы передачи:
void USART_SendChar(unsigned char sym)
{
while(!(UCSR0A & (1UDRE)));
{
UDR0 = sym;
PORTB = sym;
}
}

Два раза все проходит нормально, в регистр UDR0 записывается значение sym и вроде все проходит нормально, однако при третьем прооде программа намертво встает при провеке условия цикла, причем не пропускает его, как если бы оно не выполнялось, а просто намертво на нем встает.

Инициализация проводится кодом сгенерированным Codevision, по сути вот он:

// USART0 initialization
// Communication Parameters: 8 Data, 2 Stop, No Parity
// USART0 Receiver: On
// USART0 Transmitter: On
// USART0 Mode: Asynchronous
// USART0 Baud Rate: 9600
UCSR0A=0x00;
UCSR0B=0xD8;
UCSR0C=0x0E;
UBRR0H=0x00;
UBRR0L=0x0C;

 

Misha980: программа намертво встает при провеке условия цикла, причем не пропускает его, как если бы оно не выполнялось, а просто намертво на нем встает.
И должна вставать.

Misha980: while(!(UCSR0A & (1UDRE)));
Читается по русски: до тех пор пока UCSR0A либо 1UDRE равны нулю - не сходить с этого места, и только когда они оба равны единице - идти дальше.

 

Misha980: while(!(UCSR0A & (1UDRE)));
А точка с запятой в конце не лишняя?
С ней как раз и будет так как написал rfc выше.

Если вот это:
{
UDR0 = sym;
PORTB = sym;
}

должно выполнятся в том цикле while, то ; после условия цикла надо убрать.

 

while(!(UCSR0A & (1UDRE)));

вот так конечно же, не правильный код привел, извините.

 

без точки с запятой цикл вообще ни разу не проходит.

А сама функция была взята из даташита контроллера.

 

Точка с запятой там нужна. Этот цикл - ожидание освобождения ресурсов (по идее). Что там точно должно быть - сказать затрудняюсь, т.к. с АВР не работаю.

Misha980: while(!(UCSR0A & (1UDRE)));
- Крутиться на одном месте, пока не закончится предыдущая передача

Misha980: UDR0 = sym;
PORTB = sym;

-Поместить в буфер следующий байт.

После этого программа продолжает выполняться. Если передача байта завершается раньше, чем поступает следующий, то на цикле while зависания не будет. Если же байт не успел уйти, то пока он передаётся и будет контроллер висеть на while.

 

rfc: Точка с запятой там нужна. Этот цикл - ожидание освобождения ресурсов (по идее).
Если это так, тогда не понятны скобки сразу за wihle:
{
...
...
}
При Вашей правоте они там не нужны.
Так что всё же склоняюсь к тому что точкка с запятой там лишняя. Ну или скобкы лишние

 

Арс: Так что всё же склоняюсь к тому что точкка с запятой там лишняя. Ну или скобкы лишние
Скорей скобки.
Лишние и сам расставляю - программу визуально разделяет, и удобнее folding делать поблочно.

 

Используйте для отладки и моделирования AVR PIC 8051 ARM Motorola супер программу PROTEUS - там реальный терминал и можно подключать модель вашего устройства к вашим РЕАЛЬНЫМ портам COM и USB.

 

Misha980: кодом сгенерированным Codevision

Посмотрите там есть галочки "задействовать прерывания" и "создать буферы" приема и передачи. Это очень удобно и нет пустых ожиданий.