
STM32F407外接24位ADC, 用ADC的DATAREADY信号触发SPI通讯接收数据,且希望启动DMA存储一组ADC数据,这个应用怎么实现?查了网上帖子建议用timer事件捕捉响应DATAREADY信号启动SPI的DMA通讯,SPI是8位或16位的数据传输,而ADC的数据是24位或32位的,所以可以用SPI的DMA接收3个Byte或4个Byte,完成一个数据的接收,但是问题在于,下一次DATAREADY信号来了以后,如何不要CPU的干预把DMA的接收地址自动增加到下一个数据地址? |
STM32 F407骄阳电机版用DMA双缓存接收串口数据时,上电第一次接收区是memory1而不是memory0?
STM32F407骄阳版用DMA双缓存区接收串口数据,上电第一次接收到的数据在memory1而不是memory0
stm32f407无法配置定时器2为全部dma
FreeRTOS问题求解
使用stm32F407连接PHY芯片进行以太网通讯,一插网线就会进入错误中断。
定时器使用DMA突发传输功能时,传入指针从常量数组改为变量数组后,传输功能异常。测试官方用例一样,是何原因?
ST的IMU和地磁计用motionfx库融合后航向角异常的问题
CUEBIDE生成的APP程序,在写入FLASH之后无法正常跳转。
有关Cubeide IAP 问题
STM32U3 IIC通信后,SPI+GPDMA 进入循环发送,DMA无法使能 寄存器USEF=1
这个问题的关键点是adc转换须用spi把数据传出,而一次启动spi的传输又难以分割成若干次传输,且不想mcu干涉每个点的获取,也就是在采集1024个数据结束前要求mcu不介入,因此,解决的方法就变成每一次adc的dataready信号纯硬件触发spi传输。这里提供一个思路,具体实现要参照手册,看f407是否满足,我知道g4是可以这样做的。
(1)mcu的spi和adc的spi都配置成从模式,它的clk信号来自高级计时器(比如tim1)的输出。
(2)dataready接入tim1的输入,tim1配成slave trigger模式,同时tim1的rcr counter设成24,目的是每个dataready信号沿让tim1产生固定个数24个时钟,这个时钟作为spi的时钟,这样,意味着,每次dataready就会触发adc传3个字节到mcu的spi
(3)申请1024*3=3072个字节的数组,配置spi rx dma normal 3072个数据
(4)在进入dma的tc中断后,表示1024个数据已经被采到,在adc的采集过程中,mcu不干预
timer捕捉到DATAREADY下降沿产生一个DMA request,这个DMA的数据源地址是SPI的数据寄存器,且MCU的SPI是主,目的地址是数组的首地址。当DMA request发起后,SPI开始发送数据,重复发送3个Byte(当接收24位ADC数据),或4个Byte(当接收32位ADC数据),同时会接收到相应长度的ADC数据。每次DATAREADY信号被ADC芯片拉低就会发起一个SPI DMA传输,接收当前ADC转换的数据,这个过程我没疑问,我担心的是,每次数据都会被搬到数组的首地址,而不是递增的地址,因为地址的递增实际上是每次传输3个Byte或4个Byte时的地址递增,而不是数组元素的地址递增。结果就是传输结束以后,数组里只有第一个元素有数据,也就是最后一次DMA传输得到的数据。不知道我这个担心是否正确,最后还得写代码验证。
坦率地说,挺怀疑作者的说法。从逻辑上讲,spi的dma搬运应该发生在spi的dr寄存器或者fifo有收到数据后才触发,这是连续的两个动作。对作者上述说法的理解是,dataready之后,必须有发生spi传输(不知怎么让spi传输,作者要求mcu不能干预,仅仅依靠硬件触发,尚不知怎么不用mcu干预而用信号链让spi传输),当且仅当一个字节或者半字传输好之后,timer能捕捉到这个事件,暂时不知哪个信号或者信息能满足这个要求,倘若仅凭timer的定时溢出判断,个人认为是有风险,需保证adc的时钟和mcu的时钟要一致,否则无法确保先后的时序。
1. 硬件连接和配置。adc的dataready连接mcu的某个io,充当外部触发;mcu的spi外设连接adc的spi专用管脚,mcu的spi配置成master,8bit接收,配置spi rx dma,dma circular模式,每次接收3个字节。
2. 控制流程。adc转换成功,dataready外部触发mcu,在外部触发中断callback里,启动spi dma接收3个字节,这样3个字节自动被搬运到变量里,在dma的tc中断里,可以处理接收到的数据
硬件连接和配置就是根据第一条建议进行的。如果根据第二条建议,每次DATAREADY信号来了以后,CPU要做中断处理,就没有达到不需要CPU干预采多个数据点的目的。现在想实现的是用DMA功能采集1024个数据点,然后给一个信号给CPU,CPU对这1024点做FFT。
ADC芯片是MCP3564, 数据手册下载链接:https://ww1.microchip.com/downloads/aemDocuments/documents/APID/ProductDocuments/DataSheets/MCP3561_2_4R-Data-Sheet-DS200006391C.pdf
不知道这样操作是否可行:
1)DATAREADY连到Timer输入捕捉,DATAREADY高到低触发SPI DMA,MCU为主,数据宽度为8bit,用FIFO模式,4个Byte后一次性传输4个Byte到内存。
2)DMA传输模式设为重复传输,源地址不递增,目的地地址递增。重复次数为1024。
第一点应该没问题,第二点是否可行不清楚,请高手指点。
我看第一点有问题,spi rx dma只能是spi的RXNE=1的时候触发,意味着spi的dr收到数据,此时才request dma去读数据,dataready无法触发spi的rx dma
第一点的关键是DATAREADY信号通过timer的事件捕捉触发SPI的DMA,正是因为DATAREADY信号无法触发SPI DMA,才需要timer的事件捕捉帮忙。
楼主说的timer的事件捕捉触发spi的dma,这个是怎么实现的?能具体说说看
DATAREADY信号下降沿被timer事件捕捉到以后可以产生中断或DMA,这里选择DMA,然后配置DMA的时候,源地址是SPI数据寄存器的地址,终地址是内存量数组的起始地址,这就把外接触发信号用timer转接到了SPI的DMA启动上了。
DMA开始搬运需要reuqest 信号,用那个事件产生request 信号呢?
timer的事件捕捉可以产生DMA request