STM32 关于读sd卡的一些注意事项

2 篇文章 0 订阅
1 篇文章 0 订阅
博主分享了在STM32中读取SD卡遇到的困难,包括调试时出现的FIFO上溢错误,以及通过调整数据路径接收机配置解决问题的经验。最终成功实现了SD卡数据的稳定读取,并展示了读取到的扇区数据。还提到了另一种使用SDIO数据路径状态机的读等待功能来读取数据的方法。
摘要由CSDN通过智能技术生成
sd_error read_block(uint32_t addr,uint32_t len,uint8_t *data)
{
    uint8_t temp;
    SDIO_DataInitTypeDef SDIO_DATA;
    u32 count=0;
    uint32_t timeout;
    uint32_t *tempbuff=(u32*)data;
    SDIO_DATA.SDIO_DataBlockSize=SDIO_DataBlockSize_1b;
    SDIO_DATA.SDIO_DataLength=0;
    SDIO_DATA.SDIO_DataTimeOut=0xFFFFFFFF;
    SDIO_DATA.SDIO_DPSM=SDIO_DPSM_Enable;
    SDIO_DATA.SDIO_TransferDir=SDIO_TransferDir_ToCard;
    SDIO_DATA.SDIO_TransferMode=SDIO_TransferMode_Block;
    if(flag_bit_transfer=!1)
    {
        sd_send_commder(7,(uint32_t)(rca<<16),SDIO_Response_Short);
        temp=cmdresponse7();
        if(temp!=sd_ok) return temp;
        flag_bit_transfer=1;
    }
    SDIO_DataConfig(&SDIO_DATA);
    sd_send_commder(16,0x00000200,SDIO_Response_Short);
    temp=cmdresponse7();
    if(temp!=sd_ok) return temp;
    SDIO_DATA.SDIO_DataBlockSize=SDIO_DataBlockSize_512b;
    SDIO_DATA.SDIO_DataLength=len;
    SDIO_DATA.SDIO_DataTimeOut=0xFFFFFFFF;
    SDIO_DATA.SDIO_DPSM=SDIO_DPSM_Enable;
    SDIO_DATA.SDIO_TransferDir=SDIO_TransferDir_ToSDIO;
    SDIO_DATA.SDIO_TransferMode=SDIO_TransferMode_Block;
    SDIO_DataConfig(&SDIO_DATA);
    sd_send_commder(17,(uint32_t)addr,SDIO_Response_Short);
    temp=cmdresponse7();
    if(temp!=sd_ok) return temp;
    SDIO->ICR|=(1<<5);
    while(!(SDIO->STA&((1<<5)|(1<<1)|(1<<3)|(1<<10)|(1<<9))))//无上溢/CRC/超时/完成(标志)/起始位错误
	{
			if(SDIO_GetFlagStatus(SDIO_FLAG_RXFIFOHF) != RESET)						//接收区半满,表示至少存了8个字
			{
				for(count=0;count<8;count++)			//循环读取数据
				{
					*(tempbuff+count)=SDIO->FIFO;
				}	 
                tempbuff+=8;
                timeout=0X7FFFFF; 	//读数据溢出时间
			}else 	//处理超时
			{
				if(timeout==0)return sd_timeout;
				timeout--;
			}
	} 
    if(SDIO_GetFlagStatus(SDIO_FLAG_DTIMEOUT) != RESET)		//数据超时错误
		{										   
	 		SDIO_ClearFlag(SDIO_FLAG_DTIMEOUT); 	//清错误标志
			return sd_timeout;
	 	}else if(SDIO_GetFlagStatus(SDIO_FLAG_DCRCFAIL) != RESET)	//数据块CRC错误
		{
	 		SDIO_ClearFlag(SDIO_FLAG_DCRCFAIL);  		//清错误标志
			return sd_dcrcerror;		   
		}else if(SDIO_GetFlagStatus(SDIO_FLAG_RXOVERR) != RESET) 	//接收fifo上溢错误
		{
	 		SDIO_ClearFlag(SDIO_FLAG_RXOVERR);		//清错误标志
			return sd_rxoverr;		 
		}else if(SDIO_GetFlagStatus(SDIO_FLAG_STBITERR) != RESET) 	//接收起始位错误
		{
	 		SDIO_ClearFlag(SDIO_FLAG_STBITERR);//清错误标志
			return sd_stbiterr;		 
		}   
		while(SDIO_GetFlagStatus(SDIO_FLAG_RXDAVL) != RESET)	//FIFO里面,还存在可用数据
		{
			*tempbuff=SDIO->FIFO;	//循环读取数据
			tempbuff++;
		}
		SDIO_ClearFlag(0x000005FF);//清除所有标记
        return sd_ok;
    
}

其中接收部分是模仿正点原子的。

坑:

1、千万不要在读取sd卡的时候调试,坑死了,一调试就是fifo上溢错误,***我调了4个小时,最后想着要不先运行一下(破罐子破摔),结果读出数据了。我那个绝望啊

2、关于数据路径接收机的配置,还有一种思路是直接调用内部的函数

SDIO_StartSDIOReadWait();

SDIO_SetSDIOReadWaitMode()

 我也已经验证,可以顺利读到数据(其实是使用数据路径状态机的读等待功能)只需要在发送完读命令后打开状态机即可。

终于可以睡个好觉了!

 

 sd卡第 0扇区的数据,激动!!

sd_init return value=64
sd card size is =15601664
sd card set 4 bit bus width =64
sd card read block result =64
sd card The first 440 data =47
sd card The first 441 data =45
sd card The first 442 data =12
sd card The first 443 data =47
sd card The first 448 data =1
sd card The first 449 data =1
sd card The first 450 data =c
sd card The first 451 data =3f
sd card The first 452 data =e0
sd card The first 453 data =80
sd card The first 460 data =dc
sd card The first 461 data =1
sd card The first 510 data =55
sd card The first 511 data =aa


 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个人创造世界

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值