Я пытаюсь реализовать приемник UART, который работает, находя «\ 0» в потоке данных, ИЛИ когда он получает 256 символов, после чего данные должны обрабатываться прерыванием. Суть в том, чтобы использовать DMA для приема, но если произойдет любое из этих событий, он должен прекратить заполнение текущего буфера и обрабатывать данные. Причина в том, что я использую кодировку COBS для кадрирования своих данных.
Чип STM32F7 имеет что-то под названием «Сопоставление символов» как часть спецификации Modbus, которую я заработал, установив биты в регистре конфигурации, поскольку он не поддерживается библиотеками HAL (stm32cubemx, который удалит этот код при регенерации):
MODIFY_REG(huart->Instance->CR1, UART_CR1_FIELDS, tmpreg | USART_CR1_CMIE);
И в конце обработчик прерывания UART делаю
UART8->ICR |= USART_ISR_CMF;
Чтобы очистить флаг прерывания совпадения символов, чтобы он больше не запускался.
Насколько я понимаю, обработчики прерываний в STM32f7xx_it.c - это фактически первые функции
void DMA1_Stream6_IRQHandler(void) and void UART8_IRQHandler(void)
в моем случае они запускаются, когда прерывания происходят на периферийном устройстве, и из этих функций запускается обработчик (HAL_xxx_IRQHandler()), который проверяет, какое прерывание произошло, и запускает любые пользовательские функции в зависимости от флагов прерывания, например:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle) {
//process data, this runs when DMA finishes receiving bytes
}
Проблема в том, что неясно, какая из функций прерывания выполняется, когда, например, я использую DMA и получил указанный объем данных через UART. Он запускает прерывание UART или прерывание потока DMA? Как я могу надежно оказаться в одной и той же функции обратного вызова на '\ 0' (uart?) или 256 байтах (dma?) для обработки моих данных без испорченных прерываний?
Регистр DMA CNDTR ведет обратный отсчет до нуля после каждой передачи и показывает, сколько элементов осталось передать. Вы можете использовать его, чтобы проверить, работает ли DMA.
Ваши прерывания UART, если они включены, всегда будут работать вместе с передачами и прерываниями DMA, поэтому прерывания UART должны будут проверять регистр CNDTR DMA, чтобы знать, действительно ли они выполняются.
Вы также можете отключить прерывания изнутри прерываний. Таким образом, ваше прерывание завершения передачи DMA может отключить прерывание приема вашего персонажа (или наоборот), и вы можете снова включить его в другом месте. Помните, что у вас также есть приоритеты прерывания для обработки, когда последняя передача DMA является символом "\0" и одновременно вызывает прерывание завершения передачи DMA и совпадения символов.
В моем коде я использую сопоставление символов, чтобы обнаружить клавишу ввода, чтобы узнать, что пользовательская команда была введена, и проанализировать сообщение в памяти, хранящееся DMA. У меня также есть прерывание приема UART для эхо-символов, которое повторяет символ непосредственно из регистра приема UART. Все они выполняются одновременно с передачей и прерываниями DMA.
Я не работал с STM32F7, но вы можете проверить этот репозиторий . Я поделился пошаговым руководством по использованию DMA с совпадением символов и тайм-аутом приемника для микроконтроллеров STM32L4. Как я вижу, регистры для обоих MCU выглядят одинаково.
Питер Смит
Крис Стрэттон
Трифон