[求助] 求助:SD卡读写程序 初始化进入复位循环就出不来了,一直不返回0x01。。。

nothingo   2011-8-8 10:21 楼主

//SD卡初始化
char SD_init(void)
{
  int i;
  int time=5;
  unsigned char response1=0xff,response2=0xff;
  P5SEL|=0X0e;   //初始化430UART引脚

  P5DIR|=0X0B;

  SPI_init();
  CS_1;
   do
  {
    if(!time)
      return (failed);
    time--;
   for(i=0;i<10;i++)
     Sendbyte(0xff);//延时80个CLK
     CS_0;
     Sendcmd(cmd0,0,0x95);
  }
   while(getresponse1()!=0x01);
     while((response1!=0x01)||(response2!=0x00))
    {
      CS_1;
      Sendbyte(0xff);//延时8个CLK
      CS_0;
      Sendcmd(cmd55,0,0xff);
      response1=getresponse1();
      CS_1;
      Sendbyte(0xff);
      CS_0;
      Sendcmd(acmd41,0,0xff);
      response2=getresponse0();
    }
  CS_1;
  Sendbyte(0xff);
  return (SUCCESS);
}

 

 

 

刚开始做430,要做个SPI方式写SD卡的程序,大侠们帮帮忙看看吧。。。这个问题已经纠结好久了 ,看了很多资料也没明白为什么循环不出来

回复评论 (15)

这个要慢慢调,把错误出现的范围缩小,你先在第一个循环里放一条调试语句(就是现象很直观的),注意调试语句放在return的前后是有区别的,因为执行return后,整个函数就结束了。

很高兴来到EEW。希望和大家相互学习,共同进步!
点赞  2011-8-20 23:45

回复 沙发 5xue 的帖子

谢谢啦~~~~只有你回复了。。。刚开始做430,老师又一直催结果,就比较着急了,好好耐心调试是正道呀
点赞  2011-9-3 16:03
楼主,这么久了?跳出来没有。小弟也遇到同样的问题,能否把你的SPI写SD卡的初始化程序贴出来呢?万分感谢~~,包括SPI_init();和Sendcmd(cmd0,0,0x95);函数。谢谢~~
点赞  2011-9-15 15:40
能不能多贴一点代码呢?
或者多一点注释
感觉这样看不出来啊
点赞  2011-9-15 18:48

回复 4楼 yl20084784 的帖子

到现在我还没跳出来呢。。。很搞笑的是,三星的卡是好用的,金士顿的就写不进去了。。。真纠结。。。三星那个卡也是莫名其妙就自己能写进去了
点赞  2011-10-11 09:00

回复 5楼 wstt 的帖子

谢谢斑竹啊~~~

#include "msp430x16x.h" //使用UART1串口SPI模式控制SD卡存储  端口选择 P5.0/STE=1  P5.1/SIMO=2  P5.2/SOMI=7  P5.3/UCLK=5  
#include "string.h"
#include "sca3060spi.h"

#define CS_1 P5OUT|=0x01
#define CS_0 P5OUT&=~0x01
#define SUCCESS 1
#define failed 0
#define cmd0 0
#define cmd1 1
#define cmd8 8
#define cmd55 55
#define acmd41 41
#define cmd9 9
#define cmd16 16
#define cmd24 24
#define cmd17 17



unsigned char response=0;//回应



   
  void open_xt2(void)
{
  BCSCTL1 &= ~XT2OFF;
  char n;
  do
  {
    IFG1 &= ~OFIFG;
    for(n=0xee;n>0;n--)
    {
      ;
    }
  }
  while((IFG1&OFIFG)!=0);   
  BCSCTL2 |= SELM_2+ SELS+DIVM_3;      
}
void SPI_init(void)
{
  open_xt2();//函数
  UCTL1=SWRST;//开启设置
  UTCTL1=CKPH+SSEL1+STC;//选择SMCLK
  UCTL1|=CHAR+SYNC+MM;//8为数据 SPI模式
  UBR01=0x04;//波特率设置
  UBR11=0X00;
  UMCTL1=0X00;
  UCTL1&=~SWRST;//关闭设置
  ME2|=USPIE1;//使能SPI
}


