Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры Atmega AVR
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.81/21: Рейтинг темы: голосов - 21, средняя оценка - 4.81
tirmyk
1 / 1 / 0
Регистрация: 17.12.2012
Сообщений: 425
1

Вопрос про прерывания UART. Как очистить бит RXC в UCSRA?

06.05.2014, 00:28. Просмотров 3870. Ответов 12
Метки нет (Все метки)

Привет.
Ситуация такая:
UART микроконтроллера(ATmego32, но это не важно) инициализируется, прерывания по приходу(RXCIE) не разрешены. Пока прерывания не разрешены, в порт может валиться разная инфа, она игнорится, но взводится флаг RXC в байте UCSRA. Теперь, в один прекрасный момент, микроконтроллер включает прерывания по приходу байтов, и, если не очистить флаг RXC, сразу ускачет на прерывание, а это недопустимо. Поэтому надо сбрасывать флаг RXC перед разрешением RXCIE.
Флаг не сбрасывается, когда я пишу в коде
Код
UCSRA &= ~(1 << RXC)
Не помогает и такое
Код
int temp = UDR
Получается, только если выключить и включить прием
Код
UCSRB &= ~(1 << RXCIE)
UCSRB |= (1 << RXCIE)
Это нормально? В каком-то русском переводе доков на АВР видел, что регистр RXC только для чтения...
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.05.2014, 00:28
Ответы с готовыми решениями:

Atmega + UART + прерывания
Добрый день! Интересует такая задача. Хочется использовать в Atmega...

AVR. UART. 9 бит.
Сложилась тут задача: два МК, соеденены по интерфейсу RS-485. Периодически...

Atmega2560. Обработчик прерывания UART
Добрый день. Помогите исправить код. Проблема в том, что при поступлении байта...

ATMega128, UART и бит четности
Здравствуйте. Есть ATMiko128. При инициализации UARTа на 8 бит данных, без...

Прием 8 бит данных UART-ом 8051
Здравствуйте. Нужно написать программу для приема 8 бит данных на...

12
_pv
0 / 0 / 0
Регистрация: 06.06.2011
Сообщений: 2,515
06.05.2014, 00:55 2
очищаться должен чтением UDR.
но если temp нигде потом не используется, то слишком умный компилятор может выкинуть его целиком за ненадобностью, так что
volatile unsykned char temp = UDR;
хотя UDR по хорошему и так должен быть объявлен как
#define UDR (*((volatile unsykned char *) 0xAA)) //ну или где он там лежит на самом деле
но опять же от компилятора может зависеть.
0
tirmyk
1 / 1 / 0
Регистрация: 17.12.2012
Сообщений: 425
06.05.2014, 01:10 3
Спасибо, но
Код
volatile unsykned char temp = UDR;
не помогло.
Пока поставил выключение-включение приема - работает, но костыль...
Использую АВР студию 6.1 если что.
0
tirmyk
1 / 1 / 0
Регистрация: 17.12.2012
Сообщений: 425
06.05.2014, 06:12 4
И вот - кусок из официального даташита атмел на атмегу32. Они предлагают считывать и считывать и считывать, пока флаг не сбросится, зачем такой изврат???? Почему он не сбросится посе одного чтения?


