第3章 单片机读写SD卡的软件设计
3.1.3 SD卡的初始化
SD卡的初始化是非常重要的,只有进行了正确的初始化,才能进行扇区读写等操作。根据SD卡的手册说明,在初始化过程中,SPI的时钟不能太快,否则会造初始化失败。在初始化成功后,应尽量提高SPI的速率。在刚开始要先发送至少74个时钟信号,这是必须的,因为在上电初期,电压的上升过程据SD卡组织的计算约合64个CLK周期才能到达SD卡的正常工作电压,其后的10个CLK是为了与SD卡同步,如果疏忽了这一点,可能使初始化不成功。随后就是写入命令CMD0,为了实现兼容性,发送CMD0后,再发送CMD55和ACMD41(使用ACMD类的指令前应先发CMD55,CMD55起到一个切换到ACMD类命令的作用)确认是否有回应,如果有回应则为SD卡,如果等回应超时,则可能是MMC卡,再发CMD1确认。完成上面操作后SD卡进入SPI模式。主机还可以继续通过CMD10读取SD卡的CID寄存器,通过CMD16设置数据Block长度,通过CMD9读取卡的CSD寄存器。从CSD寄存器中,主机可获知卡容量,支持的命令集等重要参数。SD卡初始化的C语言程序见附录。其流程图如图3-4所示。
开始发送74个时钟信号发送复位命令CMD0进入SP1模式发送初始化命令接收响应N响应命令是否等于 0Y结束 图3-4 SD卡初始化
19
电子科技大学成都学院本科毕业设计论文
3.1.4 数据块的读写
完成SD卡的初始化之后即可进行它的读写操作。SD卡的读写操作都是通过发送SD卡命令完成的。SPI总线模式支持单块(CMD24)和多块(CMD25)写操作,多块操作是指从指定位置开始写下去,直到SD卡收到一个停止命令CMD12才停止。单块写操作的数据块长度只能是512 字节。单块写入时,命令为CMD24,当应答为0时说明可以写入数据,大小为512 字节。SD卡对每个发送给自己的数据块都通过一个应答命令确认,它为1个字节长,当低5位为00101 时,表明数据块被正确写入SD 卡。写SD卡程序流程图如图3-5。具体C程序实现如下:
unsigned char SD_WriteSector(unsigned char *buffer, unsigned long address) {
unsigned int count = 0; unsigned char response = 0xff;
unsigned int timeout = 0; //写命令超时
address <<= 9; //address=address*512将块地址转为字节地址
SD_Enable(); do {
response = SD_WriteCommand(0x18, address, 0xff);//发送读数据命令 timeout++;
}while((0x0 != response) && (timeout < TRY_TIME)); if(0x0 == response) {
SD_WriteByte(0xff);
SD_WriteByte(0xff);//command was a success - now send data SD_WriteByte(0xfe); //写入开始字节 0xfe
20
第3章 单片机读写SD卡的软件设计
for(count = 0; count < 512; count++)//将缓冲区中的512个字节写入SD卡 {
SD_WriteByte(*buffer++);
}
SD_WriteByte(0xff);
SD_WriteByte(0xff); //两个字节的CRC校验码,不用关心 response = SD_ReadByte();//读数据响应 response = response & 0x1f; if(0x05 != response) { }
/*等到SD卡不忙数据被接受以后,SD卡要将这些数据写入到 自身的FLASH中,需要一个时间忙时,读回来的值为0x00, 不忙时,为 0xff*/
SD_Disable();//如果返回值是XXX00101说明数据已经被SD卡接受 Uart_Send_String(\写扇区失败\\r\\n\return SD_WRITE_ERROR;
while(0 == SD_ReadByte()); //等到SD卡不忙 SD_Disable();
} }
SD_WriteByte(0xff);//按照SD卡的操作时序在这里补8个时钟 return SD_SUCCESS; //写扇区操作成功
return SD_WRITE_ERROR;//写扇区操作失败
21
相关推荐: