3771|8

180

帖子

3

TA的资源

一粒金砂(中级)

楼主
 

求大神支招,SD卡可以初始化但是无法读写 [复制链接]

初始化是成功的,但是发送读命令一直返回0x7f,写命令一
  1. void SEND_BYTE(uchar DATA)
  2. {
  3.         uchar i,temp;
  4.         temp=DATA;
  5.         CS=0;
  6.         for(i=0;i<8;i++)
  7.         {
  8.                 CLK=0;
  9.                 if(temp&0x80)
  10.                         MOSI=1;
  11.                 else
  12.                         MOSI=0;
  13.                 temp<<=1;
  14.                 CLK=1;
  15.         }
  16. }


  17. uchar READ_BYTE()
  18. {
  19.   uchar  i,temp=0;
  20.         CS=1;
  21.         SEND_BYTE(0xff);
  22.         CS=0;
  23.   for(i=0;i<8;i++)
  24.   {
  25.                         temp<<=1;  
  26.       CLK=0;
  27.       CLK=1;
  28.       if(MISO==1)
  29.         temp|=1;
  30.       else
  31.         temp|=0;   
  32.   }
  33.   return temp;
  34. }

  35. /***********发送命令*************/
  36. uchar SEND_COM(uchar CMD[])
  37. {
  38.   uchar i,temp;
  39.         CS=1;
  40.         SEND_BYTE(0xff);
  41.         CS=0;
  42.   for(i=0;i<6;i++)
  43.   {
  44.     SEND_BYTE(CMD[i]);
  45.   }
  46.         i=0;
  47.         do
  48.         {
  49.                 temp=READ_BYTE();
  50.                 i++;
  51.         }while((temp==0xff)&&(i<200));
  52.   CS=1;
  53.         SEND_BYTE(0xff);
  54.   return temp;
  55. }

  56. /*************初始化函数***************/
  57. uchar SD_INIT()
  58. {
  59.   uchar i,j=0,res;
  60.         for(i=0;i<=10;i++)
  61.     {
  62.       SEND_BYTE(0xff);
  63.     }
  64.         CS=0;
  65.   do
  66.   {
  67.     res=SEND_COM(CMD0);
  68.     j++;
  69.                 if(j==200)
  70.                 {
  71.                         return 0xff;
  72.                 }
  73.   }while(res!=0x01);
  74.         i=0;
  75.         CS=1;
  76.         SEND_BYTE(0xff);
  77.         CS=0;
  78.   do
  79.   {
  80.     res=SEND_COM(CMD8);
  81.     j++;
  82.                 if(j==200)
  83.                 {
  84.                         return 0xff;
  85.                 }
  86.   }while(res!=0x01);
  87.         do
  88.   {
  89.                 SEND_COM(CMD55);
  90.     res=SEND_COM(CMD41);
  91.     i++;
  92.                 if(i==200)
  93.                 {
  94.                         return 0xff;
  95.                 }
  96.   }while(res!=0x00);
  97.         i=0;
  98.         CS=1;
  99.         SEND_BYTE(0xff);
  100.         CS=0;
  101.         do
  102.   {
  103.     res=SEND_COM(CMD16);
  104.     i++;
  105.                 if(i==200)
  106.                 {
  107.                         return 0xff;
  108.                 }
  109.   }while(res!=0x00);
  110.         return res;       
  111. }
复制代码

直返回0xff,怎么回事??我把初始化跟读写函数贴出来给大家看看。。。
此帖出自51单片机论坛

最新回复

你直接用振南电子的sd驱动函数吧,还有视频讲解。  详情 回复 发表于 2015-2-10 00:18
点赞 关注
 

回复
举报

180

帖子

3

TA的资源

一粒金砂(中级)

沙发
 
这边是读写的函数
  1. uchar SD_ReadSector(uchar *buf,long int sector)
  2. {
  3.         uchar response,i=0;
  4.         sector*=512;
  5.         CMD17[1]=((sector)>>24);
  6.         CMD17[2]=((sector)>>16);
  7.         CMD17[3]=((sector)>>8);
  8.         CMD17[4]=sector;
  9.         CS=1;
  10.         SEND_BYTE(0xff);
  11.         CS=0;
  12.         do
  13.         {
  14.                 response=SEND_COM(CMD17);
  15.                 i++;
  16.                 if(i==200)
  17.                 {
  18.                         return response;
  19.                 }
  20.         }while(response!=0);
  21.         i=0;
  22.         while(READ_BYTE()!=0xfe);
  23.         for(i=0;i<512;i++)
  24.         {
  25.                 *buf++=READ_BYTE();
  26.         }
  27.         CS=1;
  28.         SEND_BYTE(0xff);
  29.         return 0;
  30.        
  31. }


  32. uchar SD_WriteSector(uchar *buf,long int sector)
  33. {
  34.         uchar response,i=0;
  35.         sector*=512;
  36.         CMD24[1]=((sector&0xff000000)>>24);
  37.         CMD24[2]=((sector&0x00ff0000)>>16);
  38.         CMD24[3]=((sector&0x0000ff00)>>8);
  39.         CMD24[4]=sector&0x000000ff;
  40.         CS=1;
  41.         SEND_BYTE(0xff);
  42.         CS=0;
  43.         do
  44.         {
  45.                 response=SEND_COM(CMD24);
  46.                 i++;
  47.                 if(i==200)
  48.                 {
  49.                         return response;
  50.                 }
  51.         }while(response!=0);
  52.         SEND_BYTE(0xfe);
  53.         i=0;
  54.         for(i=0;i<512;i++)
  55.         {
  56.                 SEND_BYTE(*buf++);
  57.         }
  58.         SEND_BYTE(0xff);
  59.         SEND_BYTE(0xff);
  60.         response=READ_BYTE();
  61.         if(response&0x1f!=0x05)
  62.                 return response;
  63.         while(READ_BYTE()!=0xff);
  64.         CS=1;
  65.         SEND_BYTE(0xff);
  66.         return 0;
  67. }
