SD卡初始化以及命令详解


http://blog.csdn.net/dengrengong/article/details/39831757

SD卡是嵌入式设备中很常用的一种存储设备,体积小,容量大,通讯简单,电路简单所以受到很多设备厂商的欢迎,主要用来记录设备运行过程中的各种信息,以及程序的各种配置信息,很是方便,有这样几点是需要知道的

SD 卡是基于 flash的存储卡。

SD 卡和 MMC卡的区别在于初始化过程不同。SD卡并不是我们通常意义上的手机扩展卡,那种卡叫做TF,但是通讯以及驱动模式是类似的.

SD 卡的通信协议包括 SD SPI两类,SD卡上电之后默认处于SD状态。

SD 卡使用卡内智能控制模块进行 FLASH操作控制,包括协议、安全算法、

数据存取、ECC 算法、缺陷处理和分析、电源管理、时钟管理。这些都不需要用户关系,这是SD卡厂商做的事情

驱动SD卡主要要实现读扇区,写扇区,初始化,获取SD卡相关配置信息这几个就可以了,

另外.SD卡本身只是一种数据介质,它不含有文件系统,文件系统是一种文件的组织格式,是独立于存储介质的一种规范

SD卡初始化以及命令详解_第1张图片

标准SD卡引脚序列


SD卡引脚功能表

SD卡初始化以及命令详解_第2张图片

TF卡引脚排序

SD卡初始化以及命令详解_第3张图片

TF卡引脚功能表

由此可见,TF卡比SD卡少了一个VSS引脚,也就是少了一个供电引脚

另外电路设计时若SD卡使用SPI模式,那么不用的几根数据线应加上上拉电阻,否者会因为这几根数据线的电流震荡引起电流损耗,造成电路上的不稳定

SD卡电路SPI驱动模式

 SD卡初始化以及命令详解_第4张图片

SD卡内部有五个我们可以读取的寄存器,分别如下

 SD卡初始化以及命令详解_第5张图片

要读取这些信息就需要与卡通讯,SD通讯是用命令+数据的形式进行的,命令格式如下

SD卡初始化以及命令详解_第6张图片

也就是说,一次SD卡命令发送一共要发送6个字节,对于SPI通讯而言,就是SPI总线上传送六个字节

字节 1 的最高 2 位固定为 01,低 6位为命令号(比如 CMD16

10000 16 进制的 0X10,完整的 CMD16,第一个字节为 01010000,即 0X10+0X40)。

字节 2~5 为命令参数,有些命令是没有参数的。对于没有参数的命令默认发送0即可

字节 6 的高七位为 CRC 值,最低位恒定为 1,crc计算遵循以下规律


GX为生成多项式,具体计算方法请查看CRC计算相关,不过有一点好处就是,SPI驱动模式下,不需要CRC校验(默认SD卡在SPI模式下不开启CRC校验,SD模式下默认开始CRC校验),所以我们只需要对CMD0进行CRC就可以了,后面的CRC都可以不管(因为在CMD0之前是SD模式,所以第一个命令需要,切换之后就不用了),CMD0CRC0x95(加上了之后的一位1)

:SPI模式下打开crc校验需要用到CMD59的保留命令,请查阅相关资料

SD卡的命令表如下所示(以下仅写出SPI模式的CMD)

SD卡初始化以及命令详解_第7张图片

CMD0 复位SD,重置所有卡到 Idle状态,参数为0

CMD1 设置SD卡到ACTIVATE模式,也就是推出IDLE模式

SD卡初始化以及命令详解_第8张图片

CMD8 发送接口状态命令

CMD9 读取CSD寄存器

CMD10 读取CID寄存器


CMD12 在多块读取的时候请求停止读取

CMD13读取SD卡状态寄存器

SD卡初始化以及命令详解_第9张图片

CMD16 设置单个扇区的大小一般都设置为512字节一个扇区

CMD17 读取扇区命令

CMD18 读取多个扇区知道发送停止命令


CMD24 写扇区命令

CMD25 写多个扇区命令

SD卡初始化以及命令详解_第10张图片

CMD27 编辑CSD

CMD28设置地址组保护位。写保护由卡配置数据的WP_GRP_SIZE指定

CMD29清除保护位


CMD30 要求卡发送写保护状态,参数中有要查询的地址


CMD32 设置要擦除的第一个写数据块地址

CMD33 设置要擦除的最后一个写数据块地址


CMD38 擦除所有选中的块


CMD42 设置SD卡的解锁或者上锁