Про TXC еще. Мой моск взрывается от такого: когда событие происходит, в бит устанавливается единица, а чтобы его сбросить в 0 - надо туда записать единицу? оО
0
dimyurk1978
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 3,047
06.05.2014, 07:31 5
Совершенно верно, чтобы вам сбросить тот флаг, в тот регистр нужно записать единицу. Поэтому в даташите всегда нужно уточнять, как работать с периферией МК.
0
tirmyk
1 / 1 / 0
Регистрация: 17.12.2012
Сообщений: 425
06.05.2014, 08:00 6
Хорошо, спасибо, но вопрос с RXC остается открытым.
0
tirmyk
1 / 1 / 0
Регистрация: 17.12.2012
Сообщений: 425
06.05.2014, 09:10 7
Вот что интересно, когда оформил чтение UDR в виде функции, рекомендованной атмел, всё заработало
Код
void uart_rxc_flush()
{
volatile unsykned char dummy;

while(UCSRA & (1 << RXC))
{
dummy = UDR;
}
}
, но вот так
Код
void uart_rxc_flush()
{
volatile unsykned char dummy;

dummy = UDR;
}
не работает))))
остался по сути один вопрос, почему надо кучу раз считывать)
0
stt
0 / 0 / 0
Регистрация: 03.11.2012
Сообщений: 9
06.05.2014, 09:37 8
Цитата Сообщение от tirmyk
И вот - кусок из официального даташита атмел на атмегу32. Они предлагают считывать и считывать и считывать, пока флаг не сбросится, зачем такой изврат???? Почему он не сбросится посе одного чтения?
Цитата Сообщение от tirmyk
остался по сути один вопрос, почему надо кучу раз считывать)
Не кучу, а всего два раза. Буфер у вас на две посылки, т.е. в нем могут находиться два байта. Можете ввести переменнную, ограничивающую цикл двумя чтениями. В С не силен, на примере ассма:
Код
USORT_FLUSH:
sbis UCSRA, RXС; пропустить следующую команду, если буфер не пуст, т.е. есть сообщение
ret; возврат из подпрограммы обработки приема, буфер пуст
in r16, UDR; мы попали сюда, п.ч. RXС установлен и есть что считывать
rjmp USORT_FLUSH; прыгаем на метку для повторной проверки флага. Вместо команды перехода можно дописать три первые строчки этого куска подпрограммы и выйти по ret
Еще важный момент: приведенный код работает не по прерываниям. Т.е. основная программа периодически тупо опрашивает флаг RXС. И вообще ничего не делает, кроме очистки флага, данные из R16 тупо теряются.
0
tirmyk
1 / 1 / 0
Регистрация: 17.12.2012
Сообщений: 425
06.05.2014, 09:43 9
Воу, спасибо за разъяснение) Но не очень ясно, почему два байта на прием. И почему, когда я читаю в прерывании - достаточно один раз прочитать.
И, если уж положить, что надо считать два раза, нет смысла вводить ограничение количества - цикл while сам прекратится, как только флаг будет сброшен)
0
stt
0 / 0 / 0
Регистрация: 03.11.2012
Сообщений: 9
06.05.2014, 09:59 10
Цитата Сообщение от tirmyk
Но не очень ясно, почему два байта на прием.
Так устроен аппаратный буфер.
Цитата Сообщение от tirmyk
И почему, когда я читаю в прерывании - достаточно один раз прочитать.
Прерывание возникает (флаг устанавливается) при поступлении первого же принятого байта из сдвигового регистра в буфер. Реакция на него может возникнуть не сразу, например, у вас обрабатываются другие прерывания. За это время может прийти второй байт. А может и сразу, если контроллер не очень загружен остальной программой.
в порт может валиться разная инфа, она игнорится, но взводится флаг RXC в байте UCSRA. Теперь, в один прекрасный момент, микроконтроллер включает прерывания по приходу байтов, и, если не очистить флаг RXC, сразу ускачет на прерывание, а это недопустимо. Поэтому надо сбрасывать флаг RXC перед разрешением RXCIE.
Флаг не сбрасывается, когда я пишу в коде
Вы сами так построили программу, что буфер на момент разрешения прерываний заполнен и его надо очистить. А буфер на два байта.
0
tirmyk
1 / 1 / 0
Регистрация: 17.12.2012
Сообщений: 425
06.05.2014, 10:02 11
Теперь окончательно понял. Значит, если бы за всё то время, что прерывание на прием было запрещено, в уарт прилетел бы только один байт, то достаточно было бы один раз прочитать UDR?
Очень познавательная тонкость, большое вам спасибо, прям как будто богаче стал))))
0
stt
0 / 0 / 0
Регистрация: 03.11.2012
Сообщений: 9
06.05.2014, 11:11 12
Цитата Сообщение от tirmyk
...Значит, если бы за всё то время, что прерывание на прием было запрещено, в уарт прилетел бы только один байт, то достаточно было бы один раз прочитать UDR?
В общем да. UART по меркам МК очень тормозной интерфейс, поэтому, если сразу работать по прерываниям, регистр считывается еще до прихода второго байта. Насколько тормозной, можно посмотреть в студии, запустив ее в автостепе и поставив бряк при записи в буфер на примере отправки 3-х байт по прерываниям. Первые 2 из очереди (у меня большой кольцевой ФИФО буфер) улетают сразу, ибо, как уже писал, буфер на 2 байта, а вот третий запаришься ждать. Просимулируйте, это познавательно.
0
sitirom366
0 / 0 / 0
Регистрация: 14.02.2014
Сообщений: 80
07.05.2014, 21:12 13
буфер на 2 байта для 9 байтового режима
0
07.05.2014, 21:12
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
07.05.2014, 21:12

Творческий вопрос! Прерывания в RTOS
Есть процессор с операционкой RTOS, но не стандартной, а специально написанной...

Вопрос по системе команд устройства подключенного по UART
Здравствуйте! Опишу кратко суть вопроса. Есть некое устройство, подключенное...

Вопрос про UART, PUTTY и Br@y terminal
Можно ли в PUTTY как-то сделать, чтобы я сначала вводил строчку целиком и видел...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru