[STM32F4] stm32f407中SD卡的读写不正常,对FIFo如何操作的

[复制链接]
 楼主| 唐纳德d 发表于 2025-3-11 08:30 | 显示全部楼层 |阅读模式
在stm32f407中SD卡的读写不正常,仿真分析了程序还是不太明白如何读取SDIO的FIFO。
通过仿真发现读取FIFO是通过stm32f4xx_ll_sdmmc.c中的SDIO_ReadFIFO()函数完成的。
/**  * @brief  Read data (word) from Rx FIFO in blocking mode (polling)   * @param  SDIOx Pointer to SDMMC register base  * @retval HAL status  */uint32_t SDIO_ReadFIFO(SDIO_TypeDef *SDIOx){  /* Read data from Rx FIFO */   return (SDIOx->FIFO);}
我不明白这怎样的逻辑?SD卡的FIFO怎么知道程序已经读过了,并知道要移动FIFO?在HAL_SD_ReadBlocks()下没有设置这样的标志。
        


if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXFIFOHF)){  /* 从SDIO Rx FIFO读取数据 */  for(count = 0U; count < 8U; count++)  {    *(tempbuff + count) = SDIO_ReadFIFO(hsd->Instance);  }  tempbuff += 8U;}
   
有没有懂行的高手能解释一下?查阅了数据手册、参考手册和代码文档,还是搞不太明白。

公羊子丹 发表于 2025-3-12 08:14 | 显示全部楼层
看起来你遇到的问题可能和FIFO的硬件机制有关,FIFO会自动按32位(一个字)来读取,每次读完数据指针会自动推进,确保下次读取的是新数据。
周半梅 发表于 2025-3-12 08:15 | 显示全部楼层
FIFO本身是一个先进先出的缓冲区,读取SDIO_ReadFIFO()时,硬件自动将指针推进,HAL库内部已经封装好了这些操作,所以不需要手动清标志位。
帛灿灿 发表于 2025-3-12 08:17 | 显示全部楼层
你的代码看着没啥问题,检查一下DMA的配置有没有疏漏?有时候FIFO问题可能是DMA数据长度不匹配导致的。
童雨竹 发表于 2025-3-12 08:18 | 显示全部楼层
你看看SDIO_FLAG_RXFIFOHF这个标志位的逻辑,应该是FIFO数据达到一半时触发,确保你在正确的时机读取FIFO。
万图 发表于 2025-3-12 08:19 | 显示全部楼层
HAL库里一般在数据传输完成后会清除SDIO_FLAG_RXFIFOHF等标志位,可能问题出在数据没完全读完,检查一下传输的总字节数。
Wordsworth 发表于 2025-3-12 08:20 | 显示全部楼层
FIFO的指针自动移动是硬件层面的,你调用SDIO_ReadFIFO()时,硬件会在读取数据的同时推进指针,不用担心数据重复读取。
Bblythe 发表于 2025-3-12 08:22 | 显示全部楼层
SD卡的时序对FIFO的操作也有影响,尤其是高速模式下,数据读取不及时可能会丢失,建议检查时钟配置是否合理。
Pulitzer 发表于 2025-3-12 08:23 | 显示全部楼层
你试着在读取数据后,打印一下SDIOx->STA寄存器的状态,看看是否有溢出(RXOVERR)或者FIFO错误(RXFIFOE)。
Uriah 发表于 2025-3-12 08:24 | 显示全部楼层
检查一下缓存指针tempbuff的对齐情况,SDIO的FIFO操作要求32位对齐,不对齐可能会导致奇怪的问题。
Clyde011 发表于 2025-3-12 08:25 | 显示全部楼层
我之前遇到类似问题是因为SD卡初始化时电压配置不正确,导致数据不稳定,你可以再检查一下电源、时钟和IO配置。
淡漠安然 发表于 2025-4-14 01:05 | 显示全部楼层
STM32F407中,SD卡的读写操作涉及SDIO接口的FIFOFirst-In-First-Out)缓冲机制。你提到的SDIO_ReadFIFO()函数和相关标志位的使用,确实需要理解SDIO的硬件特性和HAL库的实现逻辑

暖了夏天蓝了海 发表于 2025-4-14 02:24 | 显示全部楼层
SDIO接口使用FIFO作为数据缓冲,以实现主机和SD卡之间的高速数据传输。主机可以通过SDIO接口的寄存器读取或写入FIFO中的数据,STM32F407SDIO FIFO深度为16个字(每个字为32位)

三生万物 发表于 2025-4-14 03:23 | 显示全部楼层
一般来说,SDIO_ReadFIFO()函数通过直接读取SDIOFIFO寄存器来获取数据

江河千里 发表于 2025-4-14 04:43 | 显示全部楼层
硬件自动更新FIFO指针,当你读取FIFO中的数据时,硬件会自动更新内部指针,指向下一个数据。因此,你不需要手动设置标志来移动FIFO指针

光辉梦境 发表于 2025-4-14 05:25 | 显示全部楼层
SDIO_FLAG_RXFIFOHF,这个标志位表示接收FIFO半满(Half Full)。当FIFO中至少有8个数据(即半满)时,这个标志位会被置位

别乱了阵脚 发表于 2025-4-14 06:28 | 显示全部楼层
HAL_SD_ReadBlocks()函数中,通过轮询SDIO_FLAG_RXFIFOHF标志位来判断是否有足够的数据可供读取

远山寻你 发表于 2025-4-14 07:47 | 显示全部楼层
在读取数据之前,首先检查SDIO_FLAG_RXFIFOHF标志位是否被置位。如果置位,说明FIFO中至少有8个数据可供读取

冰春彩落下 发表于 2025-4-14 08:35 | 显示全部楼层
使用SDIO_ReadFIFO()函数从FIFO中读取数据。每次读取一个32位的数据(即一个字)

一秒落纱 发表于 2025-4-14 09:36 | 显示全部楼层
HAL_SD_ReadBlocks()中,通常会以块(block)为单位读取数据。例如,一次读取8个字(32字节)的数据,循环执行直到读取完整个块的数据

您需要登录后才可以回帖 登录 | 注册

本版积分规则

41

主题

41

帖子

0

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