CMD55 告诉SD卡下一个命令式卡应用命令,不是标准命令

SD卡初始化以及命令详解_第11张图片

CMD56 应用相关的数据块读写命令


CMD58 读取OCR信息

CMD59 设置crc校验的使能与关闭(前面说到过)


ACMD13 发送SD卡状态


ACMD18保留作为 SD安全应用(也就是这命令没用)


ACMD22发送写数据块的数目。响应为 32+CRC

ACMD23设置写前预擦除的数据块数目(用来加速多数据块写操作)1=默认(一个块)(1)

不管是否使用 ACMD23,在多数据块写操作中都需要 STOP_TRAN(CMD12)命令


ACMD25 26 38 保留作为安全应用

SD卡初始化以及命令详解_第12张图片

ACMD41要求访问的卡发送它的操作条件寄存器(OCR)内容

ACMD42连接[1]/断开[0]卡上CD/DAT3(pin 1] 50K欧姆上拉电阻。上拉电阻可用来检测卡

ACMD43-49保留作为安全应用

ACMD51读取 SD配置寄存器 SCR

 

ACMD命令,全称应该是application CMD,所以使用ACMD都需要在发送CMD55之后

发出命令后会收到相应的响应,所有响应通过 CMD线传输,响应以 MSB开始,不同类型的响应长度根据类型不同而不同。

响应以起始位开始(通常为“0),接着这是传输方向的位(卡为 0)。除了 R3外其他

响应都有 CRC。每个响应都以结束位(通常为“1)结束。,SD卡响应格式有多种

1.       R1响应

SD卡初始化以及命令详解_第13张图片


2.       R1b响应


多了一个忙数据

3.       R2响应

SD卡初始化以及命令详解_第14张图片

4.       R3响应(针对于read ocr的响应 CMD58)

SD卡初始化以及命令详解_第15张图片

5.       响应R4R5都是正对于SD mode的响应

6.       针对CMD8命令的响应R7

 SD卡初始化以及命令详解_第16张图片

 

SD卡的初始化以及识别过程(为了方便起见,我们只检测响应的R1状态)

1.  初始化与 SD卡连接的硬件条件(MCU SPI配置,IO口配置);

