串口DMA接收到数据后,DMA停止对外发送数据

hal库中原始函数,会把收发DMA一块儿关闭,这样会造成在DMA发送的同时,有DMA接收到数据调用以上函数时,会停止DMA发送;

 1 /**
 2   * @brief Stop the DMA Transfer.
 3   * @param huart UART handle.
 4   * @retval HAL status
 5   */
 6 HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart)
 7 {
 8   /* The Lock is not implemented on this API to allow the user application
 9      to call the HAL UART API under callbacks HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback() /
10      HAL_UART_TxHalfCpltCallback / HAL_UART_RxHalfCpltCallback:
11      indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete
12      interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of
13      the stream and the corresponding call back is executed. */
14 
15   const HAL_UART_StateTypeDef gstate = huart->gState;
16   const HAL_UART_StateTypeDef rxstate = huart->RxState;
17 
18   /* Stop UART DMA Tx request if ongoing */
19   if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) &&
20       (gstate == HAL_UART_STATE_BUSY_TX))
21   {
22     ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
23 
24     /* Abort the UART DMA Tx channel */
25     if (huart->hdmatx != NULL)
26     {
27       if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK)
28       {
29         if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
30         {
31           /* Set error code to DMA */
32           huart->ErrorCode = HAL_UART_ERROR_DMA;
33 
34           return HAL_TIMEOUT;
35         }
36       }
37     }
38 
39     UART_EndTxTransfer(huart);
40   }
41 
42   /* Stop UART DMA Rx request if ongoing */
43   if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) &&
44       (rxstate == HAL_UART_STATE_BUSY_RX))
45   {
46     ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
47 
48     /* Abort the UART DMA Rx channel */
49     if (huart->hdmarx != NULL)
50     {
51       if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK)
52       {
53         if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
54         {
55           /* Set error code to DMA */
56           huart->ErrorCode = HAL_UART_ERROR_DMA;
57 
58           return HAL_TIMEOUT;
59         }
60       }
61     }
62 
63     UART_EndRxTransfer(huart);
64   }
65 
66   return HAL_OK;
67 }

 

因此在可以在以上函数基础上,添加关闭DMA通道标识,确保在收到串口DMA中断中时只关闭接收DMA,不对发送DMA处理。

 

 1 /**
 2   * @brief Stop the DMA Transfer.
 3   * @param huart UART handle.
 4   * @retval HAL status
 5   */
 6 HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart, char rxtxflag)
 7 {
 8   /* The Lock is not implemented on this API to allow the user application
 9      to call the HAL UART API under callbacks HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback() /
10      HAL_UART_TxHalfCpltCallback / HAL_UART_RxHalfCpltCallback:
11      indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete
12      interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of
13      the stream and the corresponding call back is executed. */
14 
15   const HAL_UART_StateTypeDef gstate = huart->gState;
16   const HAL_UART_StateTypeDef rxstate = huart->RxState;
17 
18 if(rxtxflag&0x02){
19   /* Stop UART DMA Tx request if ongoing */
20   if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) &&
21       (gstate == HAL_UART_STATE_BUSY_TX))
22   {
23     ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
24 
25     /* Abort the UART DMA Tx channel */
26     if (huart->hdmatx != NULL)
27     {
28       if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK)
29       {
30         if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
31         {
32           /* Set error code to DMA */
33           huart->ErrorCode = HAL_UART_ERROR_DMA;
34 
35           return HAL_TIMEOUT;
36         }
37       }
38     }
39 
40     UART_EndTxTransfer(huart);
41   }
42 }
43 if(rxtxflag&0x01){
44   /* Stop UART DMA Rx request if ongoing */
45   if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) &&
46       (rxstate == HAL_UART_STATE_BUSY_RX))
47   {
48     ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
49 
50     /* Abort the UART DMA Rx channel */
51     if (huart->hdmarx != NULL)
52     {
53       if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK)
54       {
55         if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
56         {
57           /* Set error code to DMA */
58           huart->ErrorCode = HAL_UART_ERROR_DMA;
59 
60           return HAL_TIMEOUT;
61         }
62       }
63     }
64 
65     UART_EndRxTransfer(huart);
66   }
67 }
68   return HAL_OK;
69 }

 

posted @ 2023-02-28 11:01  华夏九州  阅读(271)  评论(0编辑  收藏  举报