硬汉嵌入式论坛

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

[UART] STM32H7基于STM32CubeMX的串口DMA+空闲中断接收不定长数据实现(HAL库1.9.0自带函数实现)

  [复制链接]

5

主题

192

回帖

212

积分

高级会员

积分
212
发表于 2021-8-31 20:06:17 | 显示全部楼层 |阅读模式
STM32V7.rar

以前ST没有给串口空闲接收方式提供API,但是最近发现ST系列的芯片都更新了相关的API
新增的函数实现在这个 stm32h7xx_hal_uart_ex.c 文件下
现在我们来看看STM32V7开发板上串口1的实现
printf打印.png

串口1 while.png

串口空闲中断回调.png

这是运行起来的效果
STM32V7串口GIF.gif

MPU了解的不深,开启cache 开DMA会打架,先关闭数据缓存和MPU,开启指令缓存
STM32V7 MPU.png



以下是CubeMX上的配置 printf不使用微库,通过RTE下添加EVR打印
printf EVR.png

串口1DMA.png
串口1参数.png
串口1管脚.png
串口1中断.png
串口1MX代码生成方式.png



评分

参与人数 1金币 +100 收起 理由
eric2013 + 100 很给力!

查看全部评分

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106649
QQ
发表于 2021-8-31 20:13:29 | 显示全部楼层
非常感谢楼主分享。
回复

使用道具 举报

44

主题

562

回帖

699

积分

金牌会员

积分
699
发表于 2021-8-31 21:04:06 | 显示全部楼层
谢谢分享,正好在调试这个功能
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106649
QQ
发表于 2021-9-9 17:11:12 | 显示全部楼层
好多网友咨询,有必要置顶下。
回复

使用道具 举报

0

主题

1

回帖

1

积分

新手上路

积分
1
发表于 2021-10-7 20:48:47 | 显示全部楼层
只能下载1次 好像是禁止debug了
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106649
QQ
发表于 2021-10-8 09:33:44 | 显示全部楼层
jb123456 发表于 2021-10-7 20:48
只能下载1次 好像是禁止debug了

帮你测试了下,正常。
回复

使用道具 举报

12

主题

75

回帖

111

积分

初级会员

积分
111
发表于 2021-10-8 22:10:24 | 显示全部楼层
http://www.armbbs.cn/forum.php?mod=viewthread&tid=97172

我这个里面cache和DMA和谐相处
回复

使用道具 举报

0

主题

11

回帖

11

积分

新手上路

积分
11
发表于 2021-11-1 16:56:36 | 显示全部楼层
我按这个修改,只能接收到最后一个字符,数据长度是对的。
回复

使用道具 举报

0

主题

11

回帖

11

积分

新手上路

积分
11
发表于 2021-11-2 10:54:29 | 显示全部楼层
CPU是H725,去掉DMA,使用中断方式后正确。
回复

使用道具 举报

5

主题

192

回帖

212

积分

高级会员

积分
212
 楼主| 发表于 2021-11-3 18:05:28 | 显示全部楼层
ZCBC 发表于 2021-11-2 10:54
CPU是H725,去掉DMA,使用中断方式后正确。

你的是V7开发板吗? 我的例程关闭了cache,你是不是开了cache?
回复

使用道具 举报

0

主题

11

回帖

11

积分

新手上路

积分
11
发表于 2021-11-3 22:53:52 | 显示全部楼层
旮旯旭 发表于 2021-11-3 18:05
你的是V7开发板吗? 我的例程关闭了cache,你是不是开了cache?

不是V7,用的是STM32H725。CACHE关闭了。估计就的DMA那里没有处理好。
回复

使用道具 举报

2

主题

23

回帖

29

积分

新手上路

积分
29
发表于 2021-11-9 14:15:13 | 显示全部楼层
用MPU保护好目标地址就可以开cache了,配置如下,
void MPU_Config(void)
{
  MPU_Region_InitTypeDef MPU_InitStruct = {0};

  /* Disables the MPU */
  HAL_MPU_Disable();
  /** Initializes and configures the Region and the memory to be protected
  */
  MPU_InitStruct.Enable = MPU_REGION_ENABLE;
  MPU_InitStruct.Number = MPU_REGION_NUMBER0; //找一个空闲的用
  MPU_InitStruct.BaseAddress = (uint32_t)UART_BUF;//DMA的目标地址,UART数组的指针
  MPU_InitStruct.Size = MPU_REGION_SIZE_256B;//找打相应配置字,保护长度要大于数组长度
  MPU_InitStruct.SubRegionDisable = 0x0;
  MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
  MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
  MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
  MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
  MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;//关闭这段内存的缓存功能,就不会有同步打架的问题了
  MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;

  HAL_MPU_ConfigRegion(&MPU_InitStruct);
  /* Enables the MPU */
  HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);

}
回复

