为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

SD卡初始化及读取程序

2013-09-15 6页 pdf 114KB 27阅读

用户头像

is_899832

暂无简介

举报
SD卡初始化及读取程序 SD 卡初始化及读取程序 首先是 SD 卡的初始化问题。SD 卡的初始化很简单,各个论坛上写的也很详细,个人认 为基本不存在太大问题。首先是 74 个 clk,然后 CS_LOW;发送 CMD0,收到的应答是 0x01; 接着发送 CMD1,收到的应答应该是 0x00;最后 CS_HIGH。至此,初始化完成。需要注意的 问题:初始化的时钟不宜太快,可以在 SD 卡初始化完成后可提高数据读写速度;在发送命 令之前和收到应答位之后,主控制器应该发送 8个时钟完成相应操作;CMD0的 CRC是 0x95, 其余命令的 C...
SD卡初始化及读取程序
SD 卡初始化及读取程序 首先是 SD 卡的初始化问题。SD 卡的初始化很简单,各个论坛上写的也很详细,个人认 为基本不存在太大问题。首先是 74 个 clk,然后 CS_LOW;发送 CMD0,收到的应答是 0x01; 接着发送 CMD1,收到的应答应该是 0x00;最后 CS_HIGH。至此,初始化完成。需要注意的 问题:初始化的时钟不宜太快,可以在 SD 卡初始化完成后可提高数据读写速度;在发送命 令之前和收到应答位之后,主控制器应该发送 8个时钟完成相应操作;CMD0的 CRC是 0x95, 其余命令的 CRC无所谓。  读取单块数据流程:CS_LOW‐‐>8 个 clk‐‐>发送 CMD17‐‐>接收响应 R1‐‐>接收读数据起始 令牌 0xFE‐‐>接收数据‐‐>接收 CRC‐‐>8 个 clk‐‐>CS_HIGH;  写入单块数据流程:CS_LOW‐‐>8 个 clk‐‐>发送 CMD24‐‐>接收响应 R1‐‐>写入读数据起始 令牌 0xFE‐‐>写入数据‐‐>接收 CRC‐‐>8 个 clk‐‐>CS_HIGH;  读写操作指令:单块写命令 CMD24,多块写命令 CMD25;单块读命令  CMD17,多块读 命令 CMD18。单块读写时,数据块的长度为 512 字节,多块读写时 SD 卡收到 1 个停止命令 CMD12 后停止读写。  本程序参考自 bozai 的 SD 卡驱动程序,  增加了 SD、MMC 卡判断的功能,SD、MMC 初始化成功后能返回卡的类型参数供主程序使用。      //‐‐‐‐‐‐‐‐SD_MMC.H‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐      #ifndef __SD_MMC_H__    #define __SD_MMC_H__      //  数据宏定义    #define uint8    unsigned char    #define    int8      signed char    #define uint16 unsigned int    #define    int16     signed int    #define uint32 unsigned long    #define    int32     signed long      // C8051F015与 SD_MMC  的接口定义    sbit SDCS          = P3^0;    sbit SDDET          = P3^1;    sbit SDWP          = P3^2;        void SPI_SendWreit(uchar temp);          // VS1003B DATA发送    uint8 SPI_SendByte(uint8 val);          // SPI传送一个字节    uint8 MMC_SD_SendCmd(uint8 Cmd, uint32 arg);          //发送卡命令    uint8 MMC_SD_ReadSingleBlock(uint32 sector, uint8 *buffer);          //读一个扇区    uint8 MMC_SD_WriteSingleBlock(uint32 sector, uint8 *buffer);          //写一个扇区    uint8 MMC_SD_init();          //mmc_sd 卡初始化      #endif    //‐‐‐‐‐‐‐‐‐SD_MMC.C‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐      //‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐    //          SD_MMC  底层驱动函数库    //        编译环境:Keil C V2.40    //        编写日期:2008‐04‐07    //        最后更新:2008‐05‐04    //‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐    #include "main.h"    #include "sd_mmc.h"      //‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐    //        函数名:SPI_SendByte    //        功  能:SPI  数据发送    //        参  数:uchar    //        返回值:    //‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐      void SPI_SendWreit(uchar temp)    {              SPI0DAT=temp;              while(TXBSY);          //  查询发送标志位    }      //‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐    //        函数名:SPI_SendByte    //        功  能:SPI传送一个字节    //        参  数:uchar    //        返回值:uchar    //‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐      uint8 SPI_SendByte(uint8 val)          // uint8= uchar    {              SPI0DAT = val;              while(TXBSY);              return SPI0DAT;    }      //‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐    //        函数名:MMC_SD_SendCmd    //        功  能:发送卡命令    //        参  数:uint8,uint32    //        返回值:uint8    //‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐      uint8 MMC_SD_SendCmd(uint8 Cmd, uint32 arg)    {              uint8 r1;              uint8 retry=0;                          SPI_SendWreit(0xFF);          //发命令前先发送 8 个时钟                          SPI_SendWreit(Cmd | 0x40);          //分别写入命令              SPI_SendWreit(arg>>24);              SPI_SendWreit(arg>>16);              SPI_SendWreit(arg>>8);              SPI_SendWreit(arg);              SPI_SendWreit(0x95);                  //仅本次有效的  CRC值                                  while((r1 = SPI_SendByte(0xFF)) == 0xFF)          //等待响应                      if(retry++ > 8) break;          //超时退出                return r1;          //返回状态值    }      //‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐    //        函数名:MMC_SD_ReadSingleBlock    //        功  能:读一个扇区    //        参  数:扇区,数据缓冲区    //        返回值:    //‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐      uint8 MMC_SD_ReadSingleBlock(uint32 sector,uint8 *buffer)    {              uint8 r1;              uint16 i;                SDCS=0;                  //  使能 Card                r1 = MMC_SD_SendCmd(17, sector<<9);          //  发读扇区命令                          if(r1 != 0x00) return r1;                while(SPI_SendByte(0xFF) != 0xFE);          //‐‐等待数据的起始令牌号‐‐                for(i=0; i<512; i++)          //读 512 个数据              {                      *buffer++ = SPI_SendByte(0xFF);              }                SPI_SendWreit(0xFF);          //  发送伪 CRC              SPI_SendWreit(0xFF);              SDCS=1;                          //  关闭 Card              return 0;    }      //‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐    //        函数名:MMC_SD_WriteSingleBlock    //        功  能:写一个扇区    //        参  数:扇区,数据缓冲区    //        返回值:    //‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐      uint8 MMC_SD_WriteSingleBlock(uint32 sector, uint8 *buffer)    {              uint8 r1;              uint16 i;                SDCS=0;                  //  使能 Card                r1 = MMC_SD_SendCmd(24, sector<<9);          //写命令              if(r1 != 0x00)                      return r1;                SPI_SendWreit(0xFF);              SPI_SendWreit(0xFF);              SPI_SendWreit(0xFF);                SPI_SendWreit(0xFE);          //发送数据起始令牌号                          for(i=0; i<512; i++)          //以扇区为单位写入数据              {                      SPI_SendWreit(*buffer++);              }                          SPI_SendWreit(0xFF);          //  发送伪 CRC              SPI_SendWreit(0xFF);                          r1 = SPI_SendByte(0xFF);          //  读数据应答令牌号                          if( (r1&0x1F) != 0x05)          //等待是否成功              {                      SDCS=1;                      return r1;              }                while(!SPI_SendByte(0xFF));           //‐‐等待操作完成‐‐                SDCS=1;                          //  关闭 Card                return 0;    }      //‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐    //        函数名:MMC_SD_Init    //        功  能:sd 卡初始化    //        参  数:无    //        返回值:uint8 type          //  卡类型返回值: 0x10 SD, 0x20 MMC    //‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐      uint8 MMC_SD_init()    {              uint8 i;              uint8 retry;              uint8 r1=0;              uint8 type=0;          //  卡类型返回值:0xA0 SD 0xB0 MMC              SDCS = 0;                  //  使能 Card                SPI_speed=0x13;          //低速  SPI=300k     Fsystem=12Mhz              retry = 0;                do              {                      for(i=0;i<10;i++) SPI_SendByte(0xFF);     //发送 80 个时钟,使卡同步                      r1 = MMC_SD_SendCmd(0, 0);          //发 Cmd0(复位)命令                      retry++;                      if(retry > 30) return (type=0x01); //超时退出,个别卡需要更多次循环才有反应              } while(r1 != 0x01);                  // MMC、SD 卡成功转到 SPI模式                retry = 0;      //****** SD卡在进入 SPI模式后,激活命令和MMC卡一样为 Cmd1,同时 Cmd55+Cmd41  仍 然有效******//      /*          do              {                      r1 = MMC_SD_SendCmd(1, 0);          //发 Cmd1(active激活)命令                      retry++;                      if(retry > 100) return 1;          //超时退出              } while(r1);*/              do              {                      r1 = MMC_SD_SendCmd(55, 0);          //  先发送  Cmd55                      if(r1 == 0x01)                          //  如果有反应                      {                              r1 = MMC_SD_SendCmd(41,0);          //  再发送  Cmd41  进行激活                              if(r1 == 0x00) type = 0x10;          //  激活成功就是 SD 卡                      }                        else {                                     //  如果发送  Cmd55 无反应,改发送  Cmd1                                      r1 = MMC_SD_SendCmd(1,0);                                      if(r1 == 0x00) type = 0x20;          //  激活成功就是MMC卡                               }                        retry++;                      if(retry > 255) return  (type=0x01);          //  超时退出,  个别卡需要更多次循环才有反 应              } while(r1 != 0x00);                  // MMC、SD 卡激活后的返回值均为 0x00*/      //          SPI_SendByte(0xFF);          //  高速 SPI前先发送 8 个时钟    //          SPI_speed = 0x07;          //  切换到高速  SPI                r1 = MMC_SD_SendCmd(59, 0);          //关 CRC              r1 = MMC_SD_SendCmd(16, 512);          //设置读取一次的字节数                SDCS = 1;                          //  关闭 Card    //          SPI_speed=0x07;          //切换到高速  SPI                return type;          //参数返回,1 为初始化错误,10 为 SD 卡,20 为MMC卡    }      //‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐    //          End of File    //‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐     
/
本文档为【SD卡初始化及读取程序】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索