硬汉嵌入式论坛

 找回密码
 立即注册
查看: 34537|回复: 42
收起左侧

[NUCLEO-H743ZI] 【STM32H743实验例程】实验14:STM32H743串口DMA方式收发,DMA方式问题比较多,要注意数据一致性

  [复制链接]

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
119429
QQ
发表于 2018-4-18 09:50:41 | 显示全部楼层 |阅读模式
实验介绍
开发平台:官方STM32H743 NUCLEO板子
开发环境:MDK5.25正式版
软件版本:
(1)CMSIS软件包 V5.3.0
(2)H7的HAL库版本 V1.2.0

例程说明:

   DMA使用的memory空间使能了Cache的话,空间要做32位字节对齐。同时为了保持数据一致性
   1、AXI RAM空间MPU直接设置为WT模式。
   2、DMA接收后,使用函数SCB_InvalidateDCache_by_Addr做接收缓冲区无效化。
   
   正常情况下,二选一即可,实际测试都不选也能使用,估计是没有被Cache缓存,如果缓存了的话,要注意。


例程下载: 实验14:STM32H743串口DMA方式.7z (1.09 MB, 下载次数: 2557)



  1. #if  1
  2.         ALIGN_32BYTES(__attribute__((section (".RAM_D2"))) uint8_t aRxBuffer[5]) = "ARM";
  3. #else
  4.         __attribute__((section(".RAM_D2"))) uint8_t tt= 20;
  5.         __attribute__((section(".RAM_D2"))) uint8_t aRxBuffer[13] = "KEY_DOWN_K1\r\n";
  6. #endif


  7. /*
  8. *********************************************************************************************************
  9. *        函 数 名: main
  10. *        功能说明: 标准c程序入口。
  11. *        形    参: 无
  12. *        返 回 值: 无
  13. *********************************************************************************************************
  14. */
  15. int main(void)
  16. {        
  17.         uint8_t ucKeyCode;                /* 按键代码 */
  18.         
  19.         
  20.         bsp_Init(); /* 外设初始化 */
  21.   
  22.         bsp_StartAutoTimer(0, 100);        /* 启动1个100ms的自动重装的定时器 */        
  23.         
  24.         HAL_UART_Receive_DMA(&UartHandle, aRxBuffer, 5);
  25.         while (1)
  26.         {
  27.                 bsp_Idle();                /* 这个函数在bsp.c文件。用户可以修改这个函数实现CPU休眠和喂狗 */

  28.                 if (bsp_CheckTimer(0))        /* 判断定时器超时时间 */
  29.                 {
  30.                         /* 每隔100ms 进来一次 */
  31.                         bsp_LedToggle(1);                        
  32.                 }
  33.                
  34.                 if(g_ucRecieveFlag == 1)
  35.                 {
  36.                         g_ucRecieveFlag = 0;
  37.                         bsp_LedToggle(3);
  38.                         
  39.                         /* 设置新的接收,并将接收到发送回去 */
  40.                         /* CPU访问前,将Cache对应的区域无效化 */
  41.                         SCB_InvalidateDCache_by_Addr ((uint32_t *)aRxBuffer, 5);
  42.                         HAL_UART_Transmit_DMA(&UartHandle, aRxBuffer, 5);
  43.                         HAL_UART_Receive_DMA(&UartHandle, aRxBuffer, 5);
  44.                 }
  45.                
  46.                 /* 按键滤波和检测由后台systick中断服务程序实现,我们只需要调用bsp_GetKey读取键值即可。 */
  47.                 ucKeyCode = bsp_GetKey();        /* 读取键值, 无键按下时返回 KEY_NONE = 0 */
  48.                 if (ucKeyCode != KEY_NONE)
  49.                 {
  50.                         switch (ucKeyCode)
  51.                         {
  52.                                 case KEY_DOWN_K1:                        /* K1键按下 */
  53.                                         HAL_UART_Transmit_DMA(&UartHandle, aRxBuffer, 13);
  54.                                         bsp_LedToggle(2);
  55.                                         break;

  56.                                 case KEY_UP_K1:                                /* K1键弹起 */
  57.                                         bsp_LedToggle(2);
  58.                                         break;

  59.                                 case KEY_LONG_K1:                        /* K1长按   */
  60.                                         printf("K1按键长按\r\n");
  61.                                         break;

  62.                                 default:
  63.                                         /* 其它的键值不处理 */
  64.                                         break;
  65.                         }
  66.                 }
  67.         }
  68. }