复制代码
此帖出自51单片机论坛
 
 
 

回复

180

帖子

3

TA的资源

一粒金砂(中级)

板凳
 
来个人给我看看啊。。。
此帖出自51单片机论坛
 
 
 

回复

1万

帖子

139

TA的资源

版主

4
 
列出详细的程序流程,再跟SD卡的读写时序比较,这样更容易发现问题。直接贴代码,简单是简单了,结果呢?
此帖出自51单片机论坛

点评

是按照时序来的,还参考了好几个别人的程序。。。  详情 回复 发表于 2015-2-9 19:33
 
个人签名上传了一些书籍资料,也许有你想要的:https://download.eeworld.com.cn/user/chunyang
 
 

回复

180

帖子

3

TA的资源

一粒金砂(中级)

5
 
chunyang 发表于 2015-2-9 19:08
列出详细的程序流程,再跟SD卡的读写时序比较,这样更容易发现问题。直接贴代码,简单是简单了,结果呢?


是按照时序来的,还参考了好几个别人的程序。。。

此帖出自51单片机论坛
 
 
 

回复

1976

帖子

0

TA的资源

五彩晶圆(初级)

6
 
你可以尝试一下单步调试一下读数据的函数,看看能不能读到正确回应
此帖出自51单片机论坛
 
 
 

回复

855

帖子

5

TA的资源

一粒金砂(高级)

7
 
你直接用振南电子的sd驱动函数吧,还有视频讲解。
此帖出自51单片机论坛

点评

已经成功啦。。。等哈把代码贴出来  详情 回复 发表于 2015-2-10 13:54
 
 
 

回复

180

帖子

3

TA的资源

一粒金砂(中级)

8
 
人民币的幻想 发表于 2015-2-10 00:18
你直接用振南电子的sd驱动函数吧,还有视频讲解。
已经成功啦。。。等哈把代码贴出来



此帖出自51单片机论坛
 
 
 

回复

180

帖子

3

TA的资源

一粒金砂(中级)

9
 
