stm32 sdio acmd41 无响应。一直是返回0x3f。解决方法是清除crc错误中断

http://blog.163.com/dreamatic_altezza/blog/static/119304542013112932216498/


大家在使用stm32 sdio口初始化sd卡的时候会遇到一个国内文章中都没有提到的问题

首先我来说说初始化sdhc卡(sdsc卡acmd41参数为0x00ff8000)的流程:
cmd0 无参数 返回0x00 0x00
cmd8 参数0x1aa 返回0x8 0x1aa
cmd55 无参数 返回0x37 0x120
acmd41 参数0x40ff8000 返回0x3f 0x40ff8000
cmd55 无参数 返回0x37 0x120
acmd41 参数0x40ff8000 返回0x3f 0xc0ff8000 (sd卡OCR bit[31] busy位置1 卡进入ready status)

但在实际使用stm32的过程中,我们会遇到发送完第一个acmd41后,返回就一直是0x3f 0x40ff8000。即使是再发送cmd55也是0x3f 0x40ff8000。这不是sd卡不响应,而是stm32的sdio监测到crc错误,不再发送命令了。

这是由于sd规范中,Acmd41返回的crc永远是11111,也就是应该忽略crc,但是Stm32的sdio却检查了crc,就出错了。

为了使crc错误后的sdio恢复正常我们可以使用sdio库函数来清除crc标志位,代码如下:
SDIO_ClearFlag(SDIO_FLAG_CCRCFAIL);
SDIO_ClearITPendingBit(SDIO_IT_CCRCFAIL);

以下是我写的cmd55+acmd41循环:
测试用的,请勿就纠结代码的效率。

希望能够被sd初始化困扰的朋友带来曙光!

for(k=0;k<800;k++)
{

    SDIO_CmdInitStructure.SDIO_Argument = 0x00;
    SDIO_CmdInitStructure.SDIO_CmdIndex = 0x37;
    SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
    SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
    SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
    SDIO_SendCommand(&SDIO_CmdInitStructure);

    for(i=0;i<2000;i++)//发送完命令需要延时才能获取sd卡的反馈
    {

    }   
    
    d5=SDIO_GetCommandResponse();//等待返回 返回是63
    d1=SDIO_GetResponse(SDIO_RESP1);//16gb卡返回0x40200000;16gb卡返回0x00ff8000
    d2=SDIO_GetResponse(SDIO_RESP2);
    d3=SDIO_GetResponse(SDIO_RESP3);
    d4=SDIO_GetResponse(SDIO_RESP4);  
d3=SDIO_GetITStatus(SDIO_IT_CCRCFAIL );
d4=SDIO_GetFlagStatus(SDIO_FLAG_CCRCFAIL);
SDIO_ClearFlag(SDIO_FLAG_CCRCFAIL);
SDIO_ClearITPendingBit(SDIO_IT_CCRCFAIL);
d3=SDIO_GetITStatus(SDIO_IT_CCRCFAIL );
d4=SDIO_GetFlagStatus(SDIO_FLAG_CCRCFAIL);
  //  
    
    SDIO_CmdInitStructure.SDIO_Argument = 0x40ff8000;//16gb卡用0x40000000;2gb用0x00000000
    SDIO_CmdInitStructure.SDIO_CmdIndex = 0x29;
    SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
    SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
    SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
    SDIO_SendCommand(&SDIO_CmdInitStructure);
    for(i=0;i<2000;i++)//发送完命令需要延时才能获取sd卡的反馈
    {

    }
    d5=SDIO_GetCommandResponse();//等待返回 返回是63

    d1=SDIO_GetResponse(SDIO_RESP1);//16gb卡返回0x40ff8000;16gb卡返回0x00ff8000
    d2=SDIO_GetResponse(SDIO_RESP2);
    d3=SDIO_GetResponse(SDIO_RESP3);
    d4=SDIO_GetResponse(SDIO_RESP4);
    
    for(i=0;i<5000;i++)//发送完命令需要延时才能获取sd卡的反馈
    {

    }
d3=SDIO_GetITStatus(SDIO_IT_CCRCFAIL );
d4=SDIO_GetFlagStatus(SDIO_FLAG_CCRCFAIL);
SDIO_ClearFlag(SDIO_FLAG_CCRCFAIL);
SDIO_ClearITPendingBit(SDIO_IT_CCRCFAIL);
d3=SDIO_GetITStatus(SDIO_IT_CCRCFAIL );
d4=SDIO_GetFlagStatus(SDIO_FLAG_CCRCFAIL);
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值