2.  上电延时(>74 CLK(为了让卡正常启动)

3.  复位卡(CMD0),进入 IDLE状态,检测R1的最低位,是否为闲置状态

4.  发送 CMD8,检查是否支持 2.0协议,因为这个命令是在2.0的协议里面才添加的

5.  根据不同协议检查 SD卡(命令包括:CMD55CMD41CMD58 CMD1等);

6.  取消片选,发多 8 CLK,结束初始化

具体请查看下图

SD卡初始化以及命令详解_第17张图片

以下是网络上找到的一份经我修改之后的SD卡驱动,不完全符合SD卡标准驱动,但是我用着一直还蛮正常,大家有兴趣可以看看改改

 

Spisd.c

[cpp] view plain copy
  1. #include "spisd.h"  
  2.   
  3. //预定义SD卡类型  
  4. u8  SD_Type=0;//SD卡的类型   
  5.   
  6. //这部分应根据具体的连线来修改!  
  7. #define SD_CS  PAout(4) //SD卡片选引脚  
  8.   
  9. //data:要写入的数据  
  10. //返回值:读到的数据  
  11. static u8 SdSpiReadWriteByte(u8 data)  
  12. {  
  13.     return Spi1ReadWriteByte(data);  
  14. }  
  15.   
  16. //SD卡初始化的时候,需要低速  
  17. static void SdSpiSpeedLow(void)  
  18. {  
  19.     Spi1SetSpeed(SPI_SPEED_256);//设置到低速模式  用于初始化,最高spi速度为400k     
  20. }  
  21.   
  22. //SD卡正常工作的时候,可以高速了  
  23. static void SdSpiSpeedHigh(void)  
  24. {  
  25.     Spi1SetSpeed(SPI_SPEED_4);//设置到高速模式 初始化完成之后进行,最高可到25M,不过一般不用  
  26. }  
  27.   
  28.   
  29. static void SdIOInit(void)  
  30. {  
  31.     GPIO_InitTypeDef GPIO_InitStructure;  
  32.     RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE );   
  33.       
  34.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;  
  35.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;   //推挽输出  
  36.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
  37.     GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化A4  
  38.       
  39.     SD_CS = 1;  
  40.     Spi1Init();//初始化SPI接口  
  41.     SdSpiSpeedLow();//初始化设置为低速  
  42. }  
  43.   
  44. //等待卡准备好  
  45. //返回值:0,准备好了;其他,错误代码  
  46. static u8 SdWaitReady(void)  
  47. {  
  48.     u32 t=0;  
  49.     do  
  50.     {  
  51.         if(SdSpiReadWriteByte(0XFF)==0XFF)return 0;//OK  
  52.         t++;              
  53.     }while(t<0XFFFFFF);//等待   
  54.     return 1;  
  55. }  
  56.   
  57. //取消选择,释放SPI总线  
  58. void SD_DisSelect(void)  
  59. {  
  60.     SD_CS=1;  
  61.     SdSpiReadWriteByte(0xff);//提供额外的8个时钟  
  62. }  
  63.   
  64. //选择sd卡,并且等待卡准备OK  
  65. //返回值:0,成功;1,失败;  
  66. u8 SdSelect(void)  
  67. {  
  68.     SD_CS=0;  
  69.     if(SdWaitReady()==0)return 0;//等待成功  
  70.     SD_DisSelect();  
  71.     return 1;//等待失败  
  72. }  
  73.   
  74. //等待SD卡回应  
  75. //Response:要得到的回应值  
  76. //返回值:0,成功得到了该回应值  
  77. //    其他,得到回应值失败    期待得到的回应值  
  78. u8 SdGetResponse(u8 Response)  
  79. {  
  80.     u16 Count=0xFFF;//等待次数                              
  81.     while ((SdSpiReadWriteByte(0XFF)!=Response)&&Count)Count--;//等待得到准确的回应          
  82.     if (Count==0)return MSD_RESPONSE_FAILURE;//得到回应失败     
  83.     else return MSD_RESPONSE_NO_ERROR;//正确回应  
  84. }  
  85.   
  86. //从sd卡读取一个数据包的内容  
  87. //buf:数据缓存区  
  88. //len:要读取的数据长度.  
  89. //返回值:0,成功;其他,失败;  
  90. //0XFE数据起始令牌      
  91. u8 SdRecvData(u8*buf,u16 len)  
  92. {                   
  93.     if(SdGetResponse(0xFE))return 1;//等待SD卡发回数据起始令牌0xFE  
  94.     while(len--)//开始接收数据  
  95.     {  
  96.         *buf=SdSpiReadWriteByte(0xFF);  
  97.         buf++;  
  98.     }  
  99.     //下面是2个伪CRC(dummy CRC)  
  100.     SdSpiReadWriteByte(0xFF);  
  101.     SdSpiReadWriteByte(0xFF);                                                             
  102.     return 0;//读取成功  
  103. }  
  104.   
  105. //向sd卡写入一个数据包的内容 512字节  
  106. //buf:数据缓存区  
  107. //cmd:指令  
  108. //返回值:0,成功;其他,失败;     
  109. u8 SdSendBlock(u8*buf,u8 cmd)  
  110. {     
  111.     u16 t;              
  112.     if(SdWaitReady())return 1;//等待准备失效  
  113.     SdSpiReadWriteByte(cmd);  
  114.     if(cmd!=0XFD)//不是结束指令  
  115.     {  
  116.         for(t=0;t<512;t++)SdSpiReadWriteByte(buf[t]);//提高速度,减少函数传参时间  
  117.         SdSpiReadWriteByte(0xFF);//忽略crc  
  118.         SdSpiReadWriteByte(0xFF);  
  119.         t=SdSpiReadWriteByte(0xFF);//接收响应  
  120.         if((t&0x1F)!=0x05)return 2;//响应错误                                                             
  121.     }                                                                                     
  122.     return 0;//写入成功  
  123. }  
  124.   
  125.   
  126. //向SD卡发送一个命令  
  127. //输入: u8 cmd   命令   
  128. //      u32 arg  命令参数  
  129. //      u8 crc   crc校验值      
  130. //返回值:SD卡返回的响应                                                              
  131. u8 SdSendCmd(u8 cmd, u32 arg, u8 crc)  
  132. {  
  133.     u8 r1;    
  134.     u8 Retry=0;   
  135.     SD_DisSelect();//取消上次片选  
  136.     if(SdSelect())return 0XFF;//片选失效   
  137.     //发送  
  138.     SdSpiReadWriteByte(cmd | 0x40);//分别写入命令  
  139.     SdSpiReadWriteByte(arg >> 24);  
  140.     SdSpiReadWriteByte(arg >> 16);  
  141.     SdSpiReadWriteByte(arg >> 8);  
  142.     SdSpiReadWriteByte(arg);        
  143.     SdSpiReadWriteByte(crc);   
  144.     if(cmd==CMD12)SdSpiReadWriteByte(0xff);//Skip a stuff byte when stop reading  
  145.     //等待响应,或超时退出  
  146.     Retry=0X1F;  
  147.     do  
  148.     {  
  149.         r1=SdSpiReadWriteByte(0xFF);  
  150.     }while((r1&0X80) && Retry--);      
  151.     //返回状态值  
  152.     return r1;  
  153. }     
  154.   
  155. //获取SD卡的CID信息,包括制造商信息  
  156. //输入: u8 *cid_data(存放CID的内存,至少16Byte)       
  157. //返回值:0:NO_ERR  
  158. //       1:错误                                                            
  159. u8 SdGetCID(u8 *cid_data)  
  160. {  
  161.     u8 r1;       
  162.     //发CMD10命令,读CID  
  163.     r1=SdSendCmd(CMD10,0,0x01);  
  164.     if(r1==0x00)  
  165.     {  
  166.         r1=SdRecvData(cid_data,16);//接收16个字节的数据    
  167.     }  
  168.     SD_DisSelect();//取消片选  
  169.     if(r1)return 1;  
  170.     else return 0;  
  171. }     
  172.   
  173. //获取SD卡的CSD信息,包括容量和速度信息  
  174. //输入:u8 *cid_data(存放CID的内存,至少16Byte)          
  175. //返回值:0:NO_ERR  
  176. //       1:错误                                                            
  177. u8 SdGetCSD(u8 *csd_data)  
  178. {  
  179.     u8 r1;     
  180.     r1=SdSendCmd(CMD9,0,0x01);//发CMD9命令,读CSD  
  181.     if(r1==0)  
  182.     {  
  183.         r1=SdRecvData(csd_data, 16);//接收16个字节的数据   
  184.     }  
  185.     SD_DisSelect();//取消片选  
  186.     if(r1)return 1;  
  187.     else return 0;  
  188. }  
  189.   
  190. //获取SD卡的总扇区数(扇区数)     
  191. //返回值:0: 取容量出错   
  192. //其他:SD卡的容量(扇区数/512字节)  
  193. //每扇区的字节数必为512,因为如果不是512,则初始化不能通过.                                                          
  194. u32 SdGetSectorCount(void)  
  195. {  
  196.     u8 csd[16];  
  197.     u32 Capacity;    
  198.     u8 n;  
  199.     u16 csize;                            
  200.     //取CSD信息,如果期间出错,返回0  
  201.     if(SdGetCSD(csd)!=0) return 0;        
  202.     //如果为SDHC卡,按照下面方式计算  
  203.     if((csd[0]&0xC0)==0x40)  //V2.00的卡  
  204.     {     
  205.         csize = csd[9] + ((u16)csd[8] << 8) + 1;  
  206.         Capacity = (u32)csize << 10;//得到扇区数                
  207.     }else//V1.XX的卡  
  208.     {     
  209.         n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;  
  210.         csize = (csd[8] >> 6) + ((u16)csd[7] << 2) + ((u16)(csd[6] & 3) << 10) + 1;  
  211.         Capacity= (u32)csize << (n - 9);//得到扇区数     
  212.     }  
  213.     return Capacity;  
  214. }  
  215.   
  216.   
  217. //初始化SD卡  
  218. //返回值:0,正常.  
  219. //其他,不正常.  
  220. u8 SdInitialize(void)  
  221. {  
  222.     u8 r1;      // 存放SD卡的返回值  
  223.     u16 retry;  // 用来进行超时计数  
  224.     u8 buf[4];    
  225.     u16 i;  
  226.       
  227.     SdIOInit();     //初始化IO   
  228.     for(i=0;i<10;i++)SdSpiReadWriteByte(0XFF);//发送最少74个脉冲  ,这里发送了80个脉冲  
  229.     retry=20;  
  230.     do  
  231.     {  
  232.         r1=SdSendCmd(CMD0,0,0x95);//进入IDLE状态  
  233.     }while((r1!=0X01) && retry--);  
  234.     SD_Type=0;//默认无卡  
  235.     if(r1==0X01)  
  236.     {  
  237.         if(SdSendCmd(CMD8,0x1AA,0x87)==1)//SD V2.0  
  238.         {  
  239.             for(i=0;i<4;i++)buf[i]=SdSpiReadWriteByte(0XFF); //Get trailing return value of R7 resp  
  240.             if(buf[2]==0X01&&buf[3]==0XAA)//卡是否支持2.7~3.6V  
  241.             {  
  242.                 retry=0XFFFE;  
  243.                 do  
  244.                 {  
  245.                     SdSendCmd(CMD55,0,0X01);    //发送CMD55  
  246.                     r1=SdSendCmd(CMD41,0x40000000,0X01);//发送CMD41  
  247.                 }while(r1&&retry--);  
  248.                 if(retry&&SdSendCmd(CMD58,0,0X01)==0)//鉴别SD2.0卡版本开始  
  249.                 {  
  250.                     for(i=0;i<4;i++)buf[i]=SdSpiReadWriteByte(0XFF);//得到OCR值  
  251.                     if(buf[0]&0x40)SD_Type=SD_TYPE_V2HC;    //检查CCS  
  252.                     else SD_Type=SD_TYPE_V2;     
  253.                 }  
  254.             }  
  255.         }else//SD V1.x/ MMC V3  
  256.         {  
  257.             SdSendCmd(CMD55,0,0X01);        //发送CMD55  
  258.             r1=SdSendCmd(CMD41,0,0X01); //发送CMD41  
  259.             if(r1<=1)  
  260.             {         
  261.                 SD_Type=SD_TYPE_V1;  
  262.                 retry=0XFFFE;  
  263.                 do //等待退出IDLE模式  
  264.                 {  
  265.                     SdSendCmd(CMD55,0,0X01);    //发送CMD55  
  266.                     r1=SdSendCmd(CMD41,0,0X01);//发送CMD41  
  267.                 }while(r1&&retry--);  
  268.             }else  
  269.             {  
  270.                 SD_Type=SD_TYPE_MMC;//MMC V3  
  271.                 retry=0XFFFE;  
  272.                 do //等待退出IDLE模式  
  273.                 {                                                 
  274.                     r1=SdSendCmd(CMD1,0,0X01);//发送CMD1  
  275.                 }while(r1&&retry--);    
  276.             }  
  277.             if(retry==0||SdSendCmd(CMD16,512,0X01)!=0)SD_Type=SD_TYPE_ERR;//错误的卡  
  278.         }  
  279.     }  
  280.     SD_DisSelect();//取消片选  
  281.     SdSpiSpeedHigh();//高速  
  282.     if(SD_Type)return 0;  
  283.     else if(r1)return r1;        
  284.     return 0xaa;//其他错误  
  285. }  
  286.   
  287.   
  288.   
  289. //读SD卡  
  290. //buf:数据缓存区  
  291. //sector:扇区  
  292. //cnt:扇区数  
  293. //返回值:0,ok;其他,失败.  
  294. u8 SdReadDisk(u8*buf,u32 sector,u8 cnt)  
  295. {  
  296.     u8 r1;  
  297.     if(SD_Type!=SD_TYPE_V2HC)sector <<= 9;//转换为字节地址  
  298.     if(cnt==1)  
  299.     {  
  300.         r1=SdSendCmd(CMD17,sector,0X01);//读命令  
  301.         if(r1==0)//指令发送成功  
  302.         {  
  303.             r1=SdRecvData(buf,512);//接收512个字节        
  304.         }  
  305.     }else  
  306.     {  
  307.         r1=SdSendCmd(CMD18,sector,0X01);//连续读命令  
  308.         do  
  309.         {  
  310.             r1=SdRecvData(buf,512);//接收512个字节      
  311.             buf+=512;    
  312.         }while(--cnt && r1==0);       
  313.         SdSendCmd(CMD12,0,0X01);    //发送停止命令  
  314.     }     
  315.     SD_DisSelect();//取消片选  
  316.     return r1;//  
  317. }  
  318.   
  319. //写SD卡  
  320. //buf:数据缓存区  
  321. //sector:起始扇区  
  322. //cnt:扇区数  
  323. //返回值:0,ok;其他,失败.  
  324. u8 SdWriteDisk(u8*buf,u32 sector,u8 cnt)  
  325. {  
  326.     u8 r1;  
  327.     if(SD_Type!=SD_TYPE_V2HC)sector *= 512;//转换为字节地址  
  328.     if(cnt==1)  
  329.     {  
  330.         r1=SdSendCmd(CMD24,sector,0X01);//读命令  
  331.         if(r1==0)//指令发送成功  
  332.         {  
  333.             r1=SdSendBlock(buf,0xFE);//写512个字节       
  334.         }  
  335.     }else  
  336.     {  
  337.         if(SD_Type!=SD_TYPE_MMC)  
  338.         {  
  339.             SdSendCmd(CMD55,0,0X01);      
  340.             SdSendCmd(CMD23,cnt,0X01);//发送指令      
  341.         }  
  342.         r1=SdSendCmd(CMD25,sector,0X01);//连续读命令  
  343.         if(r1==0)  
  344.         {  
  345.             do  
  346.             {  
  347.                 r1=SdSendBlock(buf,0xFC);//接收512个字节    
  348.                 buf+=512;    
  349.             }while(--cnt && r1==0);  
  350.             r1=SdSendBlock(0,0xFD);//接收512个字节   
  351.         }  
  352.     }     
  353.     SD_DisSelect();//取消片选  
  354.     return r1;//  
  355. }     


