首页 > 其他分享 >串口DMA接收到数据后,DMA停止对外发送数据

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

时间:2023-02-28 11:14:36浏览次数:33  
标签:DMA HAL CR3 UART huart Abort 串口 发送数据

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 }

 

标签:DMA,HAL,CR3,UART,huart,Abort,串口,发送数据
From: https://www.cnblogs.com/better-day/p/17163270.html

相关文章

  • 8.4-DMA方式
    DMA方式的基本原理数据的传送不经过CPU,由DMA控制器实现内存和外设,外设和外设之间的直接快速传递用于需要高速大批量数据传送系统中 DMA传输计算机系统构成DMA控制......
  • 3DMAX安装失败怎么办?安装3DMAX失败提示错误怎么解决?
    3DMAX安装失败怎么办?安装3DMAX失败提示错误怎么解决?有很多同学想把3DMAX卸载后重新安装,但是发现3DMAX安装到一半就失败了或者显示3DMAX已安装或者安装未完成,大多数情况下......
  • stm32f407探索者开发板(十七)——串口寄存器库函数配置方法
    文章目录​​一、STM32串口常用寄存器和库函数​​​​1.1常用的串口寄存器​​​​1.2串口相关的库函数​​​​1.3状态寄存器(USART_SR)​​​​1.4数据寄存器(USART_D......
  • stm32f407探索者开发板(十八)——串口通信实验讲解(USART_RX_STA流程图详解)
    文章目录​​一、uart_init(串口初始化)​​​​二、USART1_IRQHandler(串口1中断服务程序)​​​​三、main.c(主函数)​​​​四、关于printf的支持​​一、uart_init(串口初始化......
  • python计算Friedman排名代码
    python计算Friedman排名代码首先先说输入数据,为了迅速处理,采用csv格式的表格,读者可以先理解这里提供的示例和代码,再自行调整下面是代码,代码会生成一个排名文件Rank.c......
  • Podman 和 Docker 区别对比
    1.docker需要在我们的系统上运行一个守护进程(dockerdaemon),而podman不需要2.启动容器的方式不同:dockercli命令通过API跟DockerEngine(引擎)交互告诉它我想创建一个c......
  • 6.3dmax小场景案例
    #知识点: 1.cut剪切---快捷键alt+c 2.仅影响轴、坐标轴回到物体中心 3.Mirror镜像 4.attach附加、detach分离 5.Collapse、Weld合点 6.bevel倒角 7.桌面下的......
  • QT做串口助手(详解)BY LZQ
    QT做串口的完整代码:main.cpp#include"myserial.h"#include<QApplication>intmain(intargc,char*argv[]){QApplicationa(argc,argv);MySerial......
  • QT做的串口
    QT做串口:main.cpp#include"myserial.h"#include<QApplication>intmain(intargc,char*argv[]){QApplicationa(argc,argv);MySerialw;w.sho......
  • QT做串口通信(串口助手)
    QT做串口:main.cpp#include"myserial.h"#include<QApplication>intmain(intargc,char*argv[]){QApplicationa(argc,argv);MySerialw;w.sho......