找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3975|回复: 1
打印 上一主题 下一主题
收起左侧

单片机读写sd卡例程与电路原理图

[复制链接]
跳转到指定楼层
楼主
51单片机读写sd卡例程分享给大家

电路原理图如下:


单片机源程序如下:
  1. /**************************************************************************************
  2. //------------------ MMC/SD-Card Reading and Writing implementation -------------------
  3. ****************************************************************************************/
  4. sbit SPI_DI =P2^1;
  5. sbit SPI_DO =P2^5;
  6. sbit SPI_SCL=P2^2;
  7. sbit SPI_CS =P2^0;


  8. //------------------------------------------------------------
  9. // Error define
  10. //-------------------------------------------------------------
  11. #define INIT_CMD0_ERROR     0x01
  12. #define INIT_CMD1_ERROR                0x02
  13. #define WRITE_BLOCK_ERROR        0x03
  14. #define READ_BLOCK_ERROR           0x04
  15. //-------------------------------------------------------------

  16. // data type
  17. //-------------------------------------------------------------   
  18. // this structure holds info on the MMC card currently inserted

  19. typedef struct MMC_VOLUME_INFO
  20. { //MMC/SD Card info
  21.   unsigned int  size_MB;
  22.   unsigned char sector_multiply;
  23.   unsigned int  sector_count;
  24.   unsigned char name[6];
  25. } VOLUME_INFO_TYPE;

  26. typedef struct STORE
  27. {
  28.   unsigned char dat[100];
  29. } BUFFER_TYPE; //256 bytes, 128 words

  30. BUFFER_TYPE sectorBuffer; //512 bytes for sector buffer

  31. //--------------------------------------------------------------
  32. unsigned int  readPos=0;
  33. unsigned char sectorPos=0;
  34. unsigned char LBA_Opened=0; //Set to 1 when a sector is opened.
  35. unsigned char Init_Flag;    //Set it to 1 when Init is processing.
  36. //---------------------------------------------------------------

  37. void delay(unsigned int time)
  38. {
  39. while(time--);
  40. }

  41. //****************************************************************************
  42. // Port Init
  43. void MMC_Port_Init()
  44. //****************************************************************************
  45. {
  46.    SPI_SCL=1;
  47.    SPI_DO =1;
  48.    SPI_CS=1;
  49.    send_s("Port Init!");
  50. /*
  51.    //Config ports
  52.    SPI_DI=1;          //Set Pin MMC_DI as Input
  53.    SPI_SCL=1;         //Set Pin MMC_Clock as Output
  54.    SPI_DO=1;          //Set Pin MMC_DO as Output
  55.    SPI_CS=1;          //Set MMC_Chip_Select to High,MMC/SD Invalid.
  56.    //busy led port init
  57.    //SPI_BY=1;        //Set spi busy led port output
  58.    //MMC_BUSY_LED=1;                      //busy led off     
  59.    */               
  60. }

  61. //****************************************************************************
  62. //Routine for sending a byte to MMC/SD-Card
  63. void Write_Byte_MMC(unsigned char value)
  64. //****************************************************************************
  65. {
  66.    unsigned char i;
  67.    
  68.    //Software SPI
  69.    for (i=0;i<8;i++)
  70.    {  //write a byte
  71.       if (((value>>(7-i))&0x01)==0x01)
  72.            SPI_DI=1; //Send bit by bit(MSB First)
  73.       else SPI_DI=0;
  74.        SPI_SCL=0; //set Clock Impuls low
  75.       if(Init_Flag)
  76.            delay(9);
  77.       SPI_SCL=1; //set Clock Impuls High
  78.       if(Init_Flag)
  79.            delay(9);     
  80.    }//write a byte
  81.    //MMC_BUSY_LED=1;
  82. }

  83. //****************************************************************************
  84. //Routine for reading a byte from MMC/SD-Card
  85. unsigned char Read_Byte_MMC()
  86. //****************************************************************************
  87. {
  88.    unsigned char temp=0;
  89.    unsigned char i;

  90.    //Software SPI
  91.    for (i=0;i<8;i++) //MSB First
  92.    {
  93.       SPI_DO=1;
  94.       SPI_SCL=0; //Clock Impuls (Low)
  95.       if(Init_Flag)
  96.            delay(9);
  97.       temp=(temp<<1)+(unsigned char)SPI_DO; //read mmc data out pin
  98.       SPI_SCL=1; //set Clock Impuls High
  99.       if(Init_Flag)
  100.            delay(9);       
  101.    }
  102.    return (temp);
  103. }

  104. //****************************************************************************
  105. //Send a Command to MMC/SD-Card
  106. //Return: the second byte of response register of MMC/SD-Card
  107. unsigned char Write_Command_MMC(unsigned char *CMD)
  108. //****************************************************************************
  109. {
  110.    unsigned char tmp;
  111.    unsigned char retry=0;
  112.    unsigned char i;

  113.    //set MMC_Chip_Select to high (MMC/SD-Card disable)
  114.    SPI_CS=1;
  115.    //send 8 Clock Impulse
  116.    Write_Byte_MMC(0xFF);
  117.    //set MMC_Chip_Select to low (MMC/SD-Card active)
  118.    SPI_CS=0;

  119.    //send 6 Byte Command to MMC/SD-Card
  120.    for (i=0;i<0x06;i++)
  121.    {
  122.       Write_Byte_MMC(*CMD++);
  123.    }
  124.    
  125.    //get 16 bit response
  126.    Read_Byte_MMC(); //read the first byte,ignore it.
  127.    do
  128.    {  //Only last 8 bit is used here.Read it out.
  129.       tmp = Read_Byte_MMC();
  130.       retry++;
  131.    }
  132.    while((tmp==0xff)&&(retry<100));
  133.    return(tmp);
  134. }

  135. //****************************************************************************
  136. //Routine for Init MMC/SD card(SPI-MODE)
  137. unsigned char MMC_Init()
  138. //****************************************************************************
  139. {  
  140.    unsigned char retry,temp;
  141.    unsigned char i;
  142.    unsigned char CMD[] = {0x40,0x00,0x00,0x00,0x00,0x95};
  143.    send_s("SD CARD Init!");
  144.    MMC_Port_Init(); //Init SPI port  

  145.    delay(200);
  146.    
  147.    Init_Flag=1; //Set the init flag

  148.    for (i=0;i<0x0f;i++)
  149.    {
  150.       Write_Byte_MMC(0xff); //send 74 clock at least!!!
  151.    }
  152.        
  153.    //Send Command CMD0 to MMC/SD Card
  154.    send_s("Send Command CMD0 to MMC/SD Card");
  155.    retry=0;
  156.    do
  157.    { //retry 200 times to send CMD0 command
  158.      temp=Write_Command_MMC(CMD);
  159.      retry++;
  160.      if(retry==200)
  161.      { //time out
  162.        return(INIT_CMD0_ERROR);//CMD0 Error!
  163.      }
  164.    }
  165.    while(temp!=1);
  166.    
  167.    //Send Command CMD1 to MMC/SD-Card
  168.    send_s("Send Command CMD1 to MMC/SD-Card");
  169.    CMD[0] = 0x41; //Command 1
  170.    CMD[5] = 0xFF;
  171.    retry=0;
  172.    do
  173.    { //retry 100 times to send CMD1 command
  174.      temp=Write_Command_MMC(CMD);
  175.      retry++;
  176.      if(retry==100)
  177.      { //time out
  178.        return(INIT_CMD1_ERROR);//CMD1 Error!
  179.      }
  180.    }
  181.    while(temp!=0);
  182.    
  183.    Init_Flag=0; //Init is completed,clear the flag
  184.    
  185.    SPI_CS=1;  //set MMC_Chip_Select to high
  186.    send_s("SD CARD Init Suc!!");
  187.    return(0x55); //All commands have been taken.
  188. }

  189. //****************************************************************************
  190. //Routine for reading data Registers of MMC/SD-Card
  191. //Return 0 if no Error.
  192. unsigned char MMC_Read_Block(unsigned char *CMD,unsigned char *Buffer,unsigned int Bytes)
  193. //****************************************************************************
  194. {  
  195.    unsigned int i;
  196.    unsigned retry,temp;
  197.    
  198.    //Send Command CMD to MMC/SD-Card
  199.    retry=0;
  200.    do
  201.    {  //Retry 100 times to send command.
  202.       temp=Write_Command_MMC(CMD);
  203.       retry++;
  204.       if(retry==100)
  205.       {
  206.         return(READ_BLOCK_ERROR); //block write Error!
  207.       }
  208.    }
  209.    while(temp!=0);
  210.                           
  211.    //Read Start Byte form MMC/SD-Card (FEh/Start Byte)
  212.    while (Read_Byte_MMC()!=0xfe);
  213.        
  214.    //Write blocks(normal 512Bytes) to MMC/SD-Card
  215.    for (i=0;i<Bytes;i++)
  216.    {
  217.       *Buffer++ = Read_Byte_MMC();
  218.    }
  219.    
  220.    //CRC-Byte
  221.    Read_Byte_MMC();//CRC - Byte
  222.    Read_Byte_MMC();//CRC - Byte
  223.        
  224.    //set MMC_Chip_Select to high (MMC/SD-Card invalid)
  225.    SPI_CS=1;
  226.    return(0);
  227. }

  228. //***************************************************************************
  229. //Routine for reading CSD Registers from MMC/SD-Card (16Bytes)
  230. //Return 0 if no Error.
  231. unsigned char Read_CSD_MMC(unsigned char *Buffer)
  232. //***************************************************************************
  233. {       
  234.    //Command for reading CSD Registers
  235.    unsigned char CMD[] = {0x49,0x00,0x00,0x00,0x00,0xFF};
  236.    unsigned char temp;
  237.    temp=MMC_Read_Block(CMD,Buffer,16); //read 16 bytes

  238.    return(temp);
  239. }

  240. //***************************************************************************
  241. //Routine for reading CID Registers from MMC/SD-Card (16Bytes)
  242. //Return 0 if no Error.
  243. unsigned char Read_CID_MMC(unsigned char *Buffer)
  244. //***************************************************************************
  245. {
  246.    //Command for reading CID Registers
  247.    unsigned char CMD[] = {0x4A,0x00,0x00,0x00,0x00,0xFF};
  248.    unsigned char temp;
  249.    temp=MMC_Read_Block(CMD,Buffer,16); //read 16 bytes

  250.    return(temp);
  251. }

  252. //****************************************************************************
  253. //returns the :
  254. //         size of the card in MB ( ret * 1024^2) == bytes
  255. //         sector count and multiplier MB are in u08 == C_SIZE / (2^(9-C_SIZE_MULT))
  256. //         name of the media
  257. void MMC_get_volume_info(void)
  258. //****************************************************************************
  259. {   unsigned char i;
  260.     unsigned char c_temp[5];
  261.     VOLUME_INFO_TYPE MMC_volume_Info,*vinf;
  262.     send_s("SD CARD Information Read!!");
  263.     vinf=&MMC_volume_Info; //Init the pointoer;
  264.         // read the CSD register
  265.     Read_CSD_MMC(sectorBuffer.dat);
  266.         // get the C_SIZE value. bits [73:62] of data
  267.         // [73:72] == sectorBuffer.data[6] && 0x03
  268.         // [71:64] == sectorBuffer.data[7]
  269.         // [63:62] == sectorBuffer.data[8] && 0xc0
  270.         vinf->sector_count = sectorBuffer.dat[6] & 0x03;
  271.         vinf->sector_count <<= 8;
  272.         vinf->sector_count += sectorBuffer.dat[7];
  273.         vinf->sector_count <<= 2;
  274.         vinf->sector_count += (sectorBuffer.dat[8] & 0xc0) >> 6;
  275.                
  276.         // get the val for C_SIZE_MULT. bits [49:47] of sectorBuffer.data
  277.         // [49:48] == sectorBuffer.data[5] && 0x03
  278.         // [47]    == sectorBuffer.data[4] && 0x80
  279.         vinf->sector_multiply = sectorBuffer.dat[9] & 0x03;
  280.         vinf->sector_multiply <<= 1;
  281.         vinf->sector_multiply += (sectorBuffer.dat[10] & 0x80) >> 7;

  282.         // work out the MBs
  283.         // mega bytes in u08 == C_SIZE / (2^(9-C_SIZE_MULT))
  284.         vinf->size_MB = vinf->sector_count >> (9-vinf->sector_multiply);
  285.         // get the name of the card
  286.         Read_CID_MMC(sectorBuffer.dat);
  287.         vinf->name[0] = sectorBuffer.dat[3];
  288.         vinf->name[1] = sectorBuffer.dat[4];
  289.         vinf->name[2] = sectorBuffer.dat[5];
  290.         vinf->name[3] = sectorBuffer.dat[6];
  291.         vinf->name[4] = sectorBuffer.dat[7];
  292.         vinf->name[5] = 0x00; //end flag
  293.         //----------------------------------------------------------
  294.         /*
  295.         while(1)
  296.         {
  297.          P1=~(unsigned char)((vinf->size_MB)>>8);
  298.          delay(50000);
  299.          delay(50000);
  300.          delay(50000);
  301.          delay(50000);
  302.          delay(50000);
  303.          P1=~(unsigned char)((vinf->size_MB));
  304.          delay(50000);
  305.          delay(50000);
  306.          delay(50000);
  307.          delay(50000);
  308.          delay(50000);
  309.         }*/
  310.     //LCDclrscr();
  311.     //Print Product name on lcd
  312.     i=0;
  313.     send_s("Product Name:");
  314.     //while((vinf->name[i]!=0x00)&&(i<16)) send(vinf->name[i++]);
  315.         send_s(vinf->name);
  316.     //Print Card Size(eg:128MB)
  317.     //gotoxy(1,0);
  318.     send_s("Tot:");
  319.     send_s(ftoa(vinf->size_MB,c_temp,0));
  320.         send_s("MB ");
  321.     //gotoxy(2,0);
  322.     //writestring("sector_mult:"); writeNumber(vinf->sector_multiply);
  323.     //gotoxy(3,0);
  324.    
  325. ……………………

  326. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
SD卡模块.rar (277.79 KB, 下载次数: 52)


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:67274 发表于 2018-7-30 11:36 | 只看该作者
不知道为什么,到了Send Command CMD0 to MMC/SD Card  后,就没见发送CMD1命令?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表