//发送八位字节  同时用于延时八个CLK
char Sendbyte(unsigned char byte)
{
  while((IFG2&UTXIFG1)==0);//等待...直到发送中断标志位置位
  TXBUF1=byte;
  while((IFG2&URXIFG1)==0);//等待...直到接受缓存数据满  再取回数据
  return (RXBUF1);
}


void Sendcmd(unsigned char cmd,unsigned long data,unsigned char CRC)//cmd 命令字  data 命令指令 CRC 校验位
{
  unsigned char command[6];
  int i;
   command[0]=(cmd|0x40);
   for(i=1;i<5;i++)
    command=(char)(data>>8*(4-i));
  command[5]=CRC;
    for(i=0;i<6;i++)
    Sendbyte(command);
}

//回应0x00
unsigned char getresponse0()
{
    int i=0;
    while(i<10)
  {
    response= Sendbyte(0xff);
    if(response==0x00)break;
    i++;   
  }
  return (response);
}
//回应0x01
unsigned char getresponse1()
{
  int i=0;
  while(i<10)
  {
    response=Sendbyte(0xff);
    if(response==0x01)break;
    i++;
  }
  return (response);
}
//SD卡初始化
char SD_init(void)
{
  int i;
  int time=5;
  unsigned char response1=0xff,response2=0xff;
  P5SEL|=0X0e;//0000 1110 P5.0.1.2.3选择第二功能
  P5DIR|=0X0b;  //0000 0111 miso为输入
  SPI_init();
  CS_1;
  do
  {
    if(!time)
      return (failed);
    time--;
     for(i=0;i<10;i++)
     Sendbyte(0xff);//延时80个CLK
     CS_0;
     Sendcmd(cmd0,0,0x95);
  }
   while(getresponse1()!=0x01);
     while((response1!=0x01)||(response2!=0x00))
    {
      
      CS_1;
      Sendbyte(0xff);//延时8个CLK
      CS_0;
      Sendcmd(cmd55,0,0xff);
      response1=getresponse1();
      CS_1;
      Sendbyte(0xff);
      CS_0;
      Sendcmd(acmd41,0,0xff);
      response2=getresponse0();
    }
  CS_1;
  Sendbyte(0xff);
  return (SUCCESS);
}
//设置数据长度 cmd16
char Set_block_length(unsigned long length)
{
  CS_0;
  Sendcmd(cmd16,length,0xff);
  while(getresponse0()!=0x00)
  {
    SD_init();
    CS_0;
    Sendcmd(cmd16,length,0xff);
  }
  CS_1;
  Sendbyte(0xff);
  return (SUCCESS);
}
//读取SD卡数据(单块)
char Read_data(unsigned long address,unsigned long length,unsigned char *buffer)
{
  int check;
  unsigned long i;
  check=Set_block_length(length);
  if(check==SUCCESS)
  {
    do
    {
    Sendbyte(0xff);
    CS_0;
    Sendcmd(cmd17,address,0xff);
    }
   while(getresponse0()!=0x00);
   while(Sendbyte(0xff)!=0xfe);
   for(i=0;i      buffer=Sendbyte(0xff);
  }
  CS_1;
  Sendbyte(0xff);
  return (*buffer);
}

//发送命令字

//读取SD卡容量信息,此信息存储在CSD寄存器中  通过发送cmd9来读取
//需要数据为80-84/SD_len  62-73/SD_size  47-49/SD_size_mult
unsigned long  Read_SD_size(void)
{
  unsigned int data,i,j,SD_size;
  unsigned char SD_len,SD_size_mult;
  unsigned long SD_card_size;
  do
  {
   CS_1;
   Sendbyte(0xff);
   CS_0;
   Sendcmd(cmd9,0,0xff);
  }
  while(getresponse0()!=0x00);
  do
    data=response=Sendbyte(0xff);
    while(data!=0xfe);
    for(i=0;i<5;i++)//88-127
    data=Sendbyte(0xff);
    data=Sendbyte(0xff);//80-87
    SD_len=data&0x0F;//取出80-83
    data=Sendbyte(0xff);//72-79
    SD_size=(data&0x03)<<10;//取出72-72位  并放到最高位
    data=Sendbyte(0xff);//64-71
    SD_size+=data<<2;
    data=Sendbyte(0xff);//56-63
    SD_size+=data>>6;
    data=Sendbyte(0xff);//48-55
    SD_size_mult=(data&0x3)<<1;//取出48-49
    data=Sendbyte(0xff);//40-47
    SD_size_mult+=data>>7;
    for(i=0;i<5;i++)
    data=Sendbyte(0xff);//0-39
    for(i=0;i<4;i++)//延时
    Sendbyte(0xff);
    data=Sendbyte(0xff);
    CS_0;
    //开始计算容量
    SD_card_size=SD_size+1;
    for(i=2,j=SD_size_mult+2;j>1;j--)
      i<<=1;
    SD_card_size*=i;
    for(i=2,j=SD_len;j>1;j--)
      i<<=1;
    SD_card_size*=i;
    return SD_card_size;
}


//向SD卡写数据(单块)        写入的地址             数据长度              要写入的数据
unsigned char  Write_data(unsigned long address,unsigned  long length ,unsigned char *buffer)
{
  int check,temp;
  unsigned long i;
  check=Set_block_length(length);
  if(check==SUCCESS)
  {
    do
    {
    Sendbyte(0xff);
    CS_0;
    Sendcmd(cmd24,address,0xff);
    }
   while(getresponse0()!=0x00);
   Sendbyte(0xff);
   Sendbyte(0xff);
   Sendbyte(0xfe);
   for(i=0;i      Sendbyte(*buffer++);
   Sendbyte(0xff);
   Sendbyte(0xff);
    temp =  Sendbyte(0xFF);   //读SD卡运行响应
        if((temp & 0x1F)!=0x05)             //如果最后4位为0101,为操作成功。否则为操作失败。
        {
               CS_1;
                                                     
                return(failed); //返回错误
        }
        
        while ( Sendbyte(0xFF) != 0xFF);

           CS_1;
           return(SUCCESS);                            //返回成功   
   }
  else
    return(failed);
}

unsigned char buffer_data1[512];
//主函数。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

void  main( void )
{  
   int q,k;
   unsigned long m;
   volatile unsigned char ans=0;
   unsigned char write_data;
   volatile unsigned long d1;   
   WDTCTL=WDTPW+WDTHOLD;//关狗
   //P1DIR |=BIT0;
   m=520;
   //m=1040;
   Init() ;//MSP430F149引脚初始化;
   Write_One_Byte(0x14,0x01);
   SD_init();   

      for(k=0;k<10;k++)
      {
        
        for(q=0,write_data=1;q<512;q++,write_data++)
        buffer_data1[q]=write_data;
        ans=Write_data(m*512,512,buffer_data1);
        m++;                                    
        ans =Read_One_Byte(0x04);
        ans =Read_One_Byte(0x05);                                
      
   }
}

这就是主要程序啦~~~~斑竹帮忙看看,我已经试了很多方法,现在三星的2G卡可以写进去,但是金士顿的2G卡到了acmd41发送完一直收到0XFF,初始化不成功。。。
点赞  2011-10-11 09:03
还在看
点赞  2011-10-11 12:46
我也正在学啊,有点难啊
点赞  2011-11-7 19:50

回复 9楼 zkaiaizy 的帖子

哎。。。我始终没有解决那个问题。。。老师现在又让我开始做4G的了,貌似不能用SPI模式了,再学习学习~~~~加油啊
点赞  2011-11-10 10:22
难道 卡有区别 ? 我也遇到这样的问题了。复位成功,初始化失败。也不知道是不是硬件问题
https://bbs.eeworld.com.cn/viewth ... 1&extra=#pid1227110

点赞  2011-12-7 09:28

mark

楼主,我也正在学习中,用spi通信sd的方式,不知为什么换成4g卡就不行?什么原因?
点赞  2011-12-22 11:29

回复 12楼 shenmiao0330 的帖子

4G以上的卡大多是SDHC卡,要使用高速模式就要用SD模式,而不是SPI模式了。。。我记得看了的资料上是这样子的
点赞  2011-12-27 14:21
还是用SDV600模块吧!SD卡存储不用考虑FAT32协议了,直接串口存储数据就行了
点赞  2011-12-27 14:47

回复 14楼 anbek 的帖子

我要写的程序本来就是不用文件系统的,直接写入数据
点赞  2012-1-3 09:14

回复 13楼 nothingo 的帖子

哦了!
点赞  2012-1-11 09:21
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复