搜索
bottom↓
回复: 1

[SD卡读求助]SPI模式下CMD17无法接收到0xfe的令牌

[复制链接]

出0入0汤圆

发表于 2013-4-28 14:58:46 | 显示全部楼层 |阅读模式
本帖最后由 Alimy 于 2013-4-28 15:02 编辑

1GB的一个SD卡。。使用SPI模式,初始化时的时钟为375K
初始化成功后时钟转变为750K。。

初始化流程:
发CMD0,响应R1为0x01,正常。。
发CMD8, 响应R1是否支持此命令。。(此程序中没有处理下面这种情况 sd_card_type = SD_VER1X;                //1.x版本不支持CMD8指令)此卡片响应支持这个命令
发CMD58(READ_OCR),检测电压,响应正常  SD_OCR_Buff[1] == 0xff  SD_OCR_Buff[2] == 0x80
  发ACMD41,等待R1 = 0x00。
在发CMD58(READ_OCR)    响应的结果CCS ==0   说明是标准容量设备
---------初始化成功了------------------
  发cmd16,设置块长为0x0100 (256字节)

初始化程序如下
  1. /*
  2. *  @Func: uint_8 SDMMC_Init(void)
  3. *        @Usage: for SD card init
  4. *  @parameter: none
  5. *  @retval:  
  6. *    初始化状态
  7. *        CMD0_ERROR  cmd0发送错误
  8. *        CMD1_ERROR  cmd1发送错误
  9. *  CMD8_ERROR  cmd8发送错误
  10. *  CMD58_ERROR CMD58发送错误
  11. *  ACMD41_ERROR ACMD58响应有误
  12. *  INIT_SUCCESS 初始化成功
  13. *  @version: 2013-04-10 14:51:14
  14. * */
  15. uint_8 SDMMC_Init(void){
  16.         uint_8  idx = 0;
  17.         uint_16 retry = 0;
  18.        
  19.         bSDMMC_Init_Flag = 1;  // 初始化标志位,初始化未成功
  20.        
  21.         spi_cs_set();
  22.         for(;idx<0x0b;idx++){  // 发送至少74个时钟信号
  23.                 spi_send_byte(0xff);                
  24.         }        
  25.        
  26.         do{
  27.                 SD_SPISendCMD0();    // RESET CMD
  28.                 GetRespenseR1();
  29.                 if(200 == retry++){ //两百次超时
  30.                         spi_cs_set();
  31.                         return CMD0_ERROR;
  32.                 }
  33.         }while(R1_Respense!=0x01);  //响应为0x01,显示SD卡在Idle状态

  34.         SD_SPISendCMD8();
  35.         GetRespenseR7();
  36.         if(R1_Respense&R1_ILLAGAL_CMD){
  37.                 sd_card_type = SD_VER1X;                //1.x版本不支持CMD8指令       
  38.         }
  39.         else{
  40.                 sd_card_type = SD_VER20;                 // 2.0及以后版本才支持CMD8
  41.                 if((R7_Respense[4]!=CHECK_PATTERN)||(R7_Respense[3]!=VHS_2P7_3P6V)){  //valid response (check pattem error || non-compatible voltage)
  42.                         sd_card_type = SD_UNUSABLE;
  43.                         return 1;  //初始化失败
  44.                 }
  45.                 //else card with  compatible Voltage range
  46.                 SD_SPISendCMD58();   //Read OCR
  47.                 GetRespenseR3();
  48.                 if((SD_OCR_Buff[1]!=0xff)||(SD_OCR_Buff[2]!=0x80)){  // 检查操作电压范围情况
  49.                                 sd_card_type = SD_UNUSABLE;
  50.                                 return 1;  //初始化失败
  51.                 }
  52.                 retry = 0;
  53.                 do{
  54.                         WaitT0(10000);
  55.                         SD_SPISendACMD41();   //是否完成初始化
  56.                         GetRespenseR1();
  57.                         if(70==retry++){
  58.                                 spi_cs_set();
  59.                                 return 1;
  60.                                 }
  61.                 }while(R1_Respense!=0x00);   //
  62.                
  63.                 SD_SPISendCMD58();   //Read OCR
  64.                 GetRespenseR3();
  65.                 if(SD_OCR_Buff[0]&0x40){ //ccs == 1?
  66.                         sd_card_type = SD_EXT_CAPACITY;  // ccs == 1  version2.00 or later high capacity SD memory card
  67.                 }
  68.                 else{
  69.                         sd_card_type = SD_STANDARD_CAPACITY; // ccs == 0 version2.00 or later standard capacity SD memory carh
  70.                 }
  71.                
  72.         }
  73.         if(SD_STANDARD_CAPACITY == sd_card_type){
  74.                         SD_SPISendCMD16();  // SET_BLOCKLEN
  75.                         GetRespenseR1();
  76.         }
  77.         spi_cs_set();                           // 片选无效
  78.         bSDMMC_Init_Flag = 0; //初始化成功

  79.        
  80.         return INIT_SUCCESS;
  81. }
复制代码
上面用375K初始化完成后,就切换了一下时钟到750K
然后调用
  1.   
  2. SDMMC_Read_Sector(0x00000000,SD_DATA_Buff); //SD_DATA_Buff是一个放在xdata中长度为256的数组的数组名
复制代码
实现代码如下。。
  1. uint_8 SDMMC_Read_Sector(uint_32 addr,uint_8 *pbuff){
  2.         uint_16 idx = 0;
  3.         uint_8  time = 0,temp = 0;
  4.         CMD_Buff[0] = 0x51;   // CMD17   0x40 + 17
  5.         addr <<= 9;  // sector = sector*512  将块地址(扇区地址)转换为字节地址
  6. //        addr *= 512;       
  7.         CMD_Buff[1] =((addr&0xff000000)>>24);
  8.         CMD_Buff[2] =((addr&0x00ff0000)>>16);
  9.         CMD_Buff[3] =((addr&0x0000ff00)>>8);
  10.         CMD_Buff[4] =(addr&0x000000ff);
  11.         CMD_Buff[5] = 0xff;
  12. //TRY_LOOP:
  13.         spi_cs_clr();
  14.         Write_SD_CMD();
  15.         spi_read_byte();
  16.         temp =  spi_read_byte();
  17.         while(0xfe!=spi_read_byte()) ; // 一直读,读到0xfe时,接下来就是256字节的数据
  18.         for(idx=0;idx<256;idx++){
  19.                 *(pbuff+idx) = spi_read_byte();
  20.         }
  21.        
  22.         spi_read_byte();
  23.         spi_read_byte(); // 两个字节的校验码
  24.         return 0;
  25.        
  26. }
复制代码
但是逻辑分析仪抓到的数据一直是0xff,我尝试等过2min一直等不到0xfe的命令包,我也在网络搜索过类似的情况,调整了timeout时间,时钟等。还是一样无法等到0xfe
一直卡在:

  1. while(0xfe!=spi_read_byte()) ;  
复制代码
不清楚有没有前辈遇到过与我一样的问题,
还请不吝赐教!谢谢先!!!

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2013-5-2 08:58:18 | 显示全部楼层
自挽一楼。。俺的描述很难于被理解么?
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 16:27

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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