1、SD 卡引脚及 spi 模式基本操作过程(摘自网络)对于 SD 卡的硬件结构,在官方的文档上有很详细的介绍,如 SD 卡内的存储器结构、存储单元组织方式等内容。要实现对它的读写,最核心的是它的时序,笔者在经过了实际的测试后,使用 51 单片机成功实现了对 SD 卡的扇区读写,并对其读写速度进行了评估。下面先来讲解 SD 卡的读写时序。SD 卡的引脚定义SD 卡引脚功能详述:SD 模式 SPI 模式引脚编号 名称 类型 描述 名称 类型 描述1 CD/DAT3 IO 或 PP 卡检测/数据线 3#CS I 片选2 CMD PP 命令/回应DI I 数据输入3 VSS1 S 电源地 VSS S 电
2、源地4 VDD S 电源 VDD S 电源5 CLK I 时钟 SCLK I 时钟6 VSS2 S 电源地 VSS2 S 电源地7 DAT0 IO 或 PP 数据线 0 DO O 或 PP 数据输出8 DAT1 IO 或 PP 数据线 1 RSV9 DAT2 IO 或 PP 数据线 2 RSV注:S :电源供给 I:输入 O:采用推拉驱动的输出 PP:采用推拉驱动的输入输出SD 卡 SPI 模式下与单片机的连接图:SD 卡支持两种总线方式:SD 方式与 SPI 方式。其中 SD 方式采用 6 线制,使用CLK、CMD 、 DAT0DAT3 进行数据通信。而 SPI 方式采用 4 线制,使用CS
3、、 CLK、DataIn 、DataOut 进行数据通信。SD 方式时的数据传输速度与 SPI 方式要快,采用单片机对 SD 卡进行读写时一般都采用 SPI 模式。采用不同的初始化方式可以使 SD卡工作于 SD 方式或 SPI 方式。这里只对其 SPI 方式进行介绍。SPI 方式驱动 SD 卡的方法SD 卡的 SPI 通信接口使其可以通过 SPI 通道进行数据读写。从应用的角度来看,采用 SPI 接口的好处在于,很多单片机内部自带 SPI 控制器,不光给开发上带来方便,同时也见降低了开发成本。然而,它也有不好的地方,如失去了 SD 卡的性能优势,要解决这一问题,就要用 SD 方式,因为它提供更
4、大的总线数据带宽。 SPI 接口的选用是在上电初始时向其写入第一个命令时进行的。以下介绍 SD 卡的驱动方法,只实现简单的扇区读写。1) 命令与数据传输1. 命令传输SD 卡自身有完备的命令系统,以实现各项操作。命令格式如下:命令的传输过程采用发送应答机制,过程如下:每一个命令都有自己命令应答格式。在 SPI 模式中定义了三种应答格式,如下表所示:字节 位 含义7 开始位,始终为 06 参数错误5 地址错误4 擦除序列错误3 CRC 错误2 非法命令1 擦除复位10 闲置状态字节 位 含义7 开始位,始终为 06 参数错误5 地址错误4 擦除序列错误3 CRC 错误2 非法命令1 擦除复位10
5、 闲置状态7 溢出,CSD 覆盖6 擦除参数5 写保护非法4 卡 ECC 失败3 卡控制器错误2 未知错误1 写保护擦除跳过,锁解锁失败20 锁卡字节 位 含义7 开始位,始终为 06 参数错误5 地址错误4 擦除序列错误3 CRC 错误12 非法命令1 擦除复位0 闲置状态25 全部 操作条件寄存器,高位在前写命令的例程:C 程序/-向 SD 卡中写入命令,并返回回应的第二个字节 /-unsigned char Write_Command_SD(unsigned char *CMD) unsigned char tmp;unsigned char retry=0;unsigned char
6、i;/禁止 SD 卡片选SPI_CS=1; /发送 8 个时钟信号Write_Byte_SD(0xFF); /使能 SD 卡片选SPI_CS=0; /向 SD 卡发送 6 字节命令for (i=0;isector_count = sectorBuffer.dat6 vinf-sector_count sector_count += sectorBuffer.dat7; vinf-sector_count sector_count += (sectorBuffer.dat8 / 获取 multipliervinf-sector_multiply = sectorBuffer.dat9 vinf-
7、sector_multiply sector_multiply += (sectorBuffer.dat10 /获取 SD 卡的容量vinf-size_MB = vinf-sector_count (9-vinf-sector_multiply); / get the name of the cardRead_CID_SD(sectorBuffer.dat); vinf-name0 = sectorBuffer.dat3; vinf-name1 = sectorBuffer.dat4; vinf-name2 = sectorBuffer.dat5; vinf-name3 = sectorBuf
8、fer.dat6; vinf-name4 = sectorBuffer.dat7; vinf-name5 = 0x00; /end flag 以上程序将信息装载到一个结构体中,这个结构体的定义如下: typedef struct SD_VOLUME_INFO /SD/SD Card infounsigned int size_MB;unsigned char sector_multiply;unsigned int sector_count;unsigned char name6; VOLUME_INFO_TYPE; 扇区读扇区读是对 SD 卡驱动的目的之一。SD 卡的每一个扇区中有 512
9、个字节,一次扇区读操作将把某一个扇区内的 512 个字节全部读出。过程很简单,先写入命令,在得到相应的回应后,开始数据读取。扇区读的时序:扇区读的程序例程:C 程序unsigned char SD_Read_Sector(unsigned long sector,unsigned char *buffer) unsigned char retry;/命令 16unsigned char CMD = 0x51,0x00,0x00,0x00,0x00,0xFF;unsigned char temp;/地址变换 由逻辑块地址转为字节地址sector = sector 24 ); CMD2 = (sector CMD3 = (sector /将命令 16 写入 SD 卡retry=0; do