硬汉嵌入式论坛

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

[STM32H7] SPI 发送间停顿

[复制链接]

1

主题

2

回帖

5

积分

新手上路

积分
5
发表于 2025-3-20 18:19:32 | 显示全部楼层 |阅读模式
本帖最后由 magicNumber 于 2025-3-20 19:01 编辑

在使用h750的硬件spi发送时spi发送数据间总是有较长时间间隔,占了快一半的时间。
9bit发送数据用了200ns,又停了200ns才发,这停顿的200ns在做什么?没搞明白,主频
已尝试过使用hal库,用hal库停顿的时间更长。
波形图,cubemx配置和定义的spi发送函数如下:

波形图

波形图

cubemx配置

cubemx配置

代码

代码
回复

使用道具 举报

24

主题

365

回帖

437

积分

高级会员

积分
437
发表于 2025-3-20 21:08:03 | 显示全部楼层
阻塞去传输是这样的,用DMA才能达到理论传输速度,而且还要确保DMA不会被别的DMA抢占
回复

使用道具 举报

5

主题

162

回帖

177

积分

初级会员

积分
177
发表于 2025-3-20 21:34:20 | 显示全部楼层
不要判断这个,坛主有一个连续发送的。好像是判断TXE?
回复

使用道具 举报

5

主题

162

回帖

177

积分

初级会员

积分
177
发表于 2025-3-20 21:36:26 | 显示全部楼层
使用下面这个
   while (!(SPI_SelectHard->SR & TXE));
                SPI_SelectHard->DR;
回复

使用道具 举报

39

主题

1516

回帖

1638

积分

至尊会员

积分
1638
发表于 2025-3-21 08:25:04 | 显示全部楼层
tovinz 发表于 2025-3-20 21:08
阻塞去传输是这样的,用DMA才能达到理论传输速度,而且还要确保DMA不会被别的DMA抢占


阻塞传输  正常也不会有间隔;除非系统负载非常重
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117530
QQ
发表于 2025-3-21 09:25:07 | 显示全部楼层
这个确实有个间隔的。

下面参数是管理这个间隔的。
/* MIDI, 两个连续数据帧之间插入的最小时间延迟,单位 SPI 时钟周期个数 */
hspi.Init.MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_10CYCLE;

然后DMA方式下确实是有个间隔,即使间隔时间已经配置成了0,不过DMA方式是最小的间隔。

回复

使用道具 举报

1

主题

2

回帖

5

积分

新手上路

积分
5
 楼主| 发表于 2025-3-21 13:28:45 | 显示全部楼层
2859932063 发表于 2025-3-20 21:36
使用下面这个
   while (!(SPI_SelectHard->SR & TXE));
                SPI_SelectHard->DR;

但是在stm32_hal_legacy.h里有
#if defined(STM32H7)
#define SPI_FLAG_TXE                    SPI_FLAG_TXP
所以应该是一样的?
回复

使用道具 举报

1

主题

2

回帖

5

积分

新手上路

积分
5
 楼主| 发表于 2025-3-21 13:33:57 | 显示全部楼层
eric2013 发表于 2025-3-21 09:25
这个确实有个间隔的。

下面参数是管理这个间隔的。

明明已经将 MasterInterDataIdleness 设置成 0cycle 了,为什么还会出现如此长的间隔,这个间隔是代码造成的还是硬件上决定的?有办法调整或解决吗?
回复

使用道具 举报

24

主题

365

回帖

437

积分

高级会员

积分
437
发表于 2025-3-21 16:04:32 | 显示全部楼层
magicNumber 发表于 2025-3-21 13:33
明明已经将 MasterInterDataIdleness 设置成 0cycle 了,为什么还会出现如此长的间隔,这个间隔是代码造 ...

仅个人推测。
一方面你的这个SPI速率已经相当快了,以至于每传输一个字节时轮询发送缓冲区是否空的代码的运行时间变得不可以忽略。再一方面 SPI 毕竟还是一个串行总线,在实现的时候估计用的移位寄存器,这就导致检测到发送缓冲区空到将数据真正开始传输之间存在一个小的时间段,但应该是很小很小的。

H7的 SPI 如果有FIFO,推荐开启FIFO,配置FIFO的下水位线,不要在FIFO剩余待传输数据为0的时候再填充FIFO,这样SPI控制器就能连续不断地从FIFO中取数据进行传输。
再者尝试将代码放到 ITCM 中执行。
回复

使用道具 举报

5

主题

269

回帖

284

积分

高级会员

积分
284
发表于 2025-3-21 16:23:48 | 显示全部楼层
while (!LL_SPI_IsActiveFlag_TXP(spi->Instance))这一句导致的停顿,这是阻塞式收发不可避免的,可以试试用dma方式
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117530
QQ
发表于 2025-3-24 00:27:45 | 显示全部楼层
magicNumber 发表于 2025-3-21 13:33
明明已经将 MasterInterDataIdleness 设置成 0cycle 了,为什么还会出现如此长的间隔,这个间隔是代码造 ...

建议DMA方式测试下看看最小的多少,这个就是最小值了。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-8-13 05:49 , Processed in 0.048563 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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