void USART2_IRQHandler(void)
{
/* USER CODE BEGIN USART2_IRQn 0 */
/* UART IDLE Interrupt */
if(__HAL_UART_GET_FLAG(&huart2, UART_FLAG_IDLE) == SET)
{
__HAL_UART_CLEAR_IDLEFLAG(&huart2);
print("time %d",timeCounter");
receivedDataFlag = 1;
}
}
Cuando uso esta función, verifico los estados de inactividad de la línea y decido los datos recibidos o no recibidos. Pero esta interrupción se activa durante la transmisión. ¿Cómo puedo separar la línea de datos de recepción inactiva y la de recepción inactiva?
Quiero activar solo recibir la línea de datos inactiva, ¿cómo puedo hacer eso? ¿Qué otro registro debo mirar?
Obtengo un resultado muy interesante,
El remitente envía datos cada 100 ms a mi dispositivo;
Si uso las funciones DMA de recepción única; tiempo de retorno 10, 110, 220,330 (Estados inactivos trabajando)
Pero si recibí que después de transmitir datos con uart, estos valores de tiempo devuelven 10,13,15, ... una función de transmisión media cambia el estado inactivo de la línea, ¿cómo es posible? ¿El UART_FLAG_IDLE está relacionado solo con rx?
EDITAR: Por cierto, estoy usando rs485, así que cuando empiezo a transmitir, configuro el modo de transmisor del transceptor, de modo que el modo del receptor del lado del remitente, ¿así que mi MCU decide INACTIVO en este estado? ¿es eso posible? ¿Cómo puedo proteger esta situación?
Cuando inicio el modo de transmisión después de recibir los datos, luego completé la devolución de llamada, cuando llamo a HAL_UART_Receive_DMA(&huart2,(uint8_t*)dma_rx_buf,DMA_BUF_SIZE); función IDLE disparo de interrupción cada 5 ms pero tiempo de espera de envío de datos 100 ms
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
HAL_UART_DMAStop(&huart2);
dmaTransmitCompletedFlag = 1;
RS485_Set_Receive_Mode();
HAL_UART_Receive_DMA(&huart2,(uint8_t*)dma_rx_buf,DMA_BUF_SIZE);
waitForTransmittingData = 0;
}
Esa interrupción se usa tanto para transmitir como para recibir.
El IDLE es relevante solo para la recepción, significa que hay al menos un cuadro completo de inactividad detectado.
Usar print en una interrupción no es aconsejable, especialmente si la impresión usa el mismo UART para el que es la interrupción.
Esa IRQ está dedicada a USART2, pero se llama para cada interrupción habilitada asociada con USART2. Eso significa que el controlador debe verificar y manejar cada señal de interrupción habilitada. Para STM32 USART, eso incluye señales fundamentales para interrumpir el UART como TXNE y RXNE, así como señales de error, IDLE, etc.
La señal IDLE es para enmarcar recepciones de varios bytes (un problema común para USART, especialmente en entornos ruidosos). Se afirma cuando la línea de recepción se ha declarado alta (o 'inactiva') durante algún tiempo de rebote (determinado por la configuración de sobremuestreo/velocidad en baudios), después de que esa línea haya estado activa (durante la recepción de un grupo de uno o más bytes) . Esto es útil porque puede usarlo para restablecer su búfer de recepción al índice '0', de modo que el siguiente cuadro se alinee correctamente (incluso si se recibieron muy pocos o demasiados bytes en el cuadro actual). Normalmente, debe implementar este tipo de lógica con un periférico de temporizador dedicado, pero STM32 lo empaqueta convenientemente en sus periféricos USART (aunque no es compatible con el controlador HAL nativo).
Si realmente desea que solo la señal inactiva active una interrupción, deberá desactivar manualmente todas las demás señales de interrupción. Si desea un receptor UART útil controlado por interrupciones, no le sugiero que lo haga.
De una de sus preguntas anteriores, le di algunos enlaces, donde esto se implementa.
USART3_IRQHandler(void) {
/* Check for IDLE line interrupt */
if (LL_USART_IsEnabledIT_IDLE(USART3) && LL_USART_IsActiveFlag_IDLE(USART3)) {
LL_USART_ClearFlag_IDLE(USART3); /* Clear IDLE line flag */
usart_rx_check(); /* Check for data to process */
}
/* Implement other events when needed */
}
Rata de acero inoxidable
Sólo yo
Rata de acero inoxidable
Jeroen3