使用道具 举报

10

主题

130

回帖

160

积分

初级会员

积分
160
发表于 2021-11-11 15:17:51 | 显示全部楼层
楼主的研究精神还是很不错的,不过之前已经在这里看到过相应的方法https://controllerstech.com/uart-dma-with-idle-line-detection/    是否要加上__HAL_DMA_DISABLE_IT呢?
回复

使用道具 举报

5

主题

192

回帖

212

积分

高级会员

积分
212
 楼主| 发表于 2021-11-13 10:20:53 | 显示全部楼层
oneV 发表于 2021-11-11 15:17
楼主的研究精神还是很不错的,不过之前已经在这里看到过相应的方法https://controllerstech.com/uart-dma-w ...

仔细看下中断处理函数在调用HAL_UARTEx_RxEventCallback前有个HAL_DMA_Abort函数,这个函数里面的处理就是关系DMA中断的,用HAL库的好处就是傻瓜式,如果看明白了,很多中间的操作HAL都给你考虑到了,用户只需要关注应用层的实现
回复

使用道具 举报

3

主题

13

回帖

22

积分

新手上路

积分
22
发表于 2022-3-4 16:24:47 | 显示全部楼层
您好,打扰问下您这个stm32h7xx_hal_uart_ex.c  文件可以直接覆盖以前的文件不?不会有哪里不兼容吧?谢谢
回复

使用道具 举报

5

主题

192

回帖

212

积分

高级会员

积分
212
 楼主| 发表于 2022-3-5 10:31:31 | 显示全部楼层
arm_uclinux 发表于 2022-3-4 16:24
您好,打扰问下您这个stm32h7xx_hal_uart_ex.c  文件可以直接覆盖以前的文件不?不会有哪里不兼容吧?谢谢

你看下HAL库的版本,如果以前没stm32h7xx_hal_uart_ex.c的话,你最好吧HAL库的版本都重新导入下。因为这个 ex.c 属于扩展功能,支持扩展功能,原先的中断处理函数有的函数也是做了适配的。你说的覆盖是哪种覆盖? 不要单独覆盖一个文件,选择相应的HAL库版本比较好,我用最新的 1.9.1 也正常
回复

使用道具 举报

7

主题

42

回帖

63

积分

初级会员

积分
63
发表于 2022-7-24 21:00:43 | 显示全部楼层
确实因为把不用的拐角配置成模拟的导致的。一进入 gpio初始化jlink就挂了。估计因为是某些引脚在板子的别的地方复用,么有细察,代码里注释掉gpio 初始化的代码就可以debug了。吓我一条,以为是我的板子或者 jlink的问题。
企业微信截图_16586673987724.png
回复

使用道具 举报

5

主题

61

回帖

76

积分

初级会员

积分
76
发表于 2022-8-27 16:09:27 | 显示全部楼层
这个是什么鬼  FrameworkCubeMX.gpdsc is missing

FrameworkCubeMX.gpdsc is missing

FrameworkCubeMX.gpdsc is missing
回复

使用道具 举报

5

主题

192

回帖

212

积分

高级会员

积分
212
 楼主| 发表于 2022-8-28 16:17:07 | 显示全部楼层
dghwjh 发表于 2022-8-27 16:09
这个是什么鬼  FrameworkCubeMX.gpdsc is missing

你是RTE配置的? 我一般都是CubeMX配置生成代码,RTE有时候不好用
回复

使用道具 举报

13

主题

57

回帖

96

积分

初级会员

积分
96
发表于 2022-10-31 11:44:57 | 显示全部楼层
这个测试过多个串口公用吗‘?  我用两个串口dma  发现有一个就接收不到’
回复

使用道具 举报

5

主题

192

回帖

212

积分

高级会员

积分
212
 楼主| 发表于 2022-11-1 22:38:46 | 显示全部楼层
years 发表于 2022-10-31 11:44
这个测试过多个串口公用吗‘?  我用两个串口dma  发现有一个就接收不到’

