Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4521017
  • 博文数量: 1148
  • 博客积分: 25453
  • 博客等级: 上将
  • 技术积分: 11949
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-06 21:14
文章分类

全部博文(1148)

文章存档

2012年(15)

2011年(1078)

2010年(58)

分类: 嵌入式

2011-07-02 19:07:50

工程代码: 1_spi_sd卡读写扇区.rar  


一份很到的参考资料:  sd卡 文件系统1.part01.rar  
                      sd卡 文件系统1.part02.rar  
                      sd卡 文件系统1.part03.rar  

一些参考网站资料:
               
               http://www.stmcu.org/WHB565938/blog/11-03/206084_d8262.html
              http://blog.ednchina.com/nthq2004/40017/category.aspx?page=2



注意: 在 spi设置的时候,SCK MOSI MISO 都要设置为 复用 AF 选项, 前几次应该是将MISO设置为 上拉模式,没有设置为 功能复用模式,没有成功。





  1. #ifndef __SD_SPI_H
  2. #define __SD_SPI_H

  3. #include "stm32f10x.h"

  4. /* Private define ------------------------------------------------------------*/
  5. /* SD卡类型定义 */
  6. #define SD_TYPE_MMC 0
  7. #define SD_TYPE_V1 1
  8. #define SD_TYPE_V2 2
  9. #define SD_TYPE_V2HC 4

  10. /* SPI总线速度设置*/
  11. #define SPI_SPEED_LOW 0
  12. #define SPI_SPEED_HIGH 1

  13. /* SD传输数据结束后是否释放总线宏定义 */
  14. #define NO_RELEASE 0
  15. #define RELEASE 1

  16. /* SD卡指令表 */
  17. #define CMD0 0 //卡复位
  18. #define CMD9 9 //命令9 ,读CSD数据
  19. #define CMD10 10 //命令10,读CID数据
  20. #define CMD12 12 //命令12,停止数据传输
  21. #define CMD16 16 //命令16,设置SectorSize 应返回0x00
  22. #define CMD17 17 //命令17,读sector
  23. #define CMD18 18 //命令18,读Multi sector
  24. #define ACMD23 23 //命令23,设置多sector写入前预先擦除N个block
  25. #define CMD24 24 //命令24,写sector
  26. #define CMD25 25 //命令25,写Multi sector
  27. #define ACMD41 41 //命令41,应返回0x00
  28. #define CMD55 55 //命令55,应返回0x01
  29. #define CMD58 58 //命令58,读OCR信息
  30. #define CMD59 59 //命令59,使能/禁止CRC,应返回0x00


  31. /* Private macro -------------------------------------------------------------*/
  32. //SD卡CS片选使能端操作:
  33. #define SD_CS_ENABLE() GPIO_ResetBits(GPIOA,GPIO_Pin_3) //选中SD卡
  34. #define SD_CS_DISABLE() GPIO_SetBits(GPIOA,GPIO_Pin_3) //不选中SD卡

  35. /*板子上没有设置这个管脚,不需要这个功能*/
  36. #if 0
  37. #define SD_PWR_ON() GPIO_ResetBits(GPIOD,GPIO_Pin_10) //SD卡上电
  38. #define SD_PWR_OFF() GPIO_SetBits(GPIOD,GPIO_Pin_10) //SD卡断电
  39. #define SD_DET() !GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_2) //检测有卡
  40.                                                                     //1-有 0-
  41. #endif

  42. /* Private function prototypes -----------------------------------------------*/
  43. void SPI1_Configuration(void);
  44. void SPI_SetSpeed(u8 SpeedSet);

  45. u8 SPI_ReadWriteByte(u8 TxData); //SPI总线读写一个字节
  46. u8 SD_WaitReady(void); //等待SD卡就绪
  47. u8 SD_SendCommand(u8 cmd, u32 arg, u8 crc); //SD卡发送一个命令
  48. u8 SD_SendCommand_NoDeassert(u8 cmd, u32 arg, u8 crc);
  49. u8 SD_Init(void); //SD卡初始化
  50.                                                 //
  51. u8 SD_ReceiveData(u8 *data, u16 len, u8 release);//SD卡读数据
  52. u8 SD_GetCID(u8 *cid_data); //读SD卡CID
  53. u8 SD_GetCSD(u8 *csd_data); //读SD卡CSD
  54. u32 SD_GetCapacity(void); //取SD卡容量

  55. u8 SD_ReadSingleBlock(u32 sector, u8 *buffer); //读一个sector
  56. u8 SD_WriteSingleBlock(u32 sector,const u8 *buffer); //写一个sector
  57. u8 SD_ReadMultiBlock(u32 sector, u8 *buffer, u8 count); //读多个sector
  58. u8 SD_WriteMultiBlock(u32 sector,const u8 *data, u8 count);//写多个sector

  59. #endif

  1. #include "sd_spi.h"

  2. u8 SD_Type=0 ;
  3. /*******************************************************************************
  4. * Function Name : SPI_Configuration
  5. * Description : SPI模块初始化,【包括相关IO口的初始化】
  6. * Input : None
  7. * Output : None
  8. * Return : None
  9. *******************************************************************************/
  10. void SPI1_Configuration(void)
  11. {
  12.     SPI_InitTypeDef SPI_InitStructure ;
  13.     GPIO_InitTypeDef GPIO_InitStructure ;
  14.     //启动SPI时钟
  15.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1,ENABLE);
  16.     
  17.     //////下面是SPI相关GPIO初始化//////
  18.     //SPI1模块对应的SCK、MISO、MOSI为AF引脚
  19.     GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7 ;
  20.     GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz ;
  21.     GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP ;//复用模式
  22.     GPIO_Init(GPIOA,&GPIO_InitStructure);
  23.     
  24.     //PA3 pin: CS
  25.     GPIO_InitStructure.GPIO_Pin=GPIO_Pin_3 ;
  26.     GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz ;
  27.     GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP ;
  28.     GPIO_Init(GPIOA,&GPIO_InitStructure);
  29.     
  30.     //////SPI模块配置//////
  31.     //一开始SD初始化阶段,SPI时钟频率必须<400K
  32.     SPI_InitStructure.SPI_Direction=SPI_Direction_2Lines_FullDuplex ;
  33.     SPI_InitStructure.SPI_Mode=SPI_Mode_Master ;
  34.     SPI_InitStructure.SPI_DataSize=SPI_DataSize_8b ;
  35.     SPI_InitStructure.SPI_CPOL=SPI_CPOL_High ;
  36.     SPI_InitStructure.SPI_CPHA=SPI_CPHA_2Edge ;
  37.     SPI_InitStructure.SPI_NSS=SPI_NSS_Soft ; //软件控制
  38.     SPI_InitStructure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_256 ;
  39.     SPI_InitStructure.SPI_FirstBit=SPI_FirstBit_MSB ;
  40.     SPI_InitStructure.SPI_CRCPolynomial=7 ;
  41.     SPI_Init(SPI1,&SPI_InitStructure);
  42.     
  43.     SPI_Cmd(SPI1,ENABLE);
  44.   // return 0 ;
  45. }

  46. /*******************************************************************************
  47. * Function Name : SPI_SetSpeed
  48. * Description : SPI设置速度为高速
  49. * Input : u8 SpeedSet
  50. * 如果速度设置输入0,则低速模式,非0则高速模式
  51. * SPI_SPEED_HIGH 1
  52. * SPI_SPEED_LOW 0
  53. * Output : None
  54. * Return : None
  55. *******************************************************************************/
  56. void SPI_SetSpeed(u8 SpeedSet)
  57. {
  58.     SPI_InitTypeDef SPI_InitStructure ;
  59.     
  60.     SPI_InitStructure.SPI_Direction=SPI_Direction_2Lines_FullDuplex ;
  61.     SPI_InitStructure.SPI_Mode=SPI_Mode_Master ;
  62.     SPI_InitStructure.SPI_DataSize=SPI_DataSize_8b ;
  63.     SPI_InitStructure.SPI_CPOL=SPI_CPOL_High ;
  64.     SPI_InitStructure.SPI_CPHA=SPI_CPHA_2Edge ;
  65.     SPI_InitStructure.SPI_NSS=SPI_NSS_Soft ;
  66.     //如果速度设置输入0,则低速模式,非0则高速模式
  67.     if(SpeedSet==SPI_SPEED_LOW)
  68.     {
  69.         SPI_InitStructure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_256 ;
  70.     }
  71.     else
  72.     {
  73.         SPI_InitStructure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_4;
  74.     }
  75.     //moon.mp3: 4707774 Byte size 目标文件 设为buffer[512]
  76.     //speed:实验测试数据,最大速度 392314 Byte/S,
  77.     //Prescaler_128, 59592 Byte/S
  78.     //Prescaler_64, 104617 Byte/S
  79.     //Prescaler_32, 168134 Byte/S 162337 Byte/S
  80.     //Prescaler_16, 261543 Byte/S 247777 Byte/S
  81.     //Prescaler_8, 313851 Byte/S 336269 Byte/S
  82.     //Prescaler_4, 392314 Byte/S 392314 Byte/S
  83.     //Prescaler_2, 392314 Byte/S

  84.     SPI_InitStructure.SPI_FirstBit=SPI_FirstBit_MSB ;
  85.     SPI_InitStructure.SPI_CRCPolynomial=7 ;
  86.     SPI_Init(SPI1,&SPI_InitStructure);
  87.     return ;
  88. }

  89. /*******************************************************************************
  90. * Function Name : SPI_ReadWriteByte
  91. * Description : SPI读写一个字节(发送完成后返回本次通讯读取的数据)
  92. * Input : u8 TxData 待发送的数
  93. * Output : None
  94. * Return : u8 RxData 收到的数
  95. *******************************************************************************/
  96. u8 SPI_ReadWriteByte(u8 TxData)
  97. {
  98.     u8 RxData=0 ;
  99.     
  100.     //GPIO_WriteBit(GPIOC, GPIO_Pin_7, Bit_SET); //读文件闪烁
  101.     
  102.     //等待发送缓冲区空
  103.     while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET);
  104.     //发一个字节
  105.     SPI_I2S_SendData(SPI1,TxData);
  106.     
  107.     //等待数据接收
  108.     while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE)==RESET);
  109.     //取数据
  110.     RxData=SPI_I2S_ReceiveData(SPI1);
  111.     
  112.     //GPIO_WriteBit(GPIOC, GPIO_Pin_7, Bit_RESET);

  113.     return RxData ;
  114. }

  115. /*******************************************************************************
  116. * Function Name : SD_WaitReady
  117. * Description : 等待SD卡Ready
  118. * Input : None
  119. * Output : None
  120. * Return : u8
  121. * 0: 成功
  122. * other:失败
  123. *******************************************************************************/
  124. u8 SD_WaitReady(void)
  125. {
  126.     u8 r1 ;
  127.     u16 retry ;
  128.     retry=0 ;
  129.     do
  130.     {
  131.         r1=SPI_ReadWriteByte(0xFF);
  132.         if(retry==0xfffe)//????如果卡异常,会死循坏!
  133.         {
  134.             return 1 ;
  135.         }
  136.     }
  137.     while(r1!=0xFF);
  138.     
  139.     return 0 ;
  140. }

  141. /*******************************************************************************
  142. * Function Name : SD_SendCommand
  143. * Description : 向SD卡发送一个命令
  144. * Input : u8 cmd 命令
  145. * u32 arg 命令参数
  146. * u8 crc crc校验值
  147. * Output : None
  148. * Return : u8 r1 SD卡返回的响应
  149. *******************************************************************************/
  150. u8 SD_SendCommand(u8 cmd,u32 arg,u8 crc)
  151. {
  152.     unsigned char r1 ;
  153.     unsigned char Retry=0 ;
  154.     
  155.     //????????
  156.     SPI_ReadWriteByte(0xff);
  157.     //片选端置低,选中SD卡
  158.     SD_CS_ENABLE();
  159.     
  160.     //发送
  161.     SPI_ReadWriteByte(cmd|0x40);
  162.     //分别写入命令
  163.     SPI_ReadWriteByte(arg>>24);
  164.     SPI_ReadWriteByte(arg>>16);
  165.     SPI_ReadWriteByte(arg>>8);
  166.     SPI_ReadWriteByte(arg);
  167.     SPI_ReadWriteByte(crc);
  168.     
  169.     //等待响应,或超时退出
  170.     while((r1=SPI_ReadWriteByte(0xFF))==0xFF)
  171.     {
  172.         Retry++;
  173.         if(Retry>200)
  174.         {
  175.             break ;
  176.         }
  177.     }
  178.     
  179.     
  180.     //关闭片选
  181.     SD_CS_DISABLE();
  182.     //在总线上额外增加8个时钟,让SD卡完成剩下的工作
  183.     SPI_ReadWriteByte(0xFF);
  184.     
  185.     //返回状态值
  186.     return r1 ;
  187. }


  188. /*******************************************************************************
  189. * Function Name : SD_SendCommand_NoDeassert
  190. * Description : 向SD卡发送一个命令(结束是不失能片选,还有后续数据传来)
  191. * Input : u8 cmd 命令
  192. * u32 arg 命令参数
  193. * u8 crc crc校验值
  194. * Output : None
  195. * Return : u8 r1 SD卡返回的响应
  196. *******************************************************************************/
  197. u8 SD_SendCommand_NoDeassert(u8 cmd,u32 arg,u8 crc)
  198. {
  199.     unsigned char r1 ;
  200.     unsigned char Retry=0 ;
  201.     
  202.     //????????
  203.     SPI_ReadWriteByte(0xff);
  204.     //片选端置低,选中SD卡
  205.     SD_CS_ENABLE();
  206.     
  207.     //发送
  208.     SPI_ReadWriteByte(cmd|0x40);
  209.     //分别写入命令
  210.     SPI_ReadWriteByte(arg>>24);
  211.     SPI_ReadWriteByte(arg>>16);
  212.     SPI_ReadWriteByte(arg>>8);
  213.     SPI_ReadWriteByte(arg);
  214.     SPI_ReadWriteByte(crc);
  215.     
  216.     //等待响应,或超时退出
  217.     while((r1=SPI_ReadWriteByte(0xFF))==0xFF)
  218.     {
  219.         Retry++;
  220.         if(Retry>200)
  221.         {
  222.             break ;
  223.         }
  224.     }
  225.     //返回响应值
  226.     return r1 ;
  227. }

  228. /*******************************************************************************
  229. * Function Name : SD_Init
  230. * Description : 初始化SD卡
  231. * Input : None
  232. * Output : None
  233. * Return : u8
  234. * 0:NO_ERR
  235. * 1:TIME_OUT
  236. * 99:NO_CARD
  237. *******************************************************************************/
  238. u8 SD_Init(void)
  239. {
  240.     u16 i ;
  241.     // 用来循环计数
  242.     u8 r1 ;
  243.     // 存放SD卡的返回值
  244.     u16 retry ;
  245.     // 用来进行超时计数
  246.     u8 buff[6];
  247.     
  248.     //如果没有检测到卡插入,直接退出,返回错误标志
  249. #if 0
  250.     if(!SD_DET())
  251.     {
  252.         //return 99;
  253.         return STA_NODISK ;
  254.         // FatFS错误标志:没有插入磁盘
  255.     }
  256.     
  257.     //SD卡上电
  258.     SD_PWR_ON();
  259.     // 纯延时,等待SD卡上电完成
  260.     for(i=0;i<0xf00;i++);
  261. #endif
  262.     //先产生>74个脉冲,让SD卡自己初始化完成
  263.     for(i=0;i<10;i++)
  264.     {
  265.         SPI_ReadWriteByte(0xFF);
  266.     }
  267.     
  268.     //-----------------SD卡复位到idle开始-----------------
  269.     //循环连续发送CMD0,直到SD卡返回0x01,进入IDLE状态
  270.     //超时则直接退出
  271.     retry=0 ;
  272.     do
  273.     {
  274.         //发送CMD0,让SD卡进入IDLE状态
  275.         r1=SD_SendCommand(CMD0,0,0x95);
  276.         retry++;
  277.     }
  278.     while((r1!=0x01)&&(retry<200));
  279.     //跳出循环后,检查原因:初始化成功?or 重试超时?
  280.     if(retry==200)
  281.     {
  282.         return 1 ;
  283.         //超时返回1
  284.     }
  285.     //-----------------SD卡复位到idle结束-----------------
  286.     

  287.     //获取卡片的SD版本信息
  288.     r1=SD_SendCommand_NoDeassert(8,0x1aa,0x87);
  289.     
  290.     //如果卡片版本信息是v1.0版本的,即r1=0x05,则进行以下初始化
  291.     if(r1==0x05)
  292.     {
  293.         //设置卡类型为SDV1.0,如果后面检测到为MMC卡,再修改为MMC
  294.         SD_Type=SD_TYPE_V1 ;
  295.         
  296.         //如果是V1.0卡,CMD8指令后没有后续数据
  297.         //片选置高,结束本次命令
  298.         SD_CS_DISABLE();
  299.         //多发8个CLK,让SD结束后续操作
  300.         SPI_ReadWriteByte(0xFF);
  301.         
  302.         //-----------------SD卡、MMC卡初始化开始-----------------
  303.         
  304.         //发卡初始化指令CMD55+ACMD41
  305.         // 如果有应答,说明是SD卡,且初始化完成
  306.         // 没有回应,说明是MMC卡,额外进行相应初始化
  307.         retry=0 ;
  308.         do
  309.         {
  310.             //先发CMD55,应返回0x01;否则出错
  311.             r1=SD_SendCommand(CMD55,0,0);
  312.             if(r1!=0x01)
  313.             {
  314.                 return r1 ;
  315.             }
  316.             //得到正确响应后,发ACMD41,应得到返回值0x00,否则重试200次
  317.             r1=SD_SendCommand(ACMD41,0,0);
  318.             retry++;
  319.         }
  320.         while((r1!=0x00)&&(retry<400));
  321.         // 判断是超时还是得到正确回应
  322.         // 若有回应:是SD卡;没有回应:是MMC卡
  323.         
  324.         //----------MMC卡额外初始化操作开始------------
  325.         if(retry==400)
  326.         {
  327.             retry=0 ;
  328.             //发送MMC卡初始化命令(没有测试)
  329.             do
  330.             {
  331.                 r1=SD_SendCommand(1,0,0);
  332.                 retry++;
  333.             }
  334.             while((r1!=0x00)&&(retry<400));
  335.             if(retry==400)
  336.             {
  337.                 return 1 ;
  338.                 //MMC卡初始化超时
  339.             }
  340.             //写入卡类型
  341.             SD_Type=SD_TYPE_MMC ;
  342.         }
  343.         //----------MMC卡额外初始化操作结束------------
  344.         
  345.         //设置SPI为高速模式
  346.         SPI_SetSpeed(1);
  347.         
  348.         SPI_ReadWriteByte(0xFF);
  349.         
  350.         //禁止CRC校验
  351.         /*
  352.                 r1 = SD_SendCommand(CMD59, 0, 0x01);
  353.                 if(r1 != 0x00)
  354.                 {
  355.                     return r1; //命令错误,返回r1
  356.                 }
  357.                 */
  358.         //设置Sector Size
  359.         r1=SD_SendCommand(CMD16,512,0xff);
  360.         if(r1!=0x00)
  361.         {
  362.             return r1 ;
  363.             //命令错误,返回r1
  364.         }
  365.         //-----------------SD卡、MMC卡初始化结束-----------------
  366.         
  367.     }
  368.     //SD卡为V1.0版本的初始化结束
  369.     
  370.     
  371.     //下面是V2.0卡的初始化
  372.     //其中需要读取OCR数据,判断是SD2.0还是SD2.0HC卡
  373.     else if(r1==0x01)
  374.     {
  375.         //V2.0的卡,CMD8命令后会传回4字节的数据,要跳过再结束本命令
  376.         buff[0]=SPI_ReadWriteByte(0xFF);
  377.         //should be 0x00
  378.         buff[1]=SPI_ReadWriteByte(0xFF);
  379.         //should be 0x00
  380.         buff[2]=SPI_ReadWriteByte(0xFF);
  381.         //should be 0x01
  382.         buff[3]=SPI_ReadWriteByte(0xFF);
  383.         //should be 0xAA
  384.         
  385.         SD_CS_DISABLE();
  386.         //the next 8 clocks
  387.         SPI_ReadWriteByte(0xFF);
  388.         
  389.         //判断该卡是否支持2.7V-3.6V的电压范围
  390.         if(buff[2]==0x01&&buff[3]==0xAA)
  391.         {
  392.             //支持电压范围,可以操作
  393.             retry=0 ;
  394.             //发卡初始化指令CMD55+ACMD41
  395.             do
  396.             {
  397.                 r1=SD_SendCommand(CMD55,0,0);
  398.                 if(r1!=0x01)
  399.                 {
  400.                     return r1 ;
  401.                 }
  402.                 r1=SD_SendCommand(ACMD41,0x40000000,0);
  403.                 if(retry>200)
  404.                 {
  405.                     return r1 ;
  406.                     //超时则返回r1状态
  407.                 }
  408.             }
  409.             while(r1!=0);
  410.             
  411.             //初始化指令发送完成,接下来获取OCR信息
  412.             
  413.             //-----------鉴别SD2.0卡版本开始-----------
  414.             r1=SD_SendCommand_NoDeassert(CMD58,0,0);
  415.             if(r1!=0x00)
  416.             {
  417.                 return r1 ;
  418.                 //如果命令没有返回正确应答,直接退出,返回应答
  419.             }
  420.             //读OCR指令发出后,紧接着是4字节的OCR信息
  421.             buff[0]=SPI_ReadWriteByte(0xFF);
  422.             buff[1]=SPI_ReadWriteByte(0xFF);
  423.             buff[2]=SPI_ReadWriteByte(0xFF);
  424.             buff[3]=SPI_ReadWriteByte(0xFF);
  425.             
  426.             //OCR接收完成,片选置高
  427.             SD_CS_DISABLE();
  428.             SPI_ReadWriteByte(0xFF);
  429.             
  430.             //检查接收到的OCR中的bit30位(CCS),确定其为SD2.0还是SDHC
  431.             //如果CCS=1:SDHC CCS=0:SD2.0
  432.             //检查CCS
  433.             if(buff[0]&0x40)
  434.             {
  435.                 SD_Type=SD_TYPE_V2HC ;
  436.             }
  437.             else
  438.             {
  439.                 SD_Type=SD_TYPE_V2 ;
  440.             }
  441.             //-----------鉴别SD2.0卡版本结束-----------
  442.             
  443.             
  444.             //设置SPI为高速模式
  445.             SPI_SetSpeed(1);
  446.         }
  447.         
  448.     }
  449.     return r1 ;
  450. }


  451. /*******************************************************************************
  452. * Function Name : SD_ReceiveData
  453. * Description : 从SD卡中读回指定长度的数据,放置在给定位置
  454. * Input : u8 *data(存放读回数据的内存>len)
  455. * u16 len(数据长度)
  456. * u8 release(传输完成后是否释放总线CS置高 0:不释放 1:释放)
  457. * Output : None
  458. * Return : u8
  459. * 0:NO_ERR
  460. * other:错误信息
  461. *******************************************************************************/
  462. u8 SD_ReceiveData(u8*data,u16 len,u8 release)
  463. {
  464.     u16 retry ;
  465.     u8 r1 ;
  466.     
  467.     // 启动一次传输
  468.     SD_CS_ENABLE();
  469.     //等待SD卡发回数据起始令牌0xFE
  470.     retry=0 ;
  471.     do
  472.     {
  473.         r1=SPI_ReadWriteByte(0xFF);
  474.         retry++;
  475.         //2000次等待后没有应答,退出报错
  476.         if(retry>2000)
  477.         {
  478.             SD_CS_DISABLE();
  479.             return 1 ;
  480.         }
  481.     }
  482.     while(r1!=0xFE);
  483.     //开始接收数据
  484.     while(len--)
  485.     {
  486.         *data=SPI_ReadWriteByte(0xFF);
  487.         data++;
  488.     }
  489.     //下面是2个伪CRC(dummy CRC)
  490.     SPI_ReadWriteByte(0xFF);
  491.     SPI_ReadWriteByte(0xFF);
  492.     //按需释放总线,将CS置高
  493.     if(release==RELEASE)
  494.     {
  495.         //传输结束
  496.         SD_CS_DISABLE();
  497.         SPI_ReadWriteByte(0xFF);
  498.     }
  499.     
  500.     return 0 ;
  501. }

  502. /*******************************************************************************
  503. * Function Name : SD_GetCID
  504. * Description : 获取SD卡的CID信息,包括制造商信息
  505. * Input : u8 *cid_data(存放CID的内存,至少16Byte)
  506. * Output : None
  507. * Return : u8
  508. * 0:NO_ERR
  509. * 1:TIME_OUT
  510. * other:错误信息
  511. *******************************************************************************/
  512. u8 SD_GetCID(u8*cid_data)
  513. {
  514.     u8 r1 ;
  515.     
  516.     //发CMD10命令,读CID
  517.     r1=SD_SendCommand(CMD10,0,0xFF);
  518.     if(r1!=0x00)
  519.     {
  520.         return r1 ;
  521.         //没返回正确应答,则退出,报错
  522.     }
  523.     //接收16个字节的数据
  524.     SD_ReceiveData(cid_data,16,RELEASE);
  525.     
  526.     return 0 ;
  527. }


  528. /*******************************************************************************
  529. * Function Name : SD_GetCSD
  530. * Description : 获取SD卡的CSD信息,包括容量和速度信息
  531. * Input : u8 *cid_data(存放CID的内存,至少16Byte)
  532. * Output : None
  533. * Return : u8
  534. * 0:NO_ERR
  535. * 1:TIME_OUT
  536. * other:错误信息
  537. *******************************************************************************/
  538. u8 SD_GetCSD(u8 *csd_data)
  539. {
  540.     u8 r1 ;
  541.     
  542.     //发CMD9命令,读CSD
  543.     r1=SD_SendCommand(CMD9,0,0xFF);
  544.     if(r1!=0x00)
  545.     {
  546.         return r1 ;
  547.         //没返回正确应答,则退出,报错
  548.     }
  549.     //接收16个字节的数据
  550.     SD_ReceiveData(csd_data,16,RELEASE);
  551.     
  552.     return 0 ;
  553. }

  554. /*******************************************************************************
  555. * Function Name : SD_GetCapacity
  556. * Description : 获取SD卡的容量
  557. * Input : None
  558. * Output : None
  559. * Return : u32 capacity
  560. * 0: 取容量出错
  561. *******************************************************************************/
  562. u32 SD_GetCapacity(void)
  563. {
  564.     u8 csd[16];
  565.     u32 Capacity ;
  566.     u8 r1 ;
  567.     u16 i ;
  568.     u16 temp ;
  569.     
  570.     //取CSD信息,如果期间出错,返回0
  571.     if(SD_GetCSD(csd)!=0)
  572.     {
  573.         return 0 ;
  574.     }
  575.     
  576.     //如果为SDHC卡,按照下面方式计算
  577.     if((csd[0]&0xC0)==0x40)
  578.     {
  579.         Capacity=(((u32)csd[8])<<8+(u32)csd[9]+1)*(u32)1024 ;
  580.     }
  581.     else
  582.     {
  583.         //下面代码为网上版本
  584.         ////////////formula of the capacity///////////////
  585.         //
  586.         // memory capacity = BLOCKNR * BLOCK_LEN
  587.         //
  588.         //    BLOCKNR = (C_SIZE + 1)* MULT
  589.         //
  590.         // C_SIZE_MULT+2
  591.         //    MULT = 2
  592.         //
  593.         // READ_BL_LEN
  594.         //    BLOCK_LEN = 2
  595.         /**********************************************/
  596.         //C_SIZE
  597.         i=csd[6]&0x03 ;
  598.         i<<=8 ;
  599.         i+=csd[7];
  600.         i<<=2 ;
  601.         i+=((csd[8]&0xc0)>>6);
  602.         
  603.         //C_SIZE_MULT
  604.         r1=csd[9]&0x03 ;
  605.         r1<<=1 ;
  606.         r1+=((csd[10]&0x80)>>7);
  607.         
  608.         //BLOCKNR
  609.         r1+=2 ;
  610.         temp=1 ;
  611.         while(r1)
  612.         {
  613.             temp*=2 ;
  614.             r1--;
  615.         }
  616.         Capacity=((u32)(i+1))*((u32)temp);
  617.         
  618.         // READ_BL_LEN
  619.         i=csd[5]&0x0f ;
  620.         //BLOCK_LEN
  621.         temp=1 ;
  622.         while(i)
  623.         {
  624.             temp*=2 ;
  625.             i--;
  626.         }
  627.         //The final result
  628.         Capacity*=(u32)temp ;
  629.         //Capacity /= 512;
  630.     }
  631.     return (u32)Capacity ;
  632. }


  633. /*******************************************************************************
  634. * Function Name : SD_ReadSingleBlock
  635. * Description : 读SD卡的一个block
  636. * Input : u32 sector 取地址(sector值,非物理地址)
  637. * u8 *buffer 数据存储地址(大小至少512byte)
  638. * Output : None
  639. * Return : u8 r1
  640. * 0: 成功
  641. * other:失败
  642. *******************************************************************************/
  643. u8 SD_ReadSingleBlock(u32 sector,u8*buffer)
  644. {
  645.     u8 r1 ;
  646.     
  647.     //设置为高速模式
  648.     SPI_SetSpeed(SPI_SPEED_HIGH);
  649.     
  650.     //如果不是SDHC,将sector地址转成byte地址
  651.     sector=sector<<9 ;
  652.     
  653.     r1=SD_SendCommand(CMD17,sector,0);
  654.     //读命令
  655.     
  656.     if(r1!=0x00)
  657.     {
  658.         return r1 ;
  659.     }
  660.     
  661.     r1=SD_ReceiveData(buffer,512,RELEASE);
  662.     if(r1!=0)
  663.     {
  664.         return r1 ;
  665.         //读数据出错!
  666.     }
  667.     else
  668.     {
  669.         return 0 ;
  670.     }
  671. }

  672. /*******************************************************************************
  673. * Function Name : SD_WriteSingleBlock
  674. * Description : 写入SD卡的一个block
  675. * Input : u32 sector 扇区地址(sector值,非物理地址)
  676. * u8 *buffer 数据存储地址(大小至少512byte)
  677. * Output : None
  678. * Return : u8 r1
  679. * 0: 成功
  680. * other:失败
  681. *******************************************************************************/
  682. u8 SD_WriteSingleBlock(u32 sector,const u8 *data)
  683. {
  684.     u8 r1 ;
  685.     u16 i ;
  686.     u16 retry ;
  687.     
  688.     //设置为高速模式
  689.     SPI_SetSpeed(SPI_SPEED_HIGH);
  690.     
  691.     //如果不是SDHC,给定的是sector地址,将其转换成byte地址
  692.     if(SD_Type!=SD_TYPE_V2HC)
  693.     {
  694.         sector=sector<<9 ;
  695.     }
  696.     
  697.     r1=SD_SendCommand(CMD24,sector,0x00);
  698.     if(r1!=0x00)
  699.     {
  700.         return r1 ;
  701.         //应答不正确,直接返回
  702.     }
  703.     
  704.     //开始准备数据传输
  705.     SD_CS_ENABLE();
  706.     //先放3个空数据,等待SD卡准备好
  707.     SPI_ReadWriteByte(0xff);
  708.     SPI_ReadWriteByte(0xff);
  709.     SPI_ReadWriteByte(0xff);
  710.     //放起始令牌0xFE
  711.     SPI_ReadWriteByte(0xFE);
  712.     
  713.     //放一个sector的数据
  714.     for(i=0;i<512;i++)
  715.     {
  716.         SPI_ReadWriteByte(*data++);
  717.     }
  718.     //发2个Byte的dummy CRC
  719.     SPI_ReadWriteByte(0xff);
  720.     SPI_ReadWriteByte(0xff);
  721.     
  722.     //等待SD卡应答
  723.     r1=SPI_ReadWriteByte(0xff);
  724.     if((r1&0x1F)!=0x05)
  725.     {
  726.         SD_CS_DISABLE();
  727.         return r1 ;
  728.     }
  729.     
  730.     //等待操作完成
  731.     retry=0 ;
  732.     while(!SPI_ReadWriteByte(0xff))
  733.     {
  734.         retry++;
  735.         //如果长时间写入没有完成,报错退出
  736.         if(retry>0xfffe)
  737.         {
  738.             SD_CS_DISABLE();
  739.             return 1 ;
  740.             //写入超时返回1
  741.         }
  742.     }
  743.     
  744.     //写入完成,片选置1
  745.     SD_CS_DISABLE();
  746.     SPI_ReadWriteByte(0xff);
  747.     
  748.     return 0 ;
  749. }


  750. /*******************************************************************************
  751. * Function Name : SD_ReadMultiBlock
  752. * Description : 读SD卡的多个block
  753. * Input : u32 sector 取地址(sector值,非物理地址)
  754. * u8 *buffer 数据存储地址(大小至少512byte)
  755. * u8 count 连续读count个block
  756. * Output : None
  757. * Return : u8 r1
  758. * 0: 成功
  759. * other:失败
  760. *******************************************************************************/
  761. u8 SD_ReadMultiBlock(u32 sector,u8 *buffer,u8 count)
  762. {
  763.     u8 r1 ;
  764.     
  765.     //设置为高速模式
  766.     SPI_SetSpeed(SPI_SPEED_HIGH);
  767.     
  768.     //如果不是SDHC,将sector地址转成byte地址
  769.     sector=sector<<9 ;
  770.     //SD_WaitReady();
  771.     //发读多块命令
  772.     r1=SD_SendCommand(CMD18,sector,0);
  773.     //读命令
  774.     if(r1!=0x00)
  775.     {
  776.         return r1 ;
  777.     }
  778.     //开始接收数据
  779.     do
  780.     {
  781.         if(SD_ReceiveData(buffer,512,NO_RELEASE)!=0x00)
  782.         {
  783.             break ;
  784.         }
  785.         buffer+=512 ;
  786.     }
  787.     while(--count);
  788.     
  789.     //全部传输完毕,发送停止命令
  790.     SD_SendCommand(CMD12,0,0);
  791.     //释放总线
  792.     SD_CS_DISABLE();
  793.     SPI_ReadWriteByte(0xFF);
  794.     
  795.     if(count!=0)
  796.     {
  797.         return count ;
  798.         //如果没有传完,返回剩余个数
  799.     }
  800.     else
  801.     {
  802.         return 0 ;
  803.     }
  804. }


  805. /*******************************************************************************
  806. * Function Name : SD_WriteMultiBlock
  807. * Description : 写入SD卡的N个block
  808. * Input : u32 sector 扇区地址(sector值,非物理地址)
  809. * u8 *buffer 数据存储地址(大小至少512byte)
  810. * u8 count 写入的block数目
  811. * Output : None
  812. * Return : u8 r1
  813. * 0: 成功
  814. * other:失败
  815. *******************************************************************************/
  816. u8 SD_WriteMultiBlock(u32 sector,const u8*data,u8 count)
  817. {
  818.     u8 r1 ;
  819.     u16 i ;
  820.     
  821.     //设置为高速模式
  822.     SPI_SetSpeed(SPI_SPEED_HIGH);
  823.     
  824.     //如果不是SDHC,给定的是sector地址,将其转换成byte地址
  825.     if(SD_Type!=SD_TYPE_V2HC)
  826.     {
  827.         sector=sector<<9 ;
  828.     }
  829.     //如果目标卡不是MMC卡,启用ACMD23指令使能预擦除
  830.     if(SD_Type!=SD_TYPE_MMC)
  831.     {
  832.         r1=SD_SendCommand(ACMD23,count,0x00);
  833.     }
  834.     //发多块写入指令
  835.     r1=SD_SendCommand(CMD25,sector,0x00);
  836.     if(r1!=0x00)
  837.     {
  838.         return r1 ;
  839.         //应答不正确,直接返回
  840.     }
  841.     
  842.     //开始准备数据传输
  843.     SD_CS_ENABLE();
  844.     //先放3个空数据,等待SD卡准备好
  845.     SPI_ReadWriteByte(0xff);
  846.     SPI_ReadWriteByte(0xff);
  847.     
  848.     //--------下面是N个sector写入的循环部分
  849.     do
  850.     {
  851.         //放起始令牌0xFC 表明是多块写入
  852.         SPI_ReadWriteByte(0xFC);
  853.         
  854.         //放一个sector的数据
  855.         for(i=0;i<512;i++)
  856.         {
  857.             SPI_ReadWriteByte(*data++);
  858.         }
  859.         //发2个Byte的dummy CRC
  860.         SPI_ReadWriteByte(0xff);
  861.         SPI_ReadWriteByte(0xff);
  862.         
  863.         //等待SD卡应答
  864.         r1=SPI_ReadWriteByte(0xff);
  865.         if((r1&0x1F)!=0x05)
  866.         {
  867.             SD_CS_DISABLE();
  868.             //如果应答为报错,则带错误代码直接退出
  869.             return r1 ;
  870.         }
  871.         
  872.         //等待SD卡写入完成
  873.         if(SD_WaitReady()==1)
  874.         {
  875.             SD_CS_DISABLE();
  876.             //等待SD卡写入完成超时,直接退出报错
  877.             return 1 ;
  878.         }
  879.         
  880.         //本sector数据传输完成
  881.     }
  882.     while(--count);
  883.     
  884.     //发结束传输令牌0xFD
  885.     r1=SPI_ReadWriteByte(0xFD);
  886.     if(r1==0x00)
  887.     {
  888.         count=0xfe ;
  889.     }
  890.     
  891.     if(SD_WaitReady())
  892.     {
  893.         while(1){}
  894.     }
  895.     
  896.     //写入完成,片选置1
  897.     SD_CS_DISABLE();
  898.     SPI_ReadWriteByte(0xff);
  899.     
  900.     return count ;
  901.     //返回count值,如果写完则count=0,否则count=1
  902. }
  903. #if 0
  904. u8 SD_GPIO_SPI_Init(void)
  905. {
  906.     u16 i = 0;
  907.      u8 response = 0;
  908.     GPIO_InitTypeDef GPIO_InitStructure;

  909.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//SPI1 管脚
  910.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); //时钟使能
  911.     //设置 SCK MOSI 模式
  912.     GPIO_InitStructure.GPIO_Pin = SPI1_PIN_SCK | SPI1_PIN_MOSI;    // SCK MOSI 输出模式
  913.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  914.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    //复用功能
  915.     GPIO_Init(SPI1_GPIO, &GPIO_InitStructure);    //初始化 SCK MOSI 管脚

  916.     GPIO_InitStructure.GPIO_Pin = SPI1_PIN_MISO;//MISO 输入模式
  917.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉输入    
  918.     GPIO_Init(SPI1_GPIO, &GPIO_InitStructure); //初始化 MISO 管脚

  919.     GPIO_InitStructure.GPIO_Pin = SD_CS_Pin;//CS输出模式
  920.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推拉输出    
  921.     GPIO_Init(SD_CS_GPIO, &GPIO_InitStructure); //初始化 SD_CS 管脚
  922. //////////////////////////////////////////////////////////////////////////////
  923.       SD_SPI_Low_Speed();//低速启动
  924.     for(i = 0; i < 10; ++i)    //需要74个周期, 我们提供了80个周期
  925.     {
  926.         SD_SPI_Write_Byte(0xff);
  927.     }

  928.     SD_SPI_SELECT();/* address card 片选 SD*/

  929.     for(i = 0; ; ++i)//复位SD卡
  930.     {
  931.         response = SD_Send_Command(CMD_GO_IDLE_STATE, 0 );
  932.         if(response == 0x01)
  933.             break;

  934.         if(i == 0x1ff) //复位次数到,返回1
  935.         {
  936.             SD_SPI_DESELECT();
  937.             return 1;
  938.         }
  939.     }
  940.     
  941.     for(i = 0; ; ++i) //等待SD准备好
  942.     {
  943.         response = SD_Send_Command(CMD_SEND_OP_COND, 0);
  944.         if(!(response & (1 << R1_IDLE_STATE)))
  945.             break;

  946.         if(i == 0x7fff)
  947.         {
  948.             SD_SPI_DESELECT();
  949.             return 1;
  950.         }
  951.     }

  952.     if(SD_Send_Command(CMD_SET_BLOCKLEN, 512))//设置块大小512字节
  953.     {
  954.         SD_SPI_DESELECT();
  955.         return 1;
  956.     }

  957.     SD_SPI_DESELECT(); //片选 取消

  958.  // SD_MMC_High_Speed();//转换到高速模式
  959.     SD_SPI_High_Speed();
  960.     return 0;
  961. }

  962. void SD_SPI_Low_Speed(void)
  963. {
  964.         SPI_InitTypeDef SPI_InitStructure;
  965.         /* SPI1 configuration */
  966.         SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //全双工模式
  967.         SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //配置为主机
  968.         SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;//8位数据帧
  969.         SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;    //空闲时 为低电平
  970.         SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //数据在第二个边沿捕获
  971.         SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //内部NSS信号由SSI控制
  972.         SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;//预分频256
  973.         SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //高位在前
  974.         SPI_InitStructure.SPI_CRCPolynomial = 7; //用于计算CRC

  975.         SPI_Init(SPI1, &SPI_InitStructure);    //初始化 SPI1

  976.         /* SPI1 enable */
  977.         SPI_Cmd(SPI1, ENABLE);
  978. }

  979. void SD_SPI_High_Speed(void)
  980. {
  981.         SPI_InitTypeDef SPI_InitStructure;
  982.         /* SPI1 configuration */
  983.         SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  984.         SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
  985.         SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
  986.         SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
  987.         SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
  988.         SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
  989.         SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;//预分频
  990.         SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  991.         SPI_InitStructure.SPI_CRCPolynomial = 7;

  992.         SPI_Init(SPI1, &SPI_InitStructure);

  993.         /* SPI1 enable */
  994.         SPI_Cmd(SPI1, ENABLE);
  995. }

  996. void SD_SPI_Write_Byte(u8 byte)//主设备 写数据到 从设备
  997. {
  998.     while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
  999.     SPI_I2S_SendData(SPI1, byte);
  1000.     //每次发送数据时,收到的数据时没有用的话要舍弃,但是要清除RXNE位
  1001.     while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
  1002.     SPI_I2S_ReceiveData(SPI1);
  1003. }

  1004. //主设备 读取数据 from 从设备
  1005. u8 SD_SPI_Read_Byte(void)
  1006. {
  1007.  //每次要收取数据时,先要发送一个字节,主要是输出时钟
  1008.   while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
  1009.   SPI_I2S_SendData(SPI1, 0xff);
  1010.   while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
  1011.   return SPI_I2S_ReceiveData(SPI1);
  1012. }

  1013. /* 读写一起
  1014. u8 SPI_Send_Byte(u8 byte)
  1015. {
  1016.  
  1017.   while(SPI_GetFlagStatus(SPI2, SPI_FLAG_TXE) == RESET);

  1018.  
  1019.   SPI_SendData(SPI2, byte);

  1020.  
  1021.   while(SPI_GetFlagStatus(SPI2, SPI_FLAG_RXNE) == RESET);

  1022.  
  1023.   return SPI_ReceiveData(SPI2);
  1024. }
  1025. */
  1026. u8 SD_Send_Command(u8 cmd, u32 arg)
  1027. {
  1028.         u8 Response;
  1029.         u8 Retry = 0;

  1030.         SD_SPI_Write_Byte(0xff);

  1031.         SD_SPI_SELECT();

  1032.         //分别写入命令
  1033.         SD_SPI_Write_Byte(cmd | 0x40);
  1034.         SD_SPI_Write_Byte(arg >> 24);
  1035.         SD_SPI_Write_Byte(arg >> 16);
  1036.         SD_SPI_Write_Byte(arg >> 8);
  1037.         SD_SPI_Write_Byte(arg);
  1038.         SD_SPI_Write_Byte(0x95);


  1039.         do{
  1040.                 // 等待响应,响应的开始位为0
  1041.                 Response = SD_SPI_Read_Byte();
  1042.                 Retry++;
  1043.         }while( ((Response&0x80)!=0) && (Retry < 200) );

  1044.         SD_SPI_DESELECT();

  1045.         return Response; //返回状态值
  1046. }

  1047. u8 SD_Read_Single_Block(u32 sector, u8* buffer)
  1048. {
  1049.         u8 Response;
  1050.         u16 i;
  1051.         u16 Retry = 0;

  1052.          //读命令 send read command
  1053.         Response = SD_Send_Command(CMD_READ_SINGLE_BLOCK, sector<<9);

  1054.         if(Response != 0x00)
  1055.                 return Response;

  1056.         SD_SPI_SELECT();

  1057.         // start byte 0xfe
  1058.         while(SD_SPI_Read_Byte() != 0xfe)
  1059.         {
  1060.           if(++Retry > 0xfffe)
  1061.           {
  1062.               SD_SPI_DESELECT();
  1063.               return 1; //timeout
  1064.           }
  1065.         }

  1066.         for(i = 0; i < 512; ++i)
  1067.         {
  1068.                 //读512个数据
  1069.                 *buffer++ = SD_SPI_Read_Byte();
  1070.         }

  1071.      // SD_MMC_ReadWrite_Byte(0xff); //伪crc
  1072.        // SD_MMC_ReadWrite_Byte(0xff); //伪crc
  1073.         SD_SPI_Write_Byte(0xff);
  1074.         SD_SPI_Write_Byte(0xff);
  1075.         SD_SPI_DESELECT();
  1076.        // SD_MMC_ReadWrite_Byte(0xff); // extra 8 CLK
  1077.         SD_SPI_Write_Byte(0xff);

  1078.         return 0;
  1079. }

  1080. u8 SD_Write_Single_Block(u32 sector, u8* buffer)
  1081. {
  1082.     u8 Response;
  1083.     u16 i;
  1084.     u16 retry=0;
  1085.     
  1086.         //写命令 send write command
  1087.     Response = SD_Send_Command(CMD_WRITE_SINGLE_BLOCK, sector<<9);
  1088.     if(Response != 0x00)
  1089.      return Response;

  1090.     SD_SPI_SELECT();
  1091.     
  1092.     SD_SPI_Write_Byte(0xff);
  1093.     SD_SPI_Write_Byte(0xff);
  1094.     SD_SPI_Write_Byte(0xff);

  1095.         //发开始符    start byte 0xfe
  1096.     SD_SPI_Write_Byte(0xfe);
  1097.     
  1098.         //送512字节数据    send 512 bytes data
  1099.     for(i=0; i<512; i++)
  1100.     {
  1101.         SD_SPI_Write_Byte(*buffer++);
  1102.     }
  1103.     
  1104.     SD_SPI_Write_Byte(0xff); //dummy crc
  1105.     SD_SPI_Write_Byte(0xff); //dummy crc
  1106.     
  1107.     Response = SD_SPI_Read_Byte();
  1108.     
  1109.         //等待是否成功    judge if it successful
  1110.     if( (Response&0x1f) != 0x05)
  1111.     {
  1112.         SD_SPI_DESELECT();
  1113.         return Response;
  1114.     }
  1115.     //等待操作完 wait no busy
  1116.     while(SD_SPI_Read_Byte() != 0x00)
  1117.     {
  1118.         if(retry++ > 0xfffe)
  1119.         {
  1120.             SD_SPI_DESELECT();
  1121.             return 1;
  1122.         }
  1123.     }
  1124.     SD_SPI_DESELECT();
  1125.     SD_SPI_Write_Byte(0xff);// extra 8 CLK

  1126.     return 0;
  1127. }
  1128. #endif





阅读(6763) | 评论(0) | 转发(0) |
0

上一篇:唤醒自已

下一篇:SD 接下工作安排

给主人留下些什么吧!~~