Easyelectronics.ru

Электроника для всех
Текущее время: 22 янв 2021, 12:10

Часовой пояс: UTC + 5 часов



JLCPCB – Прототипы печатных плат за $2/5шт. два слоя. $5/5шт. четыре слоя
Крупнейший производитель печатных плат и прототипов. Более 600000 клиентов и свыше 10000 заказов в день!
Получите скидку на почтовую отправку при первом заказе в JLCPCB!

Начать новую тему Ответить на тему  [ Сообщений: 11 ] 
Автор Сообщение
 Заголовок сообщения: UART Mega32a. Неверный код конца строки в эхо ответе.
СообщениеДобавлено: 11 мар 2020, 09:48 
Только пришел

Зарегистрирован: 21 ноя 2015, 18:03
Сообщения: 5
Добрый день товарищи. Подскажите, как решить задачу, или хотя бы куда копать.
Суть. Делаю проект в железе на MEGA32A, на данном этапе возникла проблема с эхом ответом по уарт, цифро-буквенные коды уходят и возвращаются правильно, кроме кода конца строки 0x0D. По непонятной причине возвращается 0xED. Сделал отдельно простейший проект - тоже самое.
Если Rx и TX соединить вместе, то эхо ответ правильный. В протеусе код конца строки возвращается правильно.

Изображение
http://prntscr.com/rejjn5

Код:

#define F_CPU 16000000UL

#include <avr/io.h>
#include <avr/interrupt.h>

#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)

unsigned char cmd_char;

void UART_init(long USART_BAUDRATE)         //Init
{
   UCSRB |= (1 << RXCIE);               // Interrupt enable.
   UCSRB |= (1 << RXEN);               // Recieve byte enable.
   UCSRB |= (1 << TXEN);               // Transmit enable.
   
   UCSRC |= (1 << URSEL);               // Switch to register UCSEL
   UCSRC |= (1 << UCSZ1) | (1 << UCSZ0);     // The frame is 8 bits.
   
   UBRRL = BAUD_PRESCALE;             /* Load lower 8-bits of the baud rate value */
   UBRRH = (BAUD_PRESCALE >> 8);         /*Load upper 8-bits*/
}

unsigned char UART_RxChar()
{
   while ((UCSRA & (1 << RXC)) == 0);              /* Wait till data is received */
   return(UDR);                     /* Return the byte*/
}
void UART_TxChar(char ch)
{
   while (! (UCSRA & (1<<UDRE)));         /* Wait for empty transmit buffer*/
   UDR = ch ;
}

ISR(USART_RXC_vect)
{
   cmd_char = UART_RxChar();
   UART_TxChar(cmd_char);
}

int main(void)
{
    UART_init(9600);
    sei();
    while (1)
    {
    }
}



Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: UART Mega32a. Неверный код конца строки в эхо ответе.
СообщениеДобавлено: 11 мар 2020, 11:14 
Старожил

Зарегистрирован: 04 окт 2012, 00:23
Сообщения: 2745
Откуда: Москва
Ни хрена не понял зачем
вот это:

Код:
unsigned char UART_RxChar()
{
   while ((UCSRA & (1 << RXC)) == 0);              /* Wait till data is received */
   return(UDR);                     /* Return the byte*/
}


Если есть это

Код:
ISR(USART_RXC_vect)
{
   cmd_char = UART_RxChar();
   UART_TxChar(cmd_char);
}


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: UART Mega32a. Неверный код конца строки в эхо ответе.
СообщениеДобавлено: 11 мар 2020, 12:04 
Только пришел

Зарегистрирован: 21 ноя 2015, 18:03
Сообщения: 5
Хорошее замечание. Поправил. Но проблему это не решает.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: UART Mega32a. Неверный код конца строки в эхо ответе.
СообщениеДобавлено: 11 мар 2020, 12:28 
Старожил

Зарегистрирован: 04 окт 2012, 00:23
Сообщения: 2745
Откуда: Москва
Код:
void UART_init(long USART_BAUDRATE)         //Init
{
   UCSRB = (1 << RXCIE)|(1 << RXEN)|(1 << TXEN);                // Interrupt enable.
   
   UCSRC = (1 << URSEL)|(1 << UCSZ1) | (1 << UCSZ0)               // Switch to register UCSEL
   
   UBRRL = BAUD_PRESCALE;             /* Load lower 8-bits of the baud rate value */
   UBRRH = (BAUD_PRESCALE >> 8);         /*Load upper 8-bits*/
}


И итог кода , плиз


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: UART Mega32a. Неверный код конца строки в эхо ответе.
СообщениеДобавлено: 11 мар 2020, 14:37 
Заглядывает иногда

Зарегистрирован: 22 мар 2012, 21:55
Сообщения: 89
Откуда: г.Пермь
а программным терминалом проверить? by Br@y++ например. Чую засада в настройках odd/even, 7/8 , 1/1.5/2


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: UART Mega32a. Неверный код конца строки в эхо ответе.
СообщениеДобавлено: 11 мар 2020, 15:06 
Только пришел