Spisd.h

 

[cpp] view plain copy
  1. #ifndef __SPISD_H_  
  2. #define __SPISD_H_  
  3.   
  4. #include "spi.h"  
  5. #include "delay.h"  
  6. #include "common.h"  
  7. #include "ioremap.h"  
  8.   
  9. // SD卡类型定义    
  10. #define SD_TYPE_ERR     0X00  
  11. #define SD_TYPE_MMC     0X01  
  12. #define SD_TYPE_V1      0X02  
  13. #define SD_TYPE_V2      0X04  
  14. #define SD_TYPE_V2HC    0X06      
  15.   
  16. // SD卡指令表        
  17. #define CMD0    0       //卡复位  
  18. #define CMD1    1  
  19. #define CMD8    8       //命令8 ,SEND_IF_COND  
  20. #define CMD9    9       //命令9 ,读CSD数据  
  21. #define CMD10   10      //命令10,读CID数据  
  22. #define CMD12   12      //命令12,停止数据传输  
  23. #define CMD16   16      //命令16,设置SectorSize 应返回0x00  
  24. #define CMD17   17      //命令17,读sector  
  25. #define CMD18   18      //命令18,读Multi sector  
  26. #define CMD23   23      //命令23,设置多sector写入前预先擦除N个block  
  27. #define CMD24   24      //命令24,写sector  
  28. #define CMD25   25      //命令25,写Multi sector  
  29. #define CMD41   41      //命令41,应返回0x00  
  30. #define CMD55   55      //命令55,应返回0x01  
  31. #define CMD58   58      //命令58,读OCR信息  
  32. #define CMD59   59      //命令59,使能/禁止CRC,应返回0x00  
  33.   
  34. // SD卡中的响应有许多种,R1为标准响应,最为常用。与R1响应相似的还有R1b、R2和R3。  
  35. // R1响应在除SEND_STATUS外其它命令后发送,也是最高位先发送,共1个字节。最高位为0。响应说明如下:  
  36. // 0x01:空闲状态  
  37. // 0x02:擦除错误  
  38. // 0x04:命令错误  
  39. // 0x08:CRC通信错误  
  40. // 0x10:擦除次序错误  
  41. // 0x20:地址错误  
  42. // 0x40:参数错误  
  43.   
  44. #define MSD_RESPONSE_NO_ERROR      0x00    //无错误  
  45. #define MSD_IN_IDLE_STATE          0x01    //空闲状态  
  46. #define MSD_ERASE_RESET            0x02    //擦除错误  
  47. #define MSD_ILLEGAL_COMMAND        0x04    //命令错误  
  48. #define MSD_COM_CRC_ERROR          0x08    //CRC通信错误  
  49. #define MSD_ERASE_SEQUENCE_ERROR   0x10    //擦除次序错误  
  50. #define MSD_ADDRESS_ERROR          0x20    //地址错误  
  51. #define MSD_PARAMETER_ERROR        0x40    //参数错误  
  52. #define MSD_RESPONSE_FAILURE       0xFF    //这次命令根本是失败的,没有任何回应  
  53.   
  54. u8 SdInitialize(void);  
  55.   
  56. u8 SdGetCID(u8 *cid_data);  
  57.   
  58. u8 SdGetCSD(u8 *csd_data);  
  59.   
  60. u32 SdGetSectorCount(void);  
  61.   
  62. u8 SdReadDisk(u8*buf,u32 sector,u8 cnt);  
  63.   
  64. u8 SdWriteDisk(u8*buf,u32 sector,u8 cnt);  
  65.   
  66.   
  67. #endif 

你可能感兴趣的:(soc的常用模块)