复制代码

回复

使用道具 举报

714

主题

3709

回帖

5876

积分

论坛元老

积分
5876
发表于 2018-4-18 17:03:59 | 显示全部楼层
不错不错哟
什么时候还是搞 H7 的 emwin 啊 ???
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
119429
QQ
 楼主| 发表于 2018-4-18 17:11:23 | 显示全部楼层
hpdell 发表于 2018-4-18 17:03
不错不错哟
什么时候还是搞 H7 的 emwin 啊 ???

官方的这个NUCLEO板子不支持显示屏,也没有带SDRAM,不太方面,后面倒是可以以太网虚拟一个显示屏用。
回复

使用道具 举报

714

主题

3709

回帖

5876

积分

论坛元老

积分
5876
发表于 2018-4-19 15:34:11 | 显示全部楼层
eric2013 发表于 2018-4-18 17:11
官方的这个NUCLEO板子不支持显示屏,也没有带SDRAM,不太方面,后面倒是可以以太网虚拟一个显示屏用。

期待哟
回复

使用道具 举报

5

主题

95

回帖

110

积分

初级会员

积分
110
发表于 2019-11-21 20:02:32 | 显示全部楼层
mark
回复

使用道具 举报

0

主题

1

回帖

1

积分

新手上路

积分
1
发表于 2020-4-6 18:38:23 | 显示全部楼层
解决了困扰需求的743串口高速接收数据出错问题,谢谢
回复

使用道具 举报

6

主题

54

回帖

72

积分

初级会员

积分
72
发表于 2020-8-3 13:38:53 | 显示全部楼层
大神 我用串口DMA收发接收和发送 的数据都是不能更改的  是怎么回事
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
119429
QQ
 楼主| 发表于 2020-8-4 08:34:01 | 显示全部楼层
fengxiaoyu 发表于 2020-8-3 13:38
大神 我用串口DMA收发接收和发送 的数据都是不能更改的  是怎么回事

注意Cache问题。
回复

使用道具 举报

6

主题

54

回帖

72

积分

初级会员

积分
72
发表于 2020-8-4 08:44:25 | 显示全部楼层

恩,就是Cache问题,是不是用串口DMA收发就用不了Cache了。
回复

使用道具 举报

0

主题

6

回帖

6

积分

新手上路

积分
6
发表于 2021-4-20 21:11:37 | 显示全部楼层
按照这种方式设置还是不行,每次只能接收到1个数据,咋回事啊
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
119429
QQ
 楼主| 发表于 2021-4-21 08:16:36 | 显示全部楼层
lingbuweibu 发表于 2021-4-20 21:11
按照这种方式设置还是不行,每次只能接收到1个数据,咋回事啊

上传你的代码看看。
回复

使用道具 举报

0

主题

6

回帖

6

积分

新手上路

积分
6
发表于 2021-5-7 14:09:07 | 显示全部楼层
dma发送数据可以正常发送,但是整个while的执行周期变慢,不知道咋回事
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
119429
QQ
 楼主| 发表于 2021-5-8 08:19:26 | 显示全部楼层
lingbuweibu 发表于 2021-5-7 14:09
dma发送数据可以正常发送,但是整个while的执行周期变慢,不知道咋回事

HSE_VALUE大小和你板子实际晶振大小一致吧,PLL配置后的主屏也没问题吧,如果这都没有问题,那就没问题。
回复

使用道具 举报

2

主题

25

回帖

31

积分

新手上路

