|
STM32 прерывание по USART - по приему и передаче одновременно, Вопрос |
|
|
|
May 23 2013, 13:13
|
Участник

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

|
Здравствуйте.
Контроллер STM32L.
Возможно глупый вопрос - при возникновении прерывания по USART я ухожу по вектору прерывания проверяю флаги, смотрю что было прерывание по передаче, начинаю обрабатывать данное прерывание и тут у меня приходит байт по USART. Но я ведь в это время обрабатываю прерывание по передаче и при окончании обработки уже флаги прерываний проверять не собираюсь. Как поведет себя контроллер - по выходу из прерывания заново вызовет вектор прерывания с флагом по приему или как то иначе.
Знаю, что надо читать документацию или на крайний случай экспериментировать, но может, кто уже знает и подскажет сразу.
Заранее благодарен за любую помощь.
|
|
|
|
|
May 24 2013, 19:07
|

Ally
     
Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050

|
Цитата(DASM @ May 24 2013, 19:26)  Это описано в еррата какой-либо? У меня сложилось впечатление, что в этих процах ПДП вообще применять стоит редко и осторожно, а вместе с вашей репликой и вовсе выходит, что уапп в этих процессорах лучше не применять  Само наличие такого явления как еррата означает, что в ней много чего еще нет. На микроконтроллеры которые по 6-ть лет выпускются до сих порт обновляют ерраты. И как-то не досуг писать в ST про их проблемы. Но факт есть факт, на 900 кбит UART в STM32 пропускал прерывания на прием. При том что сама процедура прерывания была короткой и самой приоритетной. Прерывания в остальной программе запрещались не больше чем на десятки тактов. Вот эта процедура: Код void USART1_IRQHandler(void) { unsigned short sr; unsigned int tmp;
sr = USART1->SR; if( sr & USART_SR_RXNE ) { // Получили байт, сохраняем в кольцевом буфере tmp = comc_in_buf_head[0]; comc_input_buf[0][comc_in_buf_head[0]++] = USART1->DR; comc_in_buf_head[0] &= (COMC_IN_BUF_SZ - 1); if( comc_in_buf_head[0]==comc_in_buf_tail[0] ) comc_in_buf_head[0] = tmp; // Если происходит переполнение то не сдвигать указатель буфера if( receive_task[0]!=0 ) isr_evt_set (BYTE_FROM_UART_EVNT, receive_task[0]); }
if( sr & USART_SR_ORE ) { dummy = USART1->DR; } if( ( sr & USART_SR_TXE) && (USART1->CR1 & USART_CR1_TXEIE) ) { USART1->DR = comc_output_buf[0][comc_out_buf_tail[0]++]; comc_out_buf_tail[0] &= (COMC_OUT_BUF_SZ - 1); if( comc_out_buf_head[0] == comc_out_buf_tail[0] ) { USART1->CR1 &= ~USART_CR1_TXEIE; // Запретим прерывания если нечего передавать } } } Причем ждать пропуска прерываний приходилось довольно долго. Никакой системы в появлении этого бага не обнаружил. После того как стал использовать DMA проблем не стало.
|
|
|
|
|
May 25 2013, 06:41
|

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

|
Цитата(aaarrr @ May 25 2013, 01:19)  ИМХО, для процессоров с недоделанным UART'ом (без FIFO), в сколько нибудь сложном и загруженном приложении без DMA никак. Согласен. Цитата(Golikov A. @ May 25 2013, 09:59)  чудеса... А я скажу что чудес не бывает в нашей профессии. Всё рано или поздно вылезает наружу...
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|