реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Очистка приёмного буфера USART
nvk
сообщение Mar 28 2012, 12:17
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 50
Регистрация: 22-07-11
Пользователь №: 66 352



Добрый день!

Зашёл в тупик с очисткой буфера Atmega32.
Очищаю буфер как в даташите:
void USART_Flush()
{
unsigned char dummy;
while (UCSRA & (1<<RXC))
dummy = UDR;
}
Этот вариант не работает. Написал другой вариант с очисткой битов RXEN, TXEN:
void USART_Flush()
{
UCSRB = 0x00;
UCSRB = 0x18;
}
Этот код тоже не работает, всё равно остаются несчитанные символы.
В чём проблема?
Go to the top of the page
 
+Quote Post
xemul
сообщение Mar 28 2012, 12:28
Сообщение #2



*****

Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731



Если не работают два варианта, которые не могут не работать, резонно предположить, что ошибка где-то в другом месте.
(дурацкий вопрос про уверенность в не-поступлении новых символов после очистки даже не задаю)
Go to the top of the page
 
+Quote Post
Палыч
сообщение Mar 28 2012, 12:36
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(nvk @ Mar 28 2012, 16:17) *
...не работает, всё равно остаются несчитанные символы.
В чём проблема?

Оба варианта должны работать. Проблема, видимо, в том, что символы поступают после выполнения процедуры USART_Flush...
Go to the top of the page
 
+Quote Post
Navovvol
сообщение Mar 28 2012, 13:29
Сообщение #4


Частый гость
**

Группа: Участник
Сообщений: 105
Регистрация: 9-09-11
Пользователь №: 67 080



Могу только порекомендовать поменять местами Rx и Tx.
Ну и для уверенности добавить прерывание на прием. Даже не знаю есть ли они у Atmega32.
Go to the top of the page
 
+Quote Post
hd44780
сообщение Mar 28 2012, 14:06
Сообщение #5


Профессионал
*****

Группа: Свой
Сообщений: 1 202
Регистрация: 26-08-05
Из: Донецк, ДНР
Пользователь №: 7 980



Код нормальный.

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

Цитата(Navovvol @ Mar 28 2012, 16:29) *
Даже не знаю есть ли они у Atmega32.


Есть, куда ж без них-то rolleyes.gif ....

Сообщение отредактировал hd44780 - Mar 28 2012, 14:09


--------------------
Чтобы возить такого пассажира, необходим лимузин другого класса.
(с) Мария Эдуарда
Go to the top of the page
 
+Quote Post
UraGun
сообщение Mar 29 2012, 08:06
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 28
Регистрация: 11-10-05
Из: Запорожье
Пользователь №: 9 516



кольцевые буферы из даташита показались мне лично не самым оптимальным решением. Особенно, когда я запускал асинхронную спарку двух модбасов на меге128. Пришлось написать своё. Завязал всё на тайминги и прерывания, и ничего теперь не приходится очищать, а это экономия времени опять же. Кстати, память тоже разгрузилась. На каждый канал модбаса использую один буфер на 256 байт. И для приёма и для передачи. Исключил также необходимость перезагрузки данных в буфер из переменных перед передачей. Получилось не очень красиво структурно, но очень быстро и компактно. Ну и асинхронность опять же была очень важна. Так что кольцевой - не панацея.

Сообщение отредактировал IgorKossak - Mar 30 2012, 07:09
Причина редактирования: избыточное цитирование
Go to the top of the page
 
+Quote Post
nvk
сообщение Mar 30 2012, 03:17
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 50
Регистрация: 22-07-11
Пользователь №: 66 352



Сделал по другому: после каждого обращения к модулю sim300 считываю ответ функцией даже если этот ответ не нужен для обработки.
Например:

sendSMS("string");
USART_geta(); // просто считываем ответ
USART_transmit("AT+CBC");
USART_geta();
{ обработка принятого ответа}

И это работало с самого начала, просто я хотел сделать проще...
Go to the top of the page
 
+Quote Post
xemul
сообщение Mar 30 2012, 05:23
Сообщение #8



*****

Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731



Цитата(nvk @ Mar 30 2012, 07:17) *
И это работало с самого начала, просто я хотел сделать проще...

Разница между USART_geta() и USART_Flush() в признаке окончания функций - UDR == 0x0d (вероятно) и RXC == 0 слегка отличаются.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Mar 30 2012, 05:31
Сообщение #9


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



можно немного упроститьsm.gif
Код
void USART_Flush()
{
    while (UCSRA & (1<<RXC))
    {
        UDR;
    }
}


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 16th July 2025 - 10:32
Рейтинг@Mail.ru


Страница сгенерированна за 0.01865 секунд с 7
ELECTRONIX ©2004-2016