目前初始化以及扇区读写都成功。。。现在贴出代码造福需要的人。。。。本人亲测通过
  1. void SD_SendByte(u8 Byte)    //向SD写入一个字节,模拟SPI
  2. {
  3.         u8 i,temp;
  4.         temp=Byte;
  5.         CS=0;
  6.         for(i=0;i<8;i++)
  7.         {
  8.                 CLK=0;
  9.                 if(temp&0x80)             //从高位写入
  10.                         MOSI=1;
  11.                 else
  12.                         MOSI=0;
  13.                 temp<<=1;
  14.                 CLK=1;
  15.         }
  16. }


  17. u8 SD_ReceiveByte(void)            //从SD读出一个字节
  18. {
  19.         u8 Byte,i;
  20.         CS=0;
  21.         for(i=0;i<8;i++)
  22.         {
  23.                 Byte<<=1;
  24.                 CLK=0;
  25.     if(MISO==1)
  26.       Byte|=0x01;
  27.     else
  28.       Byte&=0xfe;
  29.                 CLK=1;

  30.         }
  31.         return Byte;
  32. }


  33. u8 SD_WaitReady()                 //等待SD卡准备好,返回1:失败,0:OK
  34. {
  35.         u8 i,temp;
  36.         for(i=0;i<200;i++)
  37.         {
  38.                 temp=SD_ReceiveByte();
  39.                 if(temp==0xff)
  40.                         return 0;
  41.         }
  42.         return 1;
  43. }


  44. u8 SD_SendCommand(u8 Command,u32 arg,u8 CRC)      //返回1:失败,其他:成功
  45. {
  46.         u8 response,i=200;
  47.         while(SD_WaitReady())              //先等待SD卡准备好
  48.         CS=1;
  49.         SD_SendByte(0xff);                //发送8个同步时钟
  50.         CS=0;
  51.         SD_SendByte(Command|0x40);         //开始发送命令
  52.         SD_SendByte((arg&0xff000000)>>24);      
  53.   SD_SendByte((arg&0x00ff0000)>>16);
  54.   SD_SendByte((arg&0x0000ff00)>>8);
  55.   SD_SendByte((arg&0x000000ff)>>0);
  56.   SD_SendByte(CRC);
  57.   i=200;
  58.   do
  59.   {
  60.     response=SD_ReceiveByte();
  61.     i--;
  62.     if(i==0)
  63.       return 1;                            //获得应答失败或者超时
  64.   }while(response&0x80);
  65.   CS=1;
  66.   SD_SendByte(0xff);                      //8个同步时钟
  67.   return response;
  68.          
  69. }


  70. u8 SD_Init()                       //SD卡初始化 返回0:成功 其他:失败或超时
  71. {
  72.   u8 response,i=0;
  73.   delay1(100);                    //等待SD卡电压升高至工作电压
  74.   while(SD_WaitReady());          //等待SD卡准备就绪
  75.   CS=0;
  76.   do
  77.   {
  78.     response=SD_SendCommand(CMD0,0,0x95);   //CMD0复位
  79.     i++;
  80.     if(i==200)
  81.       return 0xff;
  82.   }while(response!=0x01);
  83.   i=0;
  84.   do
  85.   {
  86.     response=SD_SendCommand(CMD8,0x01aa,0x87);   //判断SD卡版本
  87.     i++;
  88.     if(i==200)
  89.       return 0xff;
  90.   }while(response!=0x01);                       //version 2.0
  91.   i=0;
  92.   do
  93.   {
  94.     SD_SendCommand(CMD55,0x00,0x01);
  95.     response=SD_SendCommand(CMD41,0x0040,0x01);
  96.     i++;
  97.     if(i==200)
  98.       return 0xff;
  99.   }while(response!=0);                            //判断初始化是否完成
  100.   i=0;
  101.   do
  102.   {
  103.     response=SD_SendCommand(CMD16,0x0200,0x01);    //设置扇区大小为512字节
  104.     i++;
  105.     if(i==200)
  106.       return 0xff;
  107.   }while(response!=0);
  108.   CS=1;
  109.   SD_SendByte(0xff);
  110.   return 0;
  111.    
  112. }


  113. u8 SD_ReadSingleSector(u8 *buff,u32 sector)     //SD读取单个扇区,返回0:成功,其他:失败
  114. {
  115.   u8 response,i=0;
  116.   u16 cnt;
  117.   while(SD_Init());                             //先初始化SD卡
  118.   while(SD_WaitReady());
  119.   CS=0;
  120.   sector*=512;
  121.   do
  122.   {
  123.     response=SD_SendCommand(CMD17,sector,0x01);  
  124.     i++;
  125.     if(i==200)
  126.       return 1;
  127.   }while(response!=0);
  128.   while(SD_WaitReady());
  129.   for(i=0;i<200;i++)
  130.   {
  131.     response=SD_ReceiveByte();
  132.     if(response==0xfe)
  133.       break;
  134.   }
  135.   if(response!=0xfe)
  136.   {
  137.     return 1;
  138.   }
  139.   for(cnt=0;cnt<512;cnt++)
  140.   {
  141.     *buff++=SD_ReceiveByte();
  142.   }
  143.   SD_ReceiveByte();
  144.   SD_ReceiveByte();
  145.   CS=1;
  146.   SD_SendByte(0xff);
  147.   return 0;   
  148. }



  149. u8 SD_WriteSingleSector(u8 *buff,u32 sector)      //SD卡写单个扇区,返回0:成功,1:失败
  150. {
  151.   u8 response,i;
  152.   u16 cnt;
  153.   if(SD_Init())                                //先初始化SD卡
  154.   return 1;
  155.   while(SD_WaitReady());
  156.   CS=0;
  157.   sector*=512;
  158.   do
  159.   {
  160.     response=SD_SendCommand(CMD24,sector,0x01);  
  161.     i++;
  162.     if(i==200)
  163.       return 1;
  164.   }while(response!=0);
  165.   for(i=0;i<10;i++)
  166.   {
  167.     SD_SendByte(0xff);
  168.   }
  169.   SD_SendByte(0xfe);
  170.   for(cnt=0;cnt<512;cnt++)
  171.   {
  172.     SD_SendByte(*buff++);
  173.   }
  174.   SD_SendByte(0xff);
  175.   SD_SendByte(0xff);
  176.   while(((SD_ReceiveByte()&0x1f)!=0x05)&&i<=200)
  177.   {
  178.     i++;
  179.   }
  180.   if(i==200)
  181.     return 1;
  182.   else
  183.   {
  184.     SD_WaitReady();
  185.     CS=1;
  186.     SD_SendByte(0xff);
  187.     return 0;
  188.   }
  189.   
  190. }
复制代码
此帖出自51单片机论坛
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表