对于SD卡的初始化的时候,尽量要保持低速,尽量小于375K。而初始化的一般的步骤为先发送74个时钟,然后发送CMD0命令,等SD卡返回0x01信息之后,发送APP类命令ACMD41可初始化SD卡,所谓的APP类命令ACMD41,其实就是CMD55+ACMD41,。如果是MMC卡,则可以发送CMD1命令,等待返回0x01,即可。
之前对于8366的SPI接口初始化过,这里不再赘述。
这里要说的发送命令函数。
SD卡的命令为48位的,其格式如下:
![初学56F8366之SD卡读写(基于SPI模式)(2) - wehat1148158886 - 子诺](http://img115.ph.126.net/djoOPzuPtsvGzStlWD1siQ==/2010294283669533257.jpg)
开始的两位和最后一位变。开始的前8位去掉前2两位,剩下6位,表示了SD卡的64个CMD命令。之后32位表示命令的参数,一些命令或者地址参数,总之后面这32位和前面的CMD命令配合的。后面7位为RCR,最后一位是始终为1。了解了命令结构之后,就可以参照有关时序,得下面函数。
byte SD_SendCommand(byte u8SDCommand_0,byte u8SDCommand_1,byte u8SDCommand_2,
byte u8SDCommand_3,byte u8SDCommand_4,byte u8SDCommand_CRC,
byte u8SDResponse) //发送48位命令
{
byte u8Count;
byte u8SDTemp;
//送起始位命令
SPI_Send_Date(u8SDCommand_0+0x40);
//送命令字
SPI_Send_Date(u8SDCommand_1);
SPI_Send_Date(u8SDCommand_2);
SPI_Send_Date(u8SDCommand_3);
SPI_Send_Date(u8SDCommand_4);
//送CRC
SPI_Send_Date(u8SDCommand_CRC);
u8Count = 0x0F00; //等反馈命令
do
{
u8SDTemp = SPI_Get_Date();
u8Count--;
if(u8SDTemp == u8SDResponse) break;
}
while(u8Count<0);
if(u8Count) return(0); //成功返回0
else return(1); //超时返回1
}
byte u8SDCommand_3,byte u8SDCommand_4,byte u8SDCommand_CRC,
byte u8SDResponse) //发送48位命令
{
byte u8Count;
byte u8SDTemp;
//送起始位命令
SPI_Send_Date(u8SDCommand_0+0x40);
//送命令字
SPI_Send_Date(u8SDCommand_1);
SPI_Send_Date(u8SDCommand_2);
SPI_Send_Date(u8SDCommand_3);
SPI_Send_Date(u8SDCommand_4);
//送CRC
SPI_Send_Date(u8SDCommand_CRC);
u8Count = 0x0F00; //等反馈命令
do
{
u8SDTemp = SPI_Get_Date();
u8Count--;
if(u8SDTemp == u8SDResponse) break;
}
while(u8Count<0);
if(u8Count) return(0); //成功返回0
else return(1); //超时返回1
}
现在SPI初始化成功,写命令函数齐全了,然后可以开始初始化了,要点之前也说了,其具体的函数为。
void SDCard_Init(void)
{
unsigned char Success_Flag = 0;
unsigned int Count = 0; //最高要大于600,所以选择16位
unsigned char r1 = 0xFF;