[求助] 51单片机SPI通信读取SD卡的数据,SD卡内容读取不出来

阿斯顿飞11   2018-7-26 14:34 楼主
悬赏 10 分 芯积分未解决
暑假想做一个lcd12864的badapple,显示器能单独显示图片但就是读不出来SD卡扇区的内容。是SD卡读取程序写的不对还是扇区写的不对?能单独显示图片就是无法显示SD卡的内容!!
程序看了好多次改了好多遍但都不行,求大神看看程序对不对!!
#include
#define uchar unsigned char
#define uint unsigned int

uchar ints;         //初始化变速标志

sbit cs =P1^7;
sbit di =P1^6;         //sd卡数据输入
sbit clk=P1^5;
sbit d0=P1^4;        //SD卡数据输出

//uchar xdata table[512];

//错误代码//
#define cmd0        0x01
#define cmd1        0x02
#define sdw                0x03   //sd写错误
#define sdr                0x0f  //sd读错误


void delay2(uint z)
{
  while(z--);
}

//***************************************************************************************//
//*********************************spi驱动**********************************************//
void spi_w(uchar dat)                //写数据
{
uchar i;
for(i=0;i<8;i++)
{
        if(dat&0x80)
          di=1;
          else
          di=0;

        clk=0;
        if(ints)        delay2(10);         //初始化的时候时钟速度要慢
        clk=1;
        if(ints)        delay2(10);
        dat<<=1;
}
}

uchar spi_r(void)  //读数据
{
  uchar temp=0,j;
  d0=1;

  for(j=0;j<8;j++)
  {
        clk=0;
        if(ints)        delay2(10);               
        clk=1;
        if(ints)        delay2(10);         
        temp=(temp<<1)|d0;
  }
  return (temp);
}
//*********************************spi驱动**********************************************//
//***************************************************************************************//








//***************************************************************************************//
//*********************************SD卡驱动**********************************************//
uchar sd_com(uchar *com)
{
       
        uchar i,temp,time=0;
        cs=1; spi_w(0xff); cs=0;

        for(i=0;i<0x06;i++)    //写命令
        {
                spi_w(*com++);
        }
        spi_r();
        do
        {
                temp=spi_r();  //读到有返回
                time++;
        } while((temp==0xff)&&(time<100));
        return(temp);               
}


uchar sd_reset()
{
        uchar time,temp,i;
        uchar cmd[]={0x40,0x00,0x00,0x00,0x00,0x95};

        ints=1;//开启初始化延时
         cs=1;
        for(i=0;i<20;i++)//至少74个时钟
                 {spi_w(0xff);}

        cs=0;
        time=0;
        do                          //写cmd0
        {
                temp=sd_com(cmd);
                time++;
                if(time>=200)
                {return(cmd0); }
        }while(temp!=0x01);


        cs=1;
        spi_w(0xff);
        return 0;
}

uchar sd_int()
{
        uchar time,temp;
        uchar cmd[]={0x41,0x00,0x00,0x00,0x00,0xff};
        cs=0;
        time=0;
        do
        {
                temp=sd_com(cmd);
                time++;
                if(time==100)
                  {return(cmd1);}
        }while(temp!=0)        ;
        ints=0;       
        cs=1;
        spi_w(0xff);
        return 0;
}         


uchar sd_w(unsigned long add,uchar *bu)
{
        uchar temp,time;
        uint i;
        uchar cmd[]={0x58,0x00,0x00,0x00,0x00,0xff};//cmd24
        add<<=9;//  等于add*512 扇区地址转换为字节地址
        cmd[1]=((add&0xff000000)>>24);
        cmd[2]=((add&0x00ff0000)>>16);
        cmd[3]=((add&0x0000ff00)>>8);
        cs=0;
        time=0;
        do
        {
                temp=sd_com(cmd);
                time++;
                if(time==100)
                {return(0xff);}
        }while(temp!=0);

//        for(i=0;i<100;i++)        //插入若干CLK
//        {spi_r();}

        spi_w(0xfe);  //写数据的开头

        for(i=0;i<512;i++)
        {
           spi_w(*bu++);       
        }
        spi_w(0xff);
        spi_w(0xff); //两个CRC校验

        temp=spi_r();
        if((temp & 0x1f)!=0x05)
        {
                cs=1;
                return(sdw);
        }

        while(spi_r()!=0xff);  //一直读到SD卡向flash写完数据
        cs=1;
        spi_w(0xff)        ;
        return(0);
}


uchar sd_r(unsigned long add,uchar *buf)
{
        uchar time,temp;
        uint j;
        uchar cmd[]={0x51,0x00,0x00,0x00,0x00,0xff};//cmd17
        add<<=9;//  等于add*512 扇区地址转换为字节地址
        cmd[1]=((add&0xff000000)>>24);
        cmd[2]=((add&0x00ff0000)>>16);
        cmd[3]=((add&0x0000ff00)>>8);
        cs=0;
        time=0;
        do
        {
                temp=sd_com(cmd);
                time++;
                if(time==100)
                {return(sdr);}
        } while(temp!=0);  //说明命令写入成功


        while(spi_r()!=0xfe);//读到数据的开头

        for(j=0;j<512;j++)
        {
                *buf++ = spi_r();
        }

        spi_r();
        spi_r();//读2个CRC

        cs=1;
        spi_w(0xff);
        return (0);
}


//*********************************SD卡驱动**********************************************//
//***************************************************************************************//

[/code]

回复评论 (3)

你调试一下看看问题出在哪里 能显示图片是什么意思,是sd卡里的图片吗 初始化的时候要发指令关闭sd卡的crc校验,否则就需要crc。 本帖最后由 huo_hu 于 2018-7-26 17:12 编辑
点赞  2018-7-26 17:08
引用: huo_hu 发表于 2018-7-26 17:08
你调试一下看看问题出在哪里

能显示图片是什么意思,是sd卡里的图片吗

初始化的时候要发指令关闭sd卡 ...

就是在lcd12864写图片数据能够显示
点赞  2018-7-26 17:31
引用: 阿斯顿飞11 发表于 2018-7-26 17:31
就是在lcd12864写图片数据能够显示

sd这块儿和lcd没关系,你联机调试一下,干看看不出什么。
点赞  2018-7-27 12:07
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复