[STM32F1] stm32 SPI+DMA 发送,传输过程没有完成就触发SPI发送空

[复制链接]
778|18
ljxh401 发表于 2025-11-13 13:51 | 显示全部楼层 |阅读模式
本帖最后由 ljxh401 于 2025-11-14 00:50 编辑

两片STM32F103进行SPI通信,
主机采用SPI+DMA进行发送,分机DMA接收,监控片选脚的上升沿中断
主机设置拉低片选脚,DMA发送,设置SPI发送寄存器空中断,在spi发送空中断中拉升片选脚
结果发送32字节数据,分机CPU只接收到10字节数据,
如果取消spi发送空中断里面拉升片选脚的,分机能接收完整数据


最后修改成 启动DMA发送中断,发送完毕进入dma中断,
在dma中断中才启动SPI发送空中断,

我原来觉得 启动 DMA 是不会中途触发 TXE 事件的,直到DMA结束,但是发现在dma的传输过程就产生了txe中断,导致错误关闭CS信号
觉得很奇怪了,为什么DMA没有会发送了10个字节后卡断了一下 这个才是我觉得不明白的地方


classroom 发表于 2025-11-13 14:08 | 显示全部楼层
在TXE中断中拉高CS会破坏SPI传输时序。SPI传输需保证CS在整个数据帧传输期间保持低电平,否则从机会认为传输结束,导致数据截断。
cr315 发表于 2025-11-13 14:09 | 显示全部楼层
可能DMA与SPI中断冲突
duo点 发表于 2025-11-13 15:09 | 显示全部楼层
在中断服务函数中快速清除标志位,避免中断嵌套延迟。
elephant00 发表于 2025-11-13 14:10 | 显示全部楼层
DMA传输完成中断优先级高于SPI全局中断
flycamelaaa 发表于 2025-11-13 18:11 | 显示全部楼层
降低SPI时钟速率
jcky001 发表于 2025-11-13 17:12 | 显示全部楼层
可以尝试用SPI的FIFO功能
onlycook 发表于 2025-11-13 18:14 | 显示全部楼层
可能是CS提前拉高导致传输中断
powerantone 发表于 2025-11-13 20:14 | 显示全部楼层
中断优先级冲突吧
probedog 发表于 2025-11-13 21:16 | 显示全部楼层
CS必须在DMA传输完成后拉高,且SPI中断仅用于数据填充,不操作CS。
probedog 发表于 2025-11-13 22:16 | 显示全部楼层
主机使用1线发送模式,从机使用1线接收模式,避免全双工模式干扰。
solty 发表于 2025-11-13 15:57 | 显示全部楼层
主机在启动DMA前拉低CS,在DMA_TC中断中拉高CS。
qinlu123 发表于 2025-11-13 18:54 | 显示全部楼层
可以借鉴一下HAL库的处理方法,SPI这种总线用DMA非常麻烦,不光要准确处理CS还要在开始发送前判断SPI是不是空闲,如果用阻塞式判断DMA白用,用非阻塞式判断那么程序写起来逻辑会非常复杂
 楼主| ljxh401 发表于 2025-11-14 00:50 | 显示全部楼层
classroom 发表于 2025-11-13 14:08
在TXE中断中拉高CS会破坏SPI传输时序。SPI传输需保证CS在整个数据帧传输期间保持低电平,否则从机会认为传 ...

我原来觉得 启动 DMA 是不会中途触发 TXE 事件的,直到DMA结束,但是发现在dma的传输过程就产生了txe中断,导致错误关闭CS信号
觉得很奇怪了,为什么DMA没有会发送了10个字节后卡断了一下 这个才是我觉得不明白的地方
 楼主| ljxh401 发表于 2025-11-14 00:51 | 显示全部楼层
elephant00 发表于 2025-11-13 14:10
DMA传输完成中断优先级高于SPI全局中断

我原来觉得 启动 DMA 是不会中途触发 TXE 事件的,直到DMA结束,但是发现在dma的传输过程就产生了txe中断,导致错误关闭CS信号
觉得很奇怪了,为什么DMA没有会发送了10个字节后卡断了一下 这个才是我觉得不明白的地方
 楼主| ljxh401 发表于 2025-11-14 00:52 | 显示全部楼层
solty 发表于 2025-11-13 15:57
主机在启动DMA前拉低CS,在DMA_TC中断中拉高CS。

DMA_TC后启动 SPI的TXE
在TXE中拉高CS
因为DMA_TC只是将数据传输到SPI
wangshujun 发表于 2025-11-15 09:46 | 显示全部楼层
spi的txe代表的是发送缓冲区空,这时spi还有最后一帧数据没法送完,dma的tc发生的时候,除了正在发送的字节外,还有发送缓冲区里面的一帧,这两个用来控制cs都不太合适
如果你遇到的是固定少一个或者两个字节的话,是上面的问题
但是你提到的是少了很多个字节,这应该是总线竞争导致的时许间隔导致的DMA数据不连续,进而导致的txe毛刺,这个毛刺很短,不会导致发送数据的不连续,因为txe出现时还有正在发送的一个字节在传输,但是接收端可能响应到
如果发送方的cs控制,恰好是spi硬件的ss引脚,那么可以用spi硬件的ss自动控制。
如果发送方的cs选用的时普通gpio,最简单的时在dma的tc中断里面等待spi的busy信号无效后,改变cs,适用性没有问题,但是中断里面需要出现2个字节的等待时间,如果spi速度不是很高,这个时间很难接受,这时可以考虑在tc终端里面启动一个2字节传输时间的定时器中断,在定时器里面完成cs的控制
 楼主| ljxh401 发表于 2025-11-18 14:53 | 显示全部楼层
wangshujun 发表于 2025-11-15 09:46
spi的txe代表的是发送缓冲区空,这时spi还有最后一帧数据没法送完,dma的tc发生的时候,除了正在发送的字节 ...

和你分析的一致,我采用的解决方法是先 在dma中断中启动 发送空中断
在发送空中断中释放 对硬件的占用 信号量
wangshujun 发表于 2025-11-19 09:11 | 显示全部楼层
发送空中断,还是早了一个字节的
您需要登录后才可以回帖 登录 | 注册

本版积分规则

55

主题

246

帖子

4

粉丝
快速回复 在线客服 返回列表 返回顶部