SD 卡引脚 电路图及工作原理介绍SD 卡在现在的日常生活与工作中使用非常广泛,时下已经成为最为通用的数据存储卡在诸如 MP3、数码相机等设备上也都采用 SD 卡作为其存储设备SD 卡之所以得到如此广泛的使用,是因为它价格低廉、存储容量大、使用方便、通用性与安全性强等优点既然它有着这么多优点,那么如果将它加入到单片机应用开发系统中来,将使系统变得更加出色这就要求对 SD 卡的硬件与读写时序进行研究对于 SD 卡的硬件结构,在官方的文档上有很详细的介绍,如 SD 卡内的存储器结构、存储单元组织方式等内容要实现对它的读写,最核心的是它的时序,笔者在经过了实际的测试后,使用51单片机成功实现了对 SD 卡的扇区读写,并对其读写速度进行了评估下面先来讲解 SD 卡的读写时序1) SD 卡的引脚定义 :SD 卡引脚功能详述:SD 模式 SPI 模式引脚编号 名称 类型 描述 名称 类型 描述1 CD/DAT3 IO 或 PP 卡检测/数据线3#CS I 片选2 CMD PP 命令/回应DI I 数据输入3 VSS1 S 电源地 VSS S 电源地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 RSV 9 DAT2 IO 或 PP 数据线2 RSV 注:S:电源供给 I:输入 O:采用推拉驱动的输出PP:采用推拉驱动的输入输出SD 卡 SPI 模式下与单片机的连接图:SD 卡支持两种总线方式:SD 方式与 SPI 方式。
其中 SD 方式采用6线制,使用CLK、CMD、DAT0~DAT3进行数据通信而 SPI 方式采用4线制,使用CS、CLK、DataIn、DataOut 进行数据通信SD 方式时的数据传输速度与 SPI 方式要快,采用单片机对 SD 卡进行读写时一般都采用 SPI 模式采用不同的初始化方式可以使 SD卡工作于 SD 方式或 SPI 方式这里只对其 SPI 方式进行介绍2) SPI 方式驱动 SD 卡的方法SD 卡的 SPI 通信接口使其可以通过 SPI 通道进行数据读写从应用的角度来看,采用 SPI 接口的好处在于,很多单片机内部自带 SPI 控制器,不光给开发上带来方便,同时也见降低了开发成本然而,它也有不好的地方,如失去了 SD 卡的性能优势,要解决这一问题,就要用 SD 方式,因为它提供更大的总线数据带宽SPI 接口的选用是在上电初始时向其写入第一个命令时进行的以下介绍 SD 卡的驱动方法,只实现简单的扇区读写1) 命令与数据传输1. 命令传输SD 卡自身有完备的命令系统,以实现各项操作命令格式如下:命令的传输过程采用发送应答机制,过程如下:每一个命令都有自己命令应答格式在 SPI 模式中定义了三种应答格式,如下表所示:字节 位 含义7 开始位,始终为06 参数错误5 地址错误4 擦除序列错误13 CRC 错误2 非法命令1 擦除复位0 闲置状态字节 位 含义7 开始位,始终为06 参数错误5 地址错误4 擦除序列错误3 CRC 错误2 非法命令1 擦除复位10 闲置状态7 溢出,CSD 覆盖6 擦除参数5 写保护非法4 卡 ECC 失败3 卡控制器错误2 未知错误1 写保护擦除跳过,锁/解锁失败20 锁卡字节 位 含义7 开始位,始终为06 参数错误5 地址错误4 擦除序列错误3 CRC 错误2 非法命令1 擦除复位10 闲置状态2~5 全部 操作条件寄存器,高位在前写命令的例程://-----------------------------------------------------------------------------------------------向 SD 卡中写入命令,并返回回应的第二个字节//-----------------------------------------------------------------------------------------------unsigned char Write_Command_SD(unsigned char *CMD){unsigned char tmp;unsigned char retry=0;unsigned char i;//禁止 SD 卡片选SPI_CS=1;//发送8个时钟信号Write_Byte_SD(0xFF);//使能 SD 卡片选SPI_CS=0;//向 SD 卡发送6 字节命令for (i=0;isector_count = sectorBuffer.dat[6] & 0x03;vinf->sector_count sector_count += sectorBuffer.dat[7];vinf->sector_count sector_count += (sectorBuffer.dat[8] & 0xc0) >> 6;// 获取 multipliervinf->sector_multiply = sectorBuffer.dat[9] & 0x03;vinf->sector_multiply sector_multiply += (sectorBuffer.dat[10] & 0x80) >> 7;//获取 SD 卡的容量vinf->size_MB = vinf->sector_count >> (9-vinf->sector_multiply);// get the name of the cardRead_CID_SD(sectorBuffer.dat);vinf->name[0] = sectorBuffer.dat[3];vinf->name[1] = sectorBuffer.dat[4];vinf->name[2] = sectorBuffer.dat[5];vinf->name[3] = sectorBuffer.dat[6];vinf->name[4] = sectorBuffer.dat[7];vinf->name[5] = 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 name[6];} VOLUME_INFO_TYPE;。