积分
31
QQ
发表于 2021-9-19 15:49:41 | 显示全部楼层
我用你们的V7开发板,有办法做到只用DMA中断,而不用串口中断来接收串口数据吗?我串口接的激光雷达,只要发送了开始数据传输后,串口就一直以接收数据,大概7000个字节每秒,用串口接后中断或空闲中断,中断次数太多。
我移植了你这个例子,将DMA发送关掉,串口中断关掉,只保留DMA接收中断。正常模式。每次都是只能进入中断一次,之后再进行DMA接收HAL_UART_Receive_DMA(&UartHandle, aRxBuffer, 10240);,就收不到数据了,也进不了中断.仿真发现串口RDR没有新的数据进来,但逻辑分析仪一直可以正常抓到数据,说明总线上是有数据的。串口ISR寄存器有溢出错误,在while循环内清除ISR寄存器,可以看到RDR上会进来一个数据,然后再清除一次,进来一个。
请问有遇到过类似的问题吗?
有什么解决方法,或参考例程吗?
回复

使用道具 举报

0

主题

1

回帖

1

积分

新手上路

积分
1
发表于 2022-9-29 15:03:48 | 显示全部楼层
大神,有没有LL库的教程
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
119429
QQ
 楼主| 发表于 2022-9-29 16:16:26 | 显示全部楼层
兔子 发表于 2022-9-29 15:03
大神,有没有LL库的教程

就看HAL的就行,HAL本身不是孤立的,很多外设都要HAL调用LL的API

有时间可以看下这期视频教程:

BSP视频教程第20期:串口专题之玩转HAL库,LL库和寄存器方式实现方法以及参考手册几个关键时序图学习(2022-07-16)
https://forum.anfulai.cn/forum.p ... 3987&fromuid=58
(出处: 硬汉嵌入式论坛)
回复

使用道具 举报

0

主题

1

回帖

1

积分

新手上路

积分
1
发表于 2024-2-7 10:41:52 | 显示全部楼层
HAL_UART_Transmit_DMA发送数据,第一次正常,第二次发送完后就会报usage fault: SCB_CFSR_UFSR:0x01 UNDEFINSTR 这种错误,是什么原因?
回复

使用道具 举报

3

主题

9

回帖

18

积分

新手上路

积分
18
发表于 2024-4-24 12:42:26 | 显示全部楼层
例程下载不了了
回复

使用道具 举报

3

主题

9

回帖

18

积分

新手上路

积分
18
发表于 2024-4-24 12:43:32 | 显示全部楼层
lingbuweibu 发表于 2021-4-20 21:11
按照这种方式设置还是不行,每次只能接收到1个数据,咋回事啊

我遇到了和你一样的情况,请问解决了?
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
119429
QQ
 楼主| 发表于 2024-4-24 14:08:28 | 显示全部楼层
Qasd 发表于 2024-4-24 12:42
例程下载不了了

例程下载正常,是不是你的浏览器阻拦,同意下载即可。
回复

使用道具 举报

0

主题

2

回帖

2

积分

新手上路

积分
2
发表于 2024-5-15 15:07:16 | 显示全部楼层
C:\Users\123\Pictures\Screenshots
回复

使用道具 举报

0

主题

2

回帖

2

积分

新手上路

积分
2
发表于 2024-5-15 15:08:06 | 显示全部楼层
本帖最后由 xcn学stm32 于 2024-5-15 15:45 编辑
eric2013 发表于 2024-4-24 14:08
例程下载正常,是不是你的浏览器阻拦,同意下载即可。

重启了可以下载了
回复

使用道具 举报

0

主题

7

回帖

7

积分

新手上路

积分
7
发表于 2024-5-16 10:35:42 | 显示全部楼层
串口加DMA发送可以,但是就是接收不到数据怎么回事啊,用中断接收就可以
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
119429
QQ
 楼主| 发表于 2024-5-17 08:47:26 | 显示全部楼层
1316146602 发表于 2024-5-16 10:35
串口加DMA发送可以,但是就是接收不到数据怎么回事啊,用中断接收就可以

MPU/Cache不影响数据的发送和接收,影响的是数据的一致性问题。

很大概率是DMA串口的配置问题,比如接收10个字符才会触发DMA传输完成,测试的时候是发送的10个字符不。
回复

使用道具 举报

0

主题

7

回帖

7

积分

新手上路

