![shequ.stmicroelectronics.cn](./template/st_v1/static/img/logo2.png)
主芯片是 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禁止了,但没找到办法,资料没写,寄存器里也没有。 |
正点原子STM32H743开发板qspi flash问题
请问哪里有wio lite ai 开发板的样例程序?谢谢!
Wio Lite AI—基于STM32H7 人脸识别
STM32H745XIH3+DP83848YB,PHY配置成功,Link LED常亮,Activity LED和电脑端同频在闪烁,但ping不通,建议的排查方法?
STM32H743IIT6的价格
STM32H7和F4做永磁同步电机FOC控制如何选型,哪个开发更好?
H747 DSI模块采用一个数据通道无法显示图片
Stem32CubeIDE能像Keil一样指定不同文件下的代码编译到不同的FLASH地址吗?比如部分代码存放到内部FLASH,另一部分存放到外部QSPI的FLASH中
HAL库的一点小问题
Keil编译为何慢?
STM32Cube_FW_H7_V1.7.0\Projects\NUCLEO-H743ZI\Examples\SPI\SPI_FullDuplex_ComDMA\EWARM