SD卡资料编写.docx
《SD卡资料编写.docx》由会员分享,可在线阅读,更多相关《SD卡资料编写.docx(21页珍藏版)》请在冰豆网上搜索。
![SD卡资料编写.docx](https://file1.bdocx.com/fileroot1/2022-12/13/4c66b549-7615-4732-b096-00300bb00055/4c66b549-7615-4732-b096-00300bb000551.gif)
SD卡资料编写
SD卡资料整理
1、概述
SD卡高度集成闪存,具备串行和随机存取能力。
可以通过专用优化速度的串行接口访问,数据传输可靠。
接口允许几个卡垛叠,通过他们的外部连接。
接口完全符合最新的消费者标准,叫做SD卡系统标准,由SD卡系统规范定义。
SD卡系统是一个新的大容量存储系统,基于半导体技术的变革。
它的出现,提供了一个便宜的、结实的卡片式的存储媒介,为了消费多媒体应用。
SD卡可以设计出便宜的播放器和驱动器而没有可移动的部分。
一个低耗电和广供电电压的可以满足移动电话、电池应用比如音乐播放器、个人管理器、掌上电脑、电子书、电子百科全书、电子词典等等。
使用非常有效的数据压缩比如MPEG,SD卡可以提供足够的容量来应付多媒体数据。
安全数字存储卡(SecureDigitalMemoryCard,SDC)作为事实上的标准存储卡广泛应用于移动设备上。
SDC曾作为高层兼容多媒体卡(MultiMediaCard,MMC)进行开发。
SDC设备一般也兼容MMC。
还存在一些功能相同但尺寸更小的版本,如RS-MMC、miniSD和microSD。
MMC/SDC内置一个微控制器,在卡内部执行flash存储操作(擦写、读取、写入、错误控制和功耗平衡(Wearleveling))。
数据以512字节为单位在存储卡与主机控制器之间传输,从高层看来,卡可以被看作是通用硬盘设备。
当前定义的用于存储卡的文件系统为FAT12/16并使用FDISK分区规则。
FAT32仅用于大容量卡(>=4G)。
SD卡允许在两种模式下工作,即SD模式和SPI模式,本系统采用SPI模式。
本小节仅简要介绍SPI模式。
2、引脚
SD卡引脚如下图所示:
SD卡外部引脚图
micro-SD卡-本卡的物理尺寸见【1】。
SPI模式下SD各管脚名称为.JPG
注意:
SPI模式时,这些信号需要在主机端用10~100K欧的电阻上拉【2a】p4,如下表的相应引脚说明【2a】p5。
输入端是MOS管的G极,输出端很可能是OC输出或者输出电阻较大,需要增加上拉电阻以消除SD卡输入输出信号线上的不确定性与干扰。
也可以采用缓冲门方式,如【3】(我们现在购买并使用的)的电路为:
缓冲整形元件采用74VHC125,但该电路中的电阻绘制错误,应该是上拉电阻而不是串联电阻,如需要限流应该在每一个与外界连接的线上串联而不是只串联R4。
另外的在网上下载的几种连接图如下。
SD卡的几种连线图。
上面的连接可能没有必要。
5529实验板的连接如下。
该电路图仅在片选端CS上增加上拉电阻,而此处并不存在电平不确定的问题,因而是没有必要的。
很可能是MSP430的SPI口一旦设置,则在空闲时段SPI各口线仍保持确定的电平,故,不需要上拉电阻,另外,由于5529试验板的SD卡距离单片机很近,干扰很小,不需要采用74VHC125进行整形与缓冲。
可以在现有板上逐步拆解进行试验,拆解至不能正常运行的程度为止。
不过为了增加可靠性,还是增加一些上拉电阻好一些。
SD卡卡座:
3、寄存器
内部结构如下图。
SD卡内部图.JPG
SD卡中的微控制器SDControler在与主机通讯的过程中,根据命令与寄存器中的参数决定如何操作。
SD卡中的寄存器有【4】p7:
在SPI模式下,只有OCR、CID、CSD3个寄存器可以访问【2b】p18。
各寄存器的进一步解释如下【4】p10:
1)、OCR寄存器
32位的操作条件寄存器OCR(OperatingConditionsRegister)存储了VDD电压范围。
下图的例子中,OCR的4~14位为0,15~23位全为1,表示SD卡的电压范围是2.7~3.6V。
2)、CID寄存器
CID(CardIdentification)寄存器长度为16个字节,是SD卡唯一的标识号,包括生产厂家、生产日期、产品序列号等,该号在卡生产厂家编程后无法修改。
3)、CSD寄存器
CSD(CardSpecificData)寄存器包含访问卡数据所需的配置信息。
其部分字节的意义如下表【2】p39。
见“搜索XX关键词sd卡csd寄存器。
见网页:
SD/MMC相关寄存器的介绍,lwj103862095的专栏-博客频道-CSDN”,对CSD内容定义的结构变量如下。
相应的读取CSD程序见附录1。
typedefstruct
{
uint8 CSDStruct; //CSD结构
uint8 SysSpecVersion; //系统规范版本
uint8 Reserved1; //保留
uint8 TAAC; //读取时间1
uint8 NSAC; //数据在CLK周期内读取时间2
uint8 MaxBusClkFrec; //最大总线速度
uint16CardComdClasses; //卡命令集合
uint8 RdBlockLen; //最大读取数据块长
uint8 PartBlockRead; //允许读的部分块
uint8 WrBlockMisalign; //非线写块
uint8 RdBlockMisalign; //非线读块
uint8 DSRImpl; //DSR条件
uint8 Reserved2; //保留
uint32DeviceSize; //设备容量
uint8 MaxRdCurrentVDDMin; //最小读取电流@VDDmin
uint8 MaxRdCurrentVDDMax; //最大读取电流@VDDmax
uint8 MaxWrCurrentVDDMin; //最小写入电流@VDDmin
uint8 MaxWrCurrentVDDMax; //最大写入电流@VDDmax
uint8 DeviceSizeMul; //设备容量乘积因子
uint8 EraseGrSize; //擦出块大小
uint8 EraseGrMul; //擦出扇区大小
uint8 WrProtectGrSize; //写保护群大小
uint8 WrProtectGrEnable; //写保护群使能
uint8 ManDeflECC; //ManufacturerdefaultECC
uint8 WrSpeedFact; //写速度因子R2W_FACTOR
uint8 MaxWrBlockLen; //最大写数据块长度
uint8 WriteBlockPaPartial; //允许写的部分
uint8 Reserved3; //保留
uint8 ContentProtectAppli; //Contentprotectionapplication
uint8 FileFormatGrouop; //文件系统群
uint8 CopyFlag; //拷贝标志
uint8 PermWrProtect; //永久写保护
uint8 TempWrProtect; //暂时写保护
uint8 FileFormat; //文件系统
uint8 ECC; //ECCcode
uint8 CSD_CRC; //CSDCRC
uint8 Reserved4; //始终为1
}SD_CSD;
CSD记录了SD卡的一些技术参数,这些参数在产品说明书中应该可以看到,大部分内容是相同的,应该是只能读取,不能改变,一般情况下无需关心。
SD卡的寄存器与AD的寄存器不同,寄存器的作用较小,主要依靠命令进行不同的操作。
4、SPI模式协议
SD卡启动时处于SD模式。
它将在CS信号有效(低电平)时接收到一个复位命令(CMD0),回应R1,表示进入SPI总线模式,否则,表示SD卡仍停留在SD模式。
SPI总线模式下,默认的命令结构/协议CRC检查失效,由于电源开启时总是处于SD总线模式,CMD0后需要跟一个合法的CRC(即时CMD0使用SPI结构来发送)。
一旦进入SPI总线模式,CRC失效。
CMD0的完整值是:
400000000095H。
SD卡有设定好的复位顺序。
在上电复位或软复位(DMD0)后,进入静止状态,只能接收4条合法的命令:
CMD1、CMD41、CMD59、CMD58。
Host必须连续发送CMD1,直到in-idle-state位置0,表示初始化完成,可以接收下一命令。
SD卡依靠时钟进行工作。
Host必须额外的8个时钟信号给卡完成操作,在此期间,忽略CS。
Host可以在卡忙状态时关闭时钟信号。
SD卡将去完成这个烧录操作,然而,Host必须提供一个时钟信号给SD卡来关闭“忙”信号。
写入/檫除超时是因为超过了:
1)设定时间的100倍,2)250mS。
所有命令的长度均为6字节,首先发MSB,其格式为:
当SPI模式遇到问题时,将用一个错误来回答(替代原来的数据块)。
5、主要命令
SPI下支持的命令类型如下标“+”所示【2】5.2.2。
各命令的意义如下【2】5.2.2.1。
如果一个命令不需要参数,则相应的为清0。
详见【2b】p12、p13。
在每个命令(除SEND_STATUS)之后,回应R1,其MSB为0,其余位置1则表示发生了相应的错误,如下图。
写入单块数据操作时序图:
写入多块数据操作时序图:
详见【2b】p5、p6。
上图所指的“数据应答”格式如下。
数据令牌(标记)【2b】p17及【2】5.2.4是读写操作时,用于识别数据块的标记。
对于单、多块的读取及单块的写入,数据标记为0xFEH。
对于多块的写入,在每块前的数据标记为11111100B=0xFCH。
当出现错误时,将用错误标记替代数据标记:
6、复位与初始化及读写操作
SD卡的初始化是非常重要的,只有进行了正确的初始化,才能进行后面的各项操作。
在初始化过程中,SPI的时钟不能太快,否则会造初始化失败。
在刚开始要先发送至少74个时钟信号,这是必须的。
在很多读者的实验中,很多是因为疏忽了这一点,而使初始化不成功【5】p6。
这74个时钟,在SD卡上电后发送,用于使电状态稳定。
CS为低电平时发送命令0,对卡进行复位。
再发送若干个8位时钟,直到卡回应0x01H,即表示,卡在接收命令0成功时对CS信号进行了采样,若CS信号为低电平,使卡进入SPI模式并且回应R1进入空闲状态(R1=0x01)。
随后CS拉高,再发送8个时钟,时序如下图。
由于命令0必须作为原生命令发送,CRC字段必须包含有效值。
卡一旦进入SPI模式,CRC功能就被关闭,不再进行CRC校验【6】p6及【7】p2(或p147)及【2】5.1.7。
在空闲状态,卡只接收命令0、命令1、命令41、命令58(读OCR)和命令59。
其它的命令被拒绝执行。
此时,可以读OCR寄存器并查看卡的工作电压。
若系统供电不在卡的正常供电范围,则卡不工作。
注意,所有的卡工作电压范围为2.7~3.6V。
当接收到命令1时,卡执行初始化过程。
若要检测初始化过程是否结束,主机需持续发送命令1并查看回应直到初始化结束。
当卡成功完成初始化,应答R1的空闲状态位将清零(R1由0x01变为0x00)。
再拉高CS、发送8个空时钟。
初始化过程将持续几百毫秒(卡容量越大,时间越长),故而需要考虑超时时间的设定。
在空闲状态位被清零后,卡可以接收正常的读写命令【6】p7及【7】p3(或148)。
CMD1命令的构成为0x01H|0x40H=0x41H,同理可求出其它命令【7】p3。
从图中可知,CMD1为4100000000FF。
单块的读操作时序图如下【7】p4。
单块的写操作时序图如下【7】p5。
上述图中的NCR、NAC、NWR表示SD卡的控制器完成操作的等待时间,其具体数据见【2b】5.1.9.2及【2】p106Table-1A-1,如下表。
其中的TAAC、NSAC位于CSD寄存器参数表Table3-10【2】3.5.3或p39的第3、4条目,属于SD卡的交流参数,其部分值见【2】41Table3-12,通过这些参数可以计算等待时间范围如ThetotalreadaccesstimeNAC等。
考虑CSD寄存器参数表Table3-10【2】3.5.3或p39的第24条目R2W_FACTOR可以计算读写时间范围,见【2】p106Table-1A-1
实际计算需要读取CSD的值,比较麻烦,主要以编程运行调试为主。
相应的编程详见【7】p7-end。
7、读写命令C编程
8、其它
9、补充
参考资料
【1】micro-SD卡-本卡物理尺寸.DOC
【2】(英文原文)SD卡的官方资料.pdf
【2a】(中文翻译部分)SD卡中文翻译.doc
【2b】(中文翻译部分)SD卡-SPI总线协议.pdf
【3】【3】MicroSD卡适配器(文件夹)
【4】SD卡详细资料.pdf
【5】SD卡在单片机上的应用以及SD卡引脚-电路图及工作原理介绍.doc
【6】SD卡编程指南.pdf
【7】51单片机读写SD卡.pdf
附录1
网站资料——CSD读取程序。
/**************************************************************************************
*FunctionName :
SD_GetCSDRegister()
*Description :
CSD-寄存器。
寄存器长度为128,16字节
*EntryParameter:
csd寄存器
*ReturnValue :
返回操作状态:
成功-0
**************************************************************************************/
uint8SD_GetCSDRegister(SD_CSD*csd)
{
uint8i;
uint8csdTable[16];
uint8count=0xFF;
uint8rvalue=SD_RESPONSE_FAILURE; //返回值
SD_Enable(0); //SD卡使能
if(SD_SendCmd(CMD9,0x00,0xFF)==SD_RESPONSE_NO_ERROR)
{
while((SD_ReadByte()!
=SD_START_SINGLE_BLOCK_READ)&&count) //等待数据接收开始,收到0xFE表示开始
{
count--; //等待超时
}
if(count!
=0x00)
{
for(i=0;i<16;i++)
{
csdTable[i]=SD_ReadByte();
}
}
SD_ReadByte(); //读CRC
SD_ReadByte();
rvalue=SD_RESPONSE_NO_ERROR; //设置成功标志
}
SD_Enable
(1); //清除SD卡片选
SD_WriteByte(0xFF); //8个时钟脉冲的延迟
//把获取值放入CSD结构体中
csd->CSDStruct =(csdTable[0]&0xC0)>>6; //Byte0
csd->SysSpecVersion =(csdTable[0]&0x3C)>>2;
csd->Reserved1 =csdTable[0]&0x03;
csd->TAAC =csdTable[1]; //Byte1
csd->NSAC =csdTable[2]; //Byte2
csd->MaxBusClkFrec =csdTable[3]; //Byte3
csd->CardComdClasses =csdTable[4]<<4; //Byte4
csd->CardComdClasses |=(csdTable[5]&0xF0)>>4; //Byte5
csd->RdBlockLen =csdTable[5]&0x0F;
csd->PartBlockRead =(csdTable[6]&0x80)>>7; //Byte6
csd->WrBlockMisalign =(csdTable[6]&0x40)>>6;
csd->RdBlockMisalign =(csdTable[6]&0x20)>>5;
csd->DSRImpl =(csdTable[6]&0x10)>>4;
csd->Reserved2 =0;
csd->DeviceSize =(csdTable[6]&0x03)<<10;
csd->DeviceSize |=(csdTable[7])<<2; //Byte7
csd->DeviceSize |=(csdTable[8]&0xC0)>>6; //Byte8
csd->MaxRdCurrentVDDMin =(csdTable[8]&0x38)>>3;
csd->MaxRdCurrentVDDMax =(csdTable[8]&0x07);
csd->MaxWrCurrentVDDMin =(csdTable[9]&0xE0)>>5; //Byte9
csd->MaxWrCurrentVDDMax =(csdTable[9]&0x1C)>>2;
csd->DeviceSizeMul =(csdTable[9]&0x03)<<1;
csd->DeviceSizeMul |=(csdTable[10]&0x80)>>7; //Byte10
csd->EraseGrSize =(csdTable[10]&0x40)>>6;
csd->EraseGrMul =(csdTable[10]&0x3F)<<1;
csd->EraseGrMul |=(csdTable[11]&0x80)>>7; //Byte11
csd->WrProtectGrSize =(csdTable[11]&0x7F);
csd->WrProtectGrEnable =(csdTable[12]&0x80)>>7; //Byte12
csd->ManDeflECC =(csdTable[12]&0x60)>>5;
csd->WrSpeedFact =(csdTable[12]&0x1C)>>2;
csd->MaxWrBlockLen =(csdTable[12]&0x03)<<2;
csd->MaxWrBlockLen |=(csdTable[13]&0xC0)>>6; //Byte13
csd->WriteBlockPaPartial=(csdTable[13]&0x20)>>5;
csd->Reserved3 =0;
csd->ContentProtectAppli=(csdTable[13]&0x01);
csd->FileFormatGrouop =(csdTable[14]&0x80)>>7; //Byte14
csd->CopyFlag =(csdTable[14]&0x40)>>6;
csd->PermWrProtect =(csdTable[14]&0x20)>>5;
csd->TempWrProtect =(csdTable[14]&0x10)>>4;
csd->FileFormat =(csdTable[14]&0x0C)>>2;
csd->ECC =(csdTable[14]&0x03);
csd->CSD_CRC =(csdTable[15]&0xFE)>>1; //Byte15
csd->Reserved4 =1;
returnrvalue;
}