积分
7
发表于 2024-5-17 11:22:55 | 显示全部楼层
eric2013 发表于 2024-5-17 08:47
MPU/Cache不影响数据的发送和接收,影响的是数据的一致性问题。

很大概率是DMA串口的配置问题,比如接 ...

串口的空闲中断可以触发,DMA的接收中断打开的话也可以触发,但是就是没有数据
回复

使用道具 举报

0

主题

7

回帖

7

积分

新手上路

积分
7
发表于 2024-5-17 11:23:22 | 显示全部楼层
Qasd 发表于 2024-4-24 12:43
我遇到了和你一样的情况,请问解决了?

你解决了吗
回复

使用道具 举报

0

主题

7

回帖

7

积分

新手上路

积分
7
发表于 2024-5-17 20:09:26 | 显示全部楼层
eric2013 发表于 2024-5-17 08:47
MPU/Cache不影响数据的发送和接收,影响的是数据的一致性问题。

很大概率是DMA串口的配置问题,比如接 ...

我是用电脑发送的,发送的绝对也有10个,可以触发,但是就是没有数据
回复

使用道具 举报

0

主题

1

回帖

1

积分

新手上路

积分
1
发表于 2024-10-18 21:41:09 | 显示全部楼层
为什么死活进去不接收空闲中断呀,HAL_UARTEx_ReceiveToIdle_DMA,HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size),进不去
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
119429
QQ
 楼主| 发表于 2024-10-19 09:36:26 | 显示全部楼层
