Estoy tratando de implementar un receptor UART que funciona al encontrar un '\ 0' en el flujo de datos, O cuando recibe 256 caracteres, momento en el que los datos deben procesarse mediante una interrupción. El objetivo es usar DMA para la recepción, pero si ocurre cualquiera de estos eventos, debería dejar de llenar el búfer actual y procesar los datos. La razón es que estoy usando la codificación COBS para enmarcar mis datos.
El chip STM32F7 tiene algo llamado Coincidencia de caracteres como parte de la especificación Modbus, que conseguí configurar los bits en el registro de configuración, ya que no es compatible con las bibliotecas HAL (stm32cubemx, que eliminaría este código al regenerarse):
MODIFY_REG(huart->Instance->CR1, UART_CR1_FIELDS, tmpreg | USART_CR1_CMIE);
Y al final del controlador de interrupciones UART lo hago
UART8->ICR |= USART_ISR_CMF;
Para borrar el indicador de interrupción de coincidencia de caracteres para que no vuelva a ejecutarse.
Según tengo entendido, los controladores de interrupción en STM32f7xx_it.c son, de hecho, las primeras funciones
void DMA1_Stream6_IRQHandler(void) and void UART8_IRQHandler(void)
en mi caso, que se ejecutan cuando ocurren interrupciones en un periférico, y desde estas funciones se ejecuta un controlador (HAL_xxx_IRQHandler()) que verifica qué interrupción ocurrió y ejecuta cualquier función definida por el usuario según los indicadores de interrupción, como por ejemplo:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle) {
//process data, this runs when DMA finishes receiving bytes
}
El problema es que no está claro cuál de las funciones de interrupción se ejecuta cuando, por ejemplo, estoy usando DMA y he recibido la cantidad especificada de datos a través de UART. ¿Ejecuta la interrupción UART o la interrupción del flujo DMA? ¿Cómo puedo terminar de manera confiable en la misma función de devolución de llamada en '\ 0' (¿uart?) o 256 bytes (¿dma?) para procesar mis datos sin estropear las interrupciones?
El registro DMA CNDTR cuenta hasta cero después de cada transferencia y muestra cuántos elementos quedan por transferir. Puede usarlo para verificar si el DMA se está ejecutando o no.
Sus interrupciones de UART, si están habilitadas, siempre se ejecutarán junto con las transferencias e interrupciones de DMA, por lo que las interrupciones de UART tendrán que verificar el registro CNDTR de DMA para saber si realmente se ejecutarán o no.
También puede deshabilitar las interrupciones desde dentro de las interrupciones. Por lo tanto, la interrupción completa de la transferencia DMA puede deshabilitar la interrupción de recepción de su personaje (o viceversa) y puede volver a habilitarla en otro lugar. Recuerde que también tiene prioridades de interrupción para manejar cuando la última transferencia de DMA es el carácter "\0" y activa tanto la transferencia de DMA completa como las interrupciones de coincidencia de caracteres al mismo tiempo.
En mi código, uso la coincidencia de caracteres para detectar la tecla Intro para saber que se ha ingresado un comando de usuario y para analizar el mensaje en la memoria que está almacenando el DMA. También tengo una interrupción de recepción de UART para hacer eco de los caracteres que repite el carácter directamente desde el registro de recepción de UART. Todos estos se ejecutan al mismo tiempo junto con las transferencias e interrupciones de DMA.
No he trabajado con STM32F7, pero puede consultar este repositorio . Compartí una guía paso a paso para usar DMA con coincidencia de caracteres y tiempo de espera del receptor para MCU STM32L4. Como puedo ver, los registros para ambos MCU son similares.
Pedro Smith
chris stratton
Trifón