Зарегистрирован: 21 ноя 2015, 18:03
Сообщения: 5
ILYAUL писал(а):
Код:
void UART_init(long USART_BAUDRATE)         //Init
{
   UCSRB = (1 << RXCIE)|(1 << RXEN)|(1 << TXEN);                // Interrupt enable.
   
   UCSRC = (1 << URSEL)|(1 << UCSZ1) | (1 << UCSZ0)               // Switch to register UCSEL
   
   UBRRL = BAUD_PRESCALE;             /* Load lower 8-bits of the baud rate value */
   UBRRH = (BAUD_PRESCALE >> 8);         /*Load upper 8-bits*/
}


И итог кода , плиз


Спасибо! Наконец-то, дело двинулось с мертвой точки. Код работает как надо. Кстати раньше от бэкспейса тоже ответ не верный приходил.
Теперь бы понять на будущее, почему так произошло, что часть ответов верны, а часть нет.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: UART Mega32a. Неверный код конца строки в эхо ответе.
СообщениеДобавлено: 11 мар 2020, 15:29 
Старожил

Зарегистрирован: 08 авг 2013, 09:43
Сообщения: 3047
vvik2, в ДШ всё написано - проблема в вашей записи регистра UCSRC по одному биту (зачем вообще писать по 1 биту за раз?!).
When the function writes to the UCSRC Register, the URSEL bit(MSB) must be set due to the sharing of I/O location by UBRRH and UCSRC.
20.10 Accessing UBRRH/UCSRC RegistersThe UBRRH Register shares the same I/O location as the UCSRC Register. Therefore some special considerationmust be taken when accessing this I/O location.20.10.1Write AccessWhen doing a write access of this I/O location, the high bit of the value written, the USART Register Select(URSEL) bit, controls which one of the two registers that will be written. If URSEL is zero during a write operation,the UBRRH value will be updated. If URSEL is one, the UCSRC setting will be updated.

Т.к. адрес один на 2 регистра, именно наличие установленного бита URSEL определяет, что запись идет в регистр UCSRC, а не UBRRH. Т.к. вы выставляли его в отдельной строке запись битов UCSZ1, UCSZ0 не проходила, т.к. писался другой регистр. Ну а считывание там тоже особое. 1ый раз читается всегда UBRRH, и только прям в следующей инструкции повторно если считать, то считается UCSRC. Поэтому записью вроде UCSRC |= (1 << URSEL); которая Read-Modify-Write, вы вычитываете регистр UBRRH (который равен 0 в данный момент) и пишете эти нули следующей операцией в UCSRC.
Ну и в итоге вы получили другой формат кадра, нежели ожидаемый, т.к. обнулили значения бит UCSZ1, UCSZ0 вместо установки. 5-бит, вместо ожидаемых 8-бит. Со всеми вытекающими.

Кстати строка UCSRC = (1 << URSEL)|(1 << UCSZ1) | (1 << UCSZ0) // Switch to register UCSEL может быть вообще убрана, т.к. это значение по-умолчанию, после сброса МК всё-равно. Но если писать, то именно так - целиком весь регистр за 1 запись.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: UART Mega32a. Неверный код конца строки в эхо ответе.
СообщениеДобавлено: 11 мар 2020, 16:37 
Только пришел

Зарегистрирован: 21 ноя 2015, 18:03
Сообщения: 5
Благодарю за разъяснение.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: UART Mega32a. Неверный код конца строки в эхо ответе.
СообщениеДобавлено: 11 мар 2020, 16:47 
Старожил

Зарегистрирован: 08 авг 2013, 09:43
Сообщения: 3047
Ну и еще, что вытекает из прошлого коммента моего, но на всякий случай - в регистр UCSRC нельзя модифицировать биты через обыное R-M-W (т.е. через |=). Потому что эта запись считает не те данные. Читать надо так:
Код:
uint8_t tempReg;
cli();
tempReg = UCSRC;
tempReg = UCSRC;
sei();

Именно со 2го раза чтобы считалось правильное значение. Хотя читать его мало имеет смысла. Если в процессе работы проги надо менять настройки этого регистра - проще завести отдельную переменную, менять её и писать в регистр всегда через = с установкой URSEL всегда опять же.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: UART Mega32a. Неверный код конца строки в эхо ответе.
СообщениеДобавлено: 11 мар 2020, 17:48 
Старожил

Зарегистрирован: 04 окт 2012, 00:23
Сообщения: 2745
Откуда: Москва
Цитата:
Кстати строка UCSRC = (1 << URSEL)|(1 << UCSZ1) | (1 << UCSZ0) // Switch to register UCSEL может быть вообще убрана, т.к. это значение по-умолчанию, после сброса МК всё-равно.
Нет уж, пока не будет знать проц досконально - пусть пишет всё


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: UART Mega32a. Неверный код конца строки в эхо ответе.
СообщениеДобавлено: 11 мар 2020, 17:58 
Старожил

Зарегистрирован: 08 авг 2013, 09:43
Сообщения: 3047
ILYAUL, ну если б он туда изначально по битам не пытался вообще писать, то оно бы работало )


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 11 ] 


Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB