微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 单片机对SD卡读写系列(二)

单片机对SD卡读写系列(二)

时间:11-23 来源:互联网 点击:
写命令的例程:

  1. //-----------------------------------------------------------------------------------------------
  2. SD卡中写入命令,并返回回应的第二个字节
  3. //-----------------------------------------------------------------------------------------------
  4. unsignedcharWrite_Command_SD(unsignedchar*CMD)
  5. {
  6. unsignedchartmp;
  7. unsignedcharretry=0;
  8. unsignedchari;
  9. //禁止SD卡片选
  10. SPI_CS=1;
  11. //发送8个时钟信号
  12. Write_Byte_SD(0xFF);
  13. //使能SD卡片选
  14. SPI_CS=0;
  15. //向SD卡发送6字节命令
  16. for(i=0;i<0x06;i++)
  17. {
  18. Write_Byte_SD(*CMD++);
  19. }
  20. //获得16位的回应
  21. Read_Byte_SD();//readthefirstbyte,ignoreit.
  22. do
  23. {//读取后8位
  24. tmp=Read_Byte_SD();
  25. retry++;
  26. }
  27. while((tmp==0xff)&&(retry<100));
  28. return(tmp);
  29. }

2)初始化
SD卡的初始化是非常重要的,只有进行了正确的初始化,才能进行后面的各项操作。在初始化过程中,SPI的时钟不能太快,否则会造初始化失败。在初始化成功后,应尽量提高SPI的速率。在刚开始要先发送至少74个时钟信号,这是必须的。在很多读者的实验中,很多是因为疏忽了这一点,而使初始化不成功。随后就是写入两个命令CMD0与CMD1,使SD卡进入SPI模式
初始化时序图:


初始化例程:

  1. //--------------------------------------------------------------------------
  2. 初始化SD卡到SPI模式
  3. //--------------------------------------------------------------------------
  4. unsignedcharSD_Init()
  5. {
  6. unsignedcharretry,temp;
  7. unsignedchari;
  8. unsignedcharCMD[]={0x40,0x00,0x00,0x00,0x00,0x95};
  9. SD_Port_Init();//初始化驱动端口
  10. Init_Flag=1;//将初始化标志置1
  11. for(i=0;i<0x0f;i++)
  12. {
  13. Write_Byte_SD(0xff);//发送至少74个时钟信号
  14. }
  15. //向SD卡发送CMD0
  16. retry=0;
  17. do
  18. {//为了能够成功写入CMD0,在这里写200次
  19. temp=Write_Command_SD(CMD);
  20. retry++;
  21. if(retry==200)
  22. {//超过200次
  23. return(INIT_CMD0_ERROR);//CMD0Error!
  24. }
  25. }
  26. while(temp!=1);//回应01h,停止写入
  27. //发送CMD1到SD卡
  28. CMD[0]=0x41;//CMD1
  29. CMD[5]=0xFF;
  30. retry=0;
  31. do
  32. {//为了能成功写入CMD1,写100次
  33. temp=Write_Command_SD(CMD);
  34. retry++;
  35. if(retry==100)
  36. {//超过100次
  37. return(INIT_CMD1_ERROR);//CMD1Error!
  38. }
  39. }
  40. while(temp!=0);//回应00h停止写入
  41. Init_Flag=0;//初始化完毕,初始化标志清零
  42. SPI_CS=1;//片选无效
  43. return(0);//初始化成功
  44. }

3)读取CID
CID寄存器存储了SD卡的标识码。每一个卡都有唯一的标识码。
CID寄存器长度为128位。它的寄存器结构如下:

名称

数据宽度

CID划分

生产标识号

MID

8

[127:120]

OEM/应用标识

OID

16

[119:104]

产品名称

PNM

40

[103:64]

产品版本

PRV

8

[63:56]

产品序列号

PSN

32

[55:24]

保留

4

[23:20]

生产日期

MDT

12

[19:8]

CRC7校验合

CRC

7

[7:1]

未使用,始终为1

1

[0:0]

它的读取时序如下:

与此时序相对应的程序如下:

  1. //------------------------------------------------------------------------------------
  2. 读取SD卡的CID寄存器16字节成功返回0
  3. //-------------------------------------------------------------------------------------
  4. unsignedcharRead_CID_SD(unsignedchar*Buffer)
  5. {
  6. //读取CID寄存器的命令
  7. unsignedcharCMD[]={0x4A,0x00,0x00,0x00,0x00,0xFF};
  8. unsignedchartemp;
  9. temp=SD_Read_Block(CMD,Buffer,16);//read16bytes
  10. return(temp);
  11. }

4)读取CSD
CSD(Card-Specific Data)寄存器提供了读写SD卡的一些信息。其中的一些单元可以由用户重新编程。 读取CSD 的时序:


相应的程序例程如下:

  1. //-----------------------------------------------------------------------------------------
  2. 读SD卡的CSD寄存器共16字节返回0说明读取成功
  3. //-----------------------------------------------------------------------------------------
  4. unsignedcharRead_CSD_SD(unsignedchar*Buffer)
  5. {
  6. //读取CSD寄存器的命令
  7. unsignedcharCMD[]={0x49,0x00,0x00,0x00,0x00,0xFF};
  8. unsignedchartemp;
  9. temp=SD_Read_Block(CMD,Buffer,16);//read16bytes
  10. return(temp);
  11. }

4)读取SD卡信息
综合上面对CID与CSD寄存器的读取,可以知道很多关于SD卡的信息,以下程序可以获取这些信息。如下:

  1. //-----------------------------------------------------------------------------------------------
  2. //返回
  3. //SD卡的容量,单位为M
  4. //sectorcountandmultiplierMBarein
  5. u08==C_SIZE/(2^(9-C_SIZE_MULT))
  6. //SD卡的名称
  7. //-----------------------------

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top