测试过啊,我开了4个串口接收发送没问题
回复

使用道具 举报

0

主题

26

回帖

26

积分

新手上路

积分
26
发表于 2022-11-24 20:39:13 | 显示全部楼层
STM32F446VE上使用上面的代码,接收几秒数据后串口就不工作了
回复

使用道具 举报

5

主题

192

回帖

212

积分

高级会员

积分
212
 楼主| 发表于 2022-11-25 09:28:15 | 显示全部楼层
miaoguoqiang 发表于 2022-11-24 20:39
STM32F446VE上使用上面的代码,接收几秒数据后串口就不工作了

方便传一份代码看下?
回复

使用道具 举报

44

主题

562

回帖

699

积分

金牌会员

积分
699
发表于 2022-11-28 13:52:54 | 显示全部楼层
浪里个白条 发表于 2021-11-9 14:15
用MPU保护好目标地址就可以开cache了,配置如下,
void MPU_Config(void)
{

确实可行,没有保护接收到的数据就是错误的
回复

使用道具 举报

1

主题

1

回帖

4

积分

新手上路

积分
4
发表于 2022-12-1 23:19:23 | 显示全部楼层
ZCBC 发表于 2021-11-1 16:56
我按这个修改,只能接收到最后一个字符,数据长度是对的。

也遇到这个坑,/* Initialize all configured peripherals */初始化时候USART被放到了DMA_Init之前,调换顺序就解决了,上次在G4上也遇到了,坑爹的自动生成代码
回复

使用道具 举报

5

主题

5

回帖

20

积分

新手上路

积分
20
发表于 2023-1-2 12:22:26 | 显示全部楼层
我这还得清空缓存区
回复

使用道具 举报

5

主题

192

回帖

212

积分

高级会员

积分
212
 楼主| 发表于 2023-1-3 09:19:06 | 显示全部楼层
1571946997 发表于 2023-1-2 12:22
我这还得清空缓存区

你是开了D-CACHE吧,关闭的话就不用,开启的话必须要MPU
回复

使用道具 举报

4

主题

32

回帖

44

积分

新手上路

积分
44
发表于 2023-2-2 13:42:23 | 显示全部楼层
jb123456 发表于 2021-10-7 20:48
只能下载1次 好像是禁止debug了

把MX_GPIO_Init();屏蔽掉就好了
回复

使用道具 举报

0

主题

1

回帖

1

积分

新手上路

积分
1
发表于 2023-7-9 15:30:19 | 显示全部楼层
楼主好,你说的 ------ "串口空闲接收方式" 啥意思???
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106649
QQ
发表于 2023-7-10 08:09:13 | 显示全部楼层
usbbc 发表于 2023-7-9 15:30
楼主好,你说的 ------ "串口空闲接收方式" 啥意思???

串口空闲中断。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106649
QQ
发表于 2023-12-15 16:36:10 | 显示全部楼层
由于设置了空闲引脚模拟输入,下载的时候选上这个即可解决。

下载.png
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106649
QQ
发表于 2023-12-20 18:55:03 | 显示全部楼层
网友咨询的问题,记录下

测试150个字符收发正常

QQ图片20231220185421.png
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106649
QQ
发表于 2023-12-20 20:14:55 | 显示全部楼层
使用函数HAL_UARTEx_ReceiveToIdle_DMA做超时接收整理:
1、半DMA传输完成中断UART_DMARxHalfCplt     调用  HAL_UARTEx_RxEventCallback,标识继续为HAL_UART_RECEPTION_TOIDLE
2、DMA传输完成中断UART_DMAReceiveCplt       调用   HAL_UARTEx_RxEventCallback,标识继续为HAL_UART_RECEPTION_TOIDLE
3、如果传输期间触发了空闲,DMA又没有传输完成,调用串口中断HAL_UART_IRQHandler,空闲标识处理的HAL_UARTEx_RxEventCallback,并设置HAL_UART_RECEPTION_STANDARD
回复

使用道具 举报

0

主题

2

回帖

2

积分

新手上路

积分
2
发表于 2023-12-21 17:41:35 | 显示全部楼层
楼主分享的特别好,大家在调试时一定要注意:先DMA初始化,后UART初始化;cubeMX生成的顺序可能会错误。。。调到怀疑人生
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-27 22:49 , Processed in 0.352138 second(s), 29 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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