lrqblack 发表于 2022-12-15 14:43:05

STM32 求一个HAL库的SPI+DMA的重启代码

我用SPI+DMA进行数据传输,但传输到一定时间就会出现SPI数据错位现象,应该是干扰导致的。
于是我添加了检测代码,一旦检测到数据错位就进行SPI和DMA的重启,但是我试了一些API甚至尝试操作寄存器,SPI+DMA传输能被关闭但无法被再次开启。网上的方法也试了,没有用。
求坛友们分享一个SPIDMA复位重启的代码,HAL库或者寄存器都行。谢谢了!

zdg102 发表于 2022-12-15 20:29:31

lrqblack 发表于 2022-12-15 18:03
到底如何关闭再重启呀?兄弟们!
感觉一个很简单的操作竟然这么不容易,郁闷呀。 ...
(引用自9楼)

void spi_enable(SPI_HandleTypeDef * hspi)
{
       

        __HAL_SPI_ENABLE(hspi);
       

}

void spi_disable(SPI_HandleTypeDef * hspi)
{
        HAL_SPI_DMAStop(&hspi1);
       
        __HAL_SPI_DISABLE(hspi);
       
        __HAL_RCC_SPI1_FORCE_RESET();
        __HAL_RCC_SPI1_RELEASE_RESET();
}

这个是spi从机的代码,我是这么操作的,不知道能不能帮到你

yangpeng012 发表于 2022-12-15 15:23:45

SPI+DMA用着一直有问题, 片选线经常提前拉高

skype 发表于 2022-12-15 15:52:49

一直不太会用 SPI + DMA方式,但以下所谓的DMA方式与完全不用DMA的传输速度要快很多倍。

yangpeng012 发表于 2022-12-15 17:07:53

用 SPI+DMA的时候, 片选如果是软件控制方式,片选线什么时候拉高?

tclg 发表于 2022-12-15 17:55:24

我都是用片选软件控制的方式,检测DMA发送完成标志位之后,延时1us再拉高片选信号。

lrqblack 发表于 2022-12-15 17:57:55

yangpeng012 发表于 2022-12-15 17:07
用 SPI+DMA的时候, 片选如果是软件控制方式,片选线什么时候拉高?
(引用自4楼)

我暂时取消了片选,单向发送,相当于是目前没片选

lrqblack 发表于 2022-12-15 18:00:03

tclg 发表于 2022-12-15 17:55
我都是用片选软件控制的方式,检测DMA发送完成标志位之后,延时1us再拉高片选信号。 ...
(引用自5楼)

我之前也是用了片选,和你方法很像,但奇怪的是干扰来了该位移还是位移了,从机多收一个就一直多收一个

tclg 发表于 2022-12-15 18:03:29

你这个情况我遇到过,有一个诀窍是,发送或者接收数据的数组,元素个数要比实际发送或接收的数据定义多一个。比如实际发送10个数据,数组定义个数为11个,这样基本不会有错位的问题。

lrqblack 发表于 2022-12-15 18:03:57

到底如何关闭再重启呀?兄弟们!
感觉一个很简单的操作竟然这么不容易,郁闷呀。

tclg 发表于 2022-12-15 18:18:31

上面我表达的不准确,实际上应该是,接收的数组大小,要比实际传输的数据个数多1

yangpeng012 发表于 2022-12-15 20:13:26

本帖最后由 yangpeng012 于 2022-12-15 20:22 编辑

这个问题的本质是:软件如何知道数据真正发送完成? 从而在正确的时刻拉高片选(既不提前、也不加额外的delay时间开销)。

DMA方式恰恰是外设与CPU分离,这样作为CPU很难真正的知道“外设SPI”何时真正的将数据传输完毕,所以楼上的方法都是为了安全,加一个delay time。目前来看ST的SPI状态寄存器指示的发送完成,并不是数据真正发送完毕了,应该类似于数据已经发送到FIFO,至于FIFO何时传输完毕,不得而知

如果是UART/I2C这种就不需要考虑这些情况,因为没有软件上的片选控制操作,这属于天生的硬件行为差异

按理说,SPI自身的硬件控制片选应该可以知道,毕竟所有外设都是SPI控制器自己控制。 但我我试过用硬件控制片选方式,仍然有提前拉高片选导致 通信异常的问题存在{:dizzy:}

建议研究一下Nuttx 下的SPI外设驱动如何实现,几年前玩开源飞控的时候,记得PX4上的SPI驱动是用DMA实现的,并且非常稳定

denike 发表于 2022-12-16 09:45:14

yangpeng012 发表于 2022-12-15 17:07
用 SPI+DMA的时候, 片选如果是软件控制方式,片选线什么时候拉高?
(引用自4楼)

DMA接收完成中断后拉高片选。

denike 发表于 2022-12-16 09:46:17

tclg 发表于 2022-12-15 17:55
我都是用片选软件控制的方式,检测DMA发送完成标志位之后,延时1us再拉高片选信号。 ...
(引用自5楼)

DMA接收完成中断后拉高片选就行了

denike 发表于 2022-12-16 09:49:47

yangpeng012 发表于 2022-12-15 20:13
这个问题的本质是:软件如何知道数据真正发送完成? 从而在正确的时刻拉高片选(既不提前、也不加额外的del ...
(引用自11楼)

SPI的DMA接收完成中断后拉高片选。接收完成了 才算发送完成。

yangpeng012 发表于 2022-12-16 11:05:11

denike 发表于 2022-12-16 09:45
DMA接收完成中断后拉高片选。
(引用自13楼)

SPI+DMA 发送数据呢?

skype 发表于 2022-12-16 11:20:29

yangpeng012 发表于 2022-12-16 11:05
SPI+DMA 发送数据呢?
(引用自16楼)

SPI CS一般读写之前拉低,操作完成后拉高就行。

skype 发表于 2022-12-16 11:23:18

yangpeng012 发表于 2022-12-16 11:05
SPI+DMA 发送数据呢?
(引用自16楼)

基于不同的SPI芯片,看规格书CS pin的在读写操作中时序。

yangpeng012 发表于 2022-12-16 13:47:42

skype 发表于 2022-12-16 11:20
SPI CS一般读写之前拉低,操作完成后拉高就行。
(引用自17楼)

什么时候算是完成?

skype 发表于 2022-12-16 15:18:12

yangpeng012 发表于 2022-12-16 13:47
什么时候算是完成?
(引用自19楼)

yangpeng012 发表于 2022-12-17 09:38:45

skype 发表于 2022-12-16 15:18

(引用自20楼)

你实战过吗?搞得好像多牛逼似的

zdg102 发表于 2022-12-17 11:39:30

skype 发表于 2022-12-16 15:18

(引用自20楼)

我影像中记得以前遇到过, spi发送完成了,但是最后一个位实际上没发完, 拉高cs就出问题了。   后来逼得没办法, 结合对clk的电平高低来判断有没有发送完成。    时间久了,也不太不记得是不是这样了。


所以,怎么样算是完成,不通芯片,真不好说

lrqblack 发表于 2022-12-19 15:12:05

zdg102 发表于 2022-12-15 20:29
void spi_enable(SPI_HandleTypeDef * hspi)
{
       
(引用自12楼)

感谢兄弟!终于不郁闷了,一点汤圆以表谢意!
页: [1]
查看完整版本: STM32 求一个HAL库的SPI+DMA的重启代码