- u8 SD_Init(void)
- {
- u16 i;
- u8 r1;
- u16 retry;
- u8 buff[6];
- SPI_ControlLine();
- //SD卡初始化时时钟不能超过400KHz
- SPI_SetSpeed(SPI_SPEED_LOW);
- //CS为低电平,片选置低,选中SD卡
- SD_CS_ENABLE();
- //纯延时,等待SD卡上电稳定
- for(i=0;i<0xf00;i++);
- //先产生至少74个脉冲,让SD卡初始化完成
- for(i=0;i<10;i++)
- {
- //参数可随便写,经过10次循环,产生80个脉冲
- SPI_ReadWriteByte(0xff);
- }
- //-----------------SD卡复位到idle状态----------------
- //循环发送CMD0,直到SD卡返回0x01,进入idle状态
- //超时则直接退出
- retry=0;
- do
- {
- //发送CMD0,CRC为0x95
- r1=SD_SendCommand(CMD0,0,0x95);
- retry++;
- }
- while((r1!=0x01)&&(retry<200));
- //跳出循环后,检查跳出原因,
- if(retry==200) //说明已超时
- {
- return 1;
- }
- //如果未超时,说明SD卡复位到idle结束
- //发送CMD8命令,获取SD卡的版本信息
- r1=SD_SendCommand(CMD8,0x1aa,0x87);
- //下面是SD2.0卡的初始化
- if(r1==0x01)
- {
- // V2.0的卡,CMD8命令后会传回4字节的数据,要跳过再结束本命令
- buff[0] = SPI_ReadWriteByte(0xFF);
- buff[1] = SPI_ReadWriteByte(0xFF);
- buff[2] = SPI_ReadWriteByte(0xFF);
- buff[3] = SPI_ReadWriteByte(0xFF);
- SD_CS_DISABLE();
- //多发8个时钟
- SPI_ReadWriteByte(0xFF);
- retry = 0;
- //发卡初始化指令CMD55+ACMD41
- do
- {
- r1 = SD_SendCommand(CMD55, 0, 0);
- //应返回0x01
- if(r1!=0x01)
- return r1;
- r1 = SD_SendCommand(ACMD41, 0x40000000, 1);
- retry++;
- if(retry>200)
- return r1;
- }
- while(r1!=0);
- //初始化指令发送完成,接下来获取OCR信息
- //----------鉴别SD2.0卡版本开始-----------
- //读OCR指令
- r1 = SD_SendCommand_NoDeassert(CMD58, 0, 0);
- //如果命令没有返回正确应答,直接退出,返回应答
- if(r1!=0x00)
- return r1;
- //应答正确后,会回传4字节OCR信息
- buff[0] = SPI_ReadWriteByte(0xFF);
- buff[1] = SPI_ReadWriteByte(0xFF);
- buff[2] = SPI_ReadWriteByte(0xFF);
- buff[3] = SPI_ReadWriteByte(0xFF);
- //OCR接收完成,片选置高
- SD_CS_DISABLE();
- SPI_ReadWriteByte(0xFF);
- //检查接收到的OCR中的bit30位(CSS),确定其为SD2.0还是SDHC
- //CCS=1:SDHC CCS=0:SD2.0
- if(buff[0]&0x40)
- {
- SD_Type = SD_TYPE_V2HC;
- }
- else
- {
- SD_Type = SD_TYPE_V2;
- }
- //-----------鉴别SD2.0卡版本结束-----------
- SPI_SetSpeed(1); //设置SPI为高速模式
- }
- }
|