SD卡初始化过程中ACMD41命令一直返回0x01的解决方法

最近接到客户的项目中用到了SD卡来存储传感器数据,于是从网上寻得了原子哥的驱动程序,使用的单片机为STM32F103RBT6的mini板,使用的SD卡为金士顿8G,以及某宝上淘来的SD卡读写模块,使用到的参考资料为SD卡2.0协议PDF版,一切准备就绪。

配置硬件SPI格式为:主模式,8bit , CPOL为高电平,NSS信号为软件管理以使用其它IO作为片选脚,CPHA为1---数据捕获于第二个时钟沿,高位先出,首先SPI设置为低速模式256分频,然后发送0xff启动传输。

按照协议给出的初始化过程,如下图,按部就班的进行操作,首先应发送至少74个脉冲使SD卡做好数据接收准备,

 	for(i=0;i<10;i++)
		SD_SPI_ReadWriteByte(0XFF);//发送最少74个脉冲

然后一直发送CMD0直到SD卡返回0x01,注意CRC一定为0x95,使SD卡进入空闲模式;

	retry=20;
	do
	{
		r1=SD_SendCmd(CMD0,0,0x95);		//判断是否进入IDLE状态
	}while((r1!=0X01) && retry--);

接下来发送CMD8检查SD卡支持电压是否支持2.7~3.6V,命令格式如下,VHS设置为0001b,手册中建议将checkpattern设置为0xaa,对应CRC为0x87:

CMD8发送完成后准备接收回应R7,格式如下,我们需要判断R1部分IDLE位是否依然有效,checkpattern部分是否为0xaa,若是则说明卡支持2.7~3.6V:

if(SD_SendCmd(CMD8,0x000001AA,0x87)==1)//发送接口状态命令判断是否支持SD V2.0.checkpatern=0xaa
		{
			for(i=0;i<4;i++)
				buf[i]=SD_SPI_ReadWriteByte(0XFF);	//获得剩余回应字节
			if(buf[2]==0X01&&buf[3]==0XAA)//判断checkpattern 回应与VDH, 卡是否支持2.7~3.6V
			{
                            接下来发送ACMD41读取OCR;
                        }


                 }

接下来发送ACMD41命令告诉SD卡主机支持大容量SD卡操作,ACMD41格式为

HCS置位1,代表主机支持大容量SD卡,注意原子哥给出的程序中将命令参数写为了0x40,注意这样的话在传参时实际写入的参数为0x00000040,这和ACMD参数格式是不符的,会使SD卡返回的r1值为0x01!!!,需要把0x40改为0x40000000!!!

修改后:

,这样便能正确返回r1,此时SD卡应退出了空闲状态,r1为0x00,否则继续发送ACMD41指令(CMD55告诉SD卡吓一跳指令为特殊应用指令)。

后续操作不再赘述。

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值