完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
主芯片是 STM32H743X,SPI-FLASH是 W25Q256,使用HAL库(V1.8)。 如果SPI不使用DMA模式,则 W25Q256 数据读写正确。如果SPI使用DMA模式,则不正确,例如反复读取 W25Q256 的ID,只有第一次能正确读到,后续都只能读取到0。
SPI初始化代码如下: spiFlash1Handle.Init.Mode = SPI_MODE_MASTER; //设置SPI工作模式,设置为主模式 spiFlash1Handle.Init.Direction = SPI_DIRECTION_2LINES;//设置SPI单向或者双向的数据模式:SPI设置为双线模式 spiFlash1Handle.Init.DataSize = SPI_DATASIZE_8BIT; //设置SPI的数据大小:SPI发送接收8位帧结构 spiFlash1Handle.Init.CLKPolarity = SPI_POLARITY_LOW; //串行同步时钟的空闲状态为低电平 电路中下拉 spiFlash1Handle.Init.CLKPhase = SPI_PHASE_1EDGE; //串行同步时钟的第一个跳变沿(上升或下降)数据被采样 spiFlash1Handle.Init.NSS = SPI_NSS_HARD_OUTPUT; //NSS信号由软件管理 spiFlash1Handle.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;//NSS信号脉冲失能 spiFlash1Handle.Init.IOSwap = SPI_IO_SWAP_DISABLE;//SPI_IO_SWAP_ENABLE; spiFlash1Handle.Init.NSSPolarity = SPI_NSS_POLARITY_LOW; spiFlash1Handle.Init.MasterInterDataIdleness = SPI_MASTER_SS_IDLENESS_02CYCLE; spiFlash1Handle.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_ENABLE; //SPI主模式IO状态保持使能 spiFlash1Handle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;//定义波特率预分频的值:波特率预分频值为64 spiFlash1Handle.Init.FirstBit = SPI_FIRSTBIT_MSB; //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始 spiFlash1Handle.Init.FifoThreshold = SPI_FIFO_THRESHOLD_01DATA; //1个字节的FIFO spiFlash1Handle.Init.TIMode = SPI_TIMODE_DISABLE; //关闭TI模式 spiFlash1Handle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;//关闭硬件CRC校验 spiFlash1Handle.Init.CRCPolynomial = 7; //CRC值计算的多项式 经过几天的测试,发现是SPI模块的FIFO在作怪。在HAL库中,函数 HAL_SPI_TransmitReveive_DMA( ) 中操作过程是:配置RXDMA -> 设置 CFG1.RXDMAEN -> 配置TXDMA -> 设置 CFG1.TXDMAEN -> 设置 CR1.SPE -> 设置 CR1.CSTART。 这个过程看起来没有错,但在实际运行时,到“设置 CFG1.TXDMAEN”后,对应DMA的 SR.HTIF 和 SR.TCIF 立即被置上,并进了相应的DMA完成中断。而此时“设置 CR1.SPE” 和 “设置 CR1.CSTART”都还没执行,MOSI、SCK上也没有波形输出,当执行完 “设置 CR1.CSTART”之后,时钟、数据才有波形输出,之后进入RXDMA完成中断。 而到了第二次,同样的处理过程,到“设置 CFG1.TXDMAEN”后,会同时进TXDMA完成中断 和 RXDMA完成中断,导致接收到的数据全为0,因为此时并没有实际收发数据,执行完 “设置 CR1.CSTART”之后,数据才真正发送出去。 根据以上现象,我的推测结果是,一设置 CFG1.TXDMAEN,SPI模块就会把Txduf中的数据搬到SPI的TXFIFO中,致使产生TXDMA完成中断,数据实际并没有被发出去,直到 “设置 CR1.CSTART”后,才开始将TXFIFO中的数据发送出去。之所以第二次及以后会同时产生TXDMA和RXDMA中断,是因为SPI的RXFIFO被SPI模块认为没读空(实际已经被DMA读走),RXFIFO显示内部有数据(SPI寄存器SR.RXWNE 和 RXPLVL不为0),使得后续只要一设置 CFG1.TXDMAEN,就发生RXDMA完成中断。 根据猜测,进行了大于16字节(SPI模块FIFO的大小)的测试,发现使用DMA方式时,只能发送16字节的数据,例如DMA设置为40个字节,“设置 CFG1.TXDMAEN”后,对应DMA的 SR.HTIF 和 SR.TCIF 立即被置上,但 “设置 CR1.CSTART”后,MOSI和SCK上的波形,只有16个字节的宽度。 无论我将FIFO阈值(CFG1.FTHVL)设置为多少,现象都是一样,CFG1.TXDMAEN之后,就会DMA数据传输到TXFIFO中,并且最多只能发16个字节。 各位大神,有没有知道怎么解决这个问题,我想把SPI模块的FIFO禁止了,但没找到办法,资料没写,寄存器里也没有。 |
|
相关推荐
2个回答
|
|
不应该只能发送16个字节的,否则没法用了呀。官方有个例程,用DMA的,试试,可已发送的{:1:}。
STM32Cube_FW_H7_V1.7.0ProjectsNUCLEO-H743ZIExamplesSPISPI_FullDuplex_ComDMAEWARM |
|
|
|
根据提供的信息,可能会有几个可能的原因导致SPI使用DMA模式时与W25Q256芯片通信不正确:
1. DMA传输设置不正确:在使用DMA模式时,需要正确配置DMA通道和传输长度。可能需要检查DMA配置是否正确,并确保传输长度足够。 2. DMA传输冲突:可能存在DMA传输冲突问题,尤其是如果有其他设备也使用了DMA。确保SPI和其他设备在DMA传输时没有冲突。 3. SPI通信时序问题:W25Q256可能对SPI的时序要求较高。请确保SPI时钟频率和时序参数(例如极性和相位)设置正确。 4. FIFO溢出问题:在高速传输中,如果DMA的传输速度超过W25Q256芯片的处理能力,可能会导致DMA传输期间FIFO溢出。可以通过降低DMA传输速度或增加SPI的时钟频率来解决此问题。 5. 软件错误:请确保在读取W25Q256芯片时,正确设置读取命令和地址,并在DMA传输开始之前发送这些命令和地址。 建议逐一排查上述问题,以确定导致数据读写错误的确切原因。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1617 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1543 浏览 1 评论
977 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
683 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1595 浏览 2 评论
1863浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
644浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
515浏览 3评论
531浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
504浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 08:10 , Processed in 0.953861 second(s), Total 85, Slave 67 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号