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)
0
|
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
|
06.05.2014, 00:28 |
Ответы с готовыми решениями:
12
Atmega + UART + прерывания AVR. UART. 9 бит. Atmega2560. Обработчик прерывания UART ATMega128, UART и бит четности Прием 8 бит данных UART-ом 8051 |
_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 |
![]() ![]() Код
USORT_FLUSH: sbis UCSRA, RXС; пропустить следующую команду, если буфер не пуст, т.е. есть сообщение ret; возврат из подпрограммы обработки приема, буфер пуст in r16, UDR; мы попали сюда, п.ч. RXС установлен и есть что считывать rjmp USORT_FLUSH; прыгаем на метку для повторной проверки флага. Вместо команды перехода можно дописать три первые строчки этого куска подпрограммы и выйти по ret
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 |
![]() ![]()
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 |
![]()
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 Вопрос по системе команд устройства подключенного по UART Вопрос про UART, PUTTY и Br@y terminal Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |