|
发表于 2021-7-5 11:23:19
|
显示全部楼层
1.请问你用的是V7开发板吗?
如果不是你可以参考我在V6开发板上的实现方法:
http://www.armbbs.cn/forum.php?m ... d=101377&extra=
2.如果你的开发板是V7,CPU应该是STM32H743系列,无意中看到F7和H7系列,
ST官方对空闲DMA接收做了处理,在 HAL_UART_IRQHandler 里面 代码如下:- /* Check current reception Mode :
- If Reception till IDLE event has been selected : */
- if ((huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
- && ((isrflags & USART_ISR_IDLE) != 0U)
- && ((cr1its & USART_ISR_IDLE) != 0U))
- {
- __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
- /* Check if DMA mode is enabled in UART */
- if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
- {
- /* DMA mode enabled */
- /* Check received length : If all expected data are received, do nothing,
- (DMA cplt callback will be called).
- Otherwise, if at least one data has already been received, IDLE event is to be notified to user */
- uint16_t nb_remaining_rx_data = (uint16_t) __HAL_DMA_GET_COUNTER(huart->hdmarx);
- if ((nb_remaining_rx_data > 0U)
- && (nb_remaining_rx_data < huart->RxXferSize))
- {
- /* Reception is not complete */
- huart->RxXferCount = nb_remaining_rx_data;
- /* In Normal mode, end DMA xfer and HAL UART Rx process*/
- if (huart->hdmarx->Init.Mode != DMA_CIRCULAR)
- {
- /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
- CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
- CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
- /* Disable the DMA transfer for the receiver request by resetting the DMAR bit
- in the UART CR3 register */
- CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
- /* At end of Rx process, restore huart->RxState to Ready */
- huart->RxState = HAL_UART_STATE_READY;
- huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
- CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
- /* Last bytes received, so no need as the abort is immediate */
- (void)HAL_DMA_Abort(huart->hdmarx);
- }
- #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
- /*Call registered Rx Event callback*/
- huart->RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount));
- #else
- /*Call legacy weak Rx Event callback*/
- HAL_UARTEx_RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount));
- #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
- }
- return;
- }
复制代码
3.根据我自己的方式和官方代码的实现可以看出,在空闲中断的判断上要先判断中断是否开启
以及标志位是否置位,最重要的一点就是:不是调用HAL_UART_DMAStop,
而是使用 HAL_DMA_Abort。你自己可以查看函数原型。abort是不会关闭串口发送的,
stop是会关闭串口DMA发送和接收的。 |
|