xu. 发表于 2024-10-18 21:41
为什么死活进去不接收空闲中断呀,HAL_UARTEx_ReceiveToIdle_DMA,HAL_UARTEx_RxEventCallback(UART_Handle ...

参考下这个例子。

STM32H7基于STM32CubeMX的串口DMA+空闲中断接收不定长数据实现(HAL库1.9.0自带函数实现)
https://forum.anfulai.cn/forum.php?mod=viewthread&tid=108553
回复

使用道具 举报

0

主题

1

回帖

1

积分

新手上路

积分
1
发表于 2024-12-27 13:03:18 | 显示全部楼层
lingbuweibu 发表于 2021-5-7 14:09
dma发送数据可以正常发送,但是整个while的执行周期变慢,不知道咋回事

我也遇到了同样的问题,整个While执行周期变慢了,串口数据响应没有之前快速了
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
119429
QQ
 楼主| 发表于 2024-12-28 07:32:17 | 显示全部楼层
Allen2023 发表于 2024-12-27 13:03
我也遇到了同样的问题,整个While执行周期变慢了,串口数据响应没有之前快速了

串口的速度远低于SRAM的速度,即使关闭串口所使用SRAM的空间,不会影响到程序执行的,除非你的程序里面做了个串口数据和SRAM的大批量for循环搬运。
回复

使用道具 举报

2

主题

53

回帖

59

积分

初级会员

积分
59
发表于 2025-10-16 15:47:32 | 显示全部楼层
我目前串口DMA的发送出现一个比较奇怪的问题,就是HAL_UART_Transmit_DMA调用的时候,在里面只执行了一次HAL_DMA_Start_IT后就直接return ok了,并只进了一次dma中断,从寄存器来看是触发了半传输,但是NDTR也一直是我发送的字符串的长度,并没有递减,在这之后串口还是一直保持busy,我挨个去查看寄存器发现关于dma和串口的启动都没有问题,就是启动传输的时候没有发生数据的搬运?
回复

使用道具 举报

5

主题

133

回帖

148

积分

初级会员

积分
148
发表于 2025-10-16 23:57:54 | 显示全部楼层
小梁呐 发表于 2025-10-16 15:47
我目前串口DMA的发送出现一个比较奇怪的问题,就是HAL_UART_Transmit_DMA调用的时候,在里面只执行了一次HA ...

HAL_UART_Transmit_DMA 只负责告诉 DMA 启动,成功就 return HAL_DMA_Start_IT,此时 huart->gState 仍为 HAL_UART_STATE_BUSY_TX,在传输完成进入 UART_EndTransmit_IT 时恢复至 HAL_UART_STATE_READY。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
119429
QQ
 楼主| 发表于 2025-10-17 08:50:51 | 显示全部楼层
小梁呐 发表于 2025-10-16 15:47
我目前串口DMA的发送出现一个比较奇怪的问题,就是HAL_UART_Transmit_DMA调用的时候,在里面只执行了一次HA ...

串口有三种发送API,查询,中断和DMA

查询是阻塞的,会执行完毕才返回,而中断和DMA是非阻塞的,执行完毕函数立即返回。需要你在中断回调函数里面判断是否完成。
回复

使用道具 举报

2

主题

53

回帖

59

积分

初级会员

积分
59
发表于 2025-10-17 08:58:31 | 显示全部楼层
本帖最后由 小梁呐 于 2025-10-17 09:05 编辑
Penguins 发表于 2025-10-16 23:57
HAL_UART_Transmit_DMA 只负责告诉 DMA 启动,成功就 return HAL_DMA_Start_IT,此时 huart->gState 仍为 ...

关键就是进中断的时候实际上并没有传输完成,NDTR仍然为字符长度,另外为了测试方便我直接阻塞判断了
回复

使用道具 举报

2

主题

53

回帖

59

积分

初级会员

积分
59
发表于 2025-10-17 09:02:30 | 显示全部楼层
eric2013 发表于 2025-10-17 08:50
串口有三种发送API,查询,中断和DMA

查询是阻塞的,会执行完毕才返回,而中断和DMA是非阻塞的,执行 ...

实际上只进了一次中断,而且进中断的时候并没有传输完成,我刚开始以为第一次进是触发了半传输完成,但是实际上NDTR并没有变化,而且看寄存器也并非是因为错误而触发的中断
回复

使用道具 举报

2

主题

53

回帖

59

积分

初级会员

积分
59
发表于 2025-10-17 09:04:06 | 显示全部楼层
eric2013 发表于 2025-10-17 08:50
串口有三种发送API,查询,中断和DMA

查询是阻塞的,会执行完毕才返回,而中断和DMA是非阻塞的,执行 ...

另外硬汉哥你的这个贴子的程序我昨天也看了,还没发现我的代码有啥明显的问题
回复

使用道具 举报

2

主题

53

回帖

59

积分

初级会员

积分
59
发表于 2025-10-17 09:32:26 | 显示全部楼层
本帖最后由 小梁呐 于 2025-10-17 09:33 编辑
eric2013 发表于 2025-10-17 08:50
串口有三种发送API,查询,中断和DMA

查询是阻塞的,会执行完毕才返回,而中断和DMA是非阻塞的,执行 ...

虽然不知道是什么问题,但是应该基本把问题定位了,因为我个人用的是VSCODE,但是有同事用的是CubeIDE,所以我的工程一直都是CMAKE工程和IDE工程做双工程管理的,虽然比较麻烦,但是之前一直没有出问题,而且之前虽然没有串口DMA,但是也用过SPI+DMA,并没有出现过这类问题

刚刚做了如下尝试,直接将原本的cubemx文件单独生成了一个纯净的IDE工程,同样的代码没有任何问题
回复

使用道具 举报

5

主题

133

回帖

148

积分

初级会员

积分
148
发表于 2025-10-17 11:09:13 | 显示全部楼层
eric2013 发表于 2025-10-17 08:50
串口有三种发送API,查询,中断和DMA

查询是阻塞的,会执行完毕才返回,而中断和DMA是非阻塞的,执行 ...

“在中断回调函数里面判断是否完成” 指什么?UART_EndTransmit_IT 就会置 huart->gState 标志位,不需要再定义变量再在 HAL_UART_TxCpltCallback 作处理了。
回复

使用道具 举报

5

主题

133

回帖

148

积分

初级会员

积分
148
发表于 2025-10-17 11:10:00 | 显示全部楼层
小梁呐 发表于 2025-10-17 09:32
虽然不知道是什么问题,但是应该基本把问题定位了,因为我个人用的是VSCODE,但是有同事用的是CubeIDE, ...

所以你的意思是,只用 IDE 可以,加上 VSCode 就不行了?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-11-21 21:55 , Processed in 0.074235 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表