sungngai 发表于 2014-10-2 12:19:43

SD卡复位失败,现在实在没有头绪了,只能在这里请教

本帖最后由 sungngai 于 2014-10-2 12:24 编辑

我刚升大二,由于大一学了点C语言和单片机基础,所以现在我想搞一个MP3,现在解码模块程序调好了,只剩下SD卡模块,可是SD卡总是复位失败。芯片用的是89C52,SD卡和程序如下,由于是新手,程序不够精简,我想各位帮我看看这SD卡驱动程序哪里有问题。先谢谢各位啦。
#include <reg52.h>
#include <vs1003.h>
#include <SDcard.h>

unsigned char is_init;                                       // 在初始化的时候设置此变量为1,同步数据传输(SPI)会放慢
unsigned char bdata Data;
sbit Data7=Data^7;
sbit Data6=Data^6;
sbit Data5=Data^5;
sbit Data4=Data^4;
sbit Data3=Data^3;
sbit Data2=Data^2;
sbit Data1=Data^1;
sbit Data0=Data^0;
void SD_spi_writeByte(unsigned char x)
{
   Data=x;
   SD_SI=Data7;
   SD_SCL=0;
   if(is_init) delay(DELAY_TIME);
       SD_SCL=1;
   if(is_init) delay(DELAY_TIME);
   SD_SI=Data6;
   SD_SCL=0;
   if(is_init) delay(DELAY_TIME);
   SD_SCL=1;
   if(is_init) delay(DELAY_TIME);
   SD_SI=Data5;
   SD_SCL=0;
   if(is_init) delay(DELAY_TIME);
   SD_SCL=1;
   if(is_init) delay(DELAY_TIME);
   SD_SI=Data4;
   SD_SCL=0;
   if(is_init) delay(DELAY_TIME);
   SD_SCL=1;
   if(is_init) delay(DELAY_TIME);
   SD_SI=Data3;
   SD_SCL=0;
   if(is_init) delay(DELAY_TIME);
   SD_SCL=1;
   if(is_init) delay(DELAY_TIME);
   SD_SI=Data2;
   SD_SCL=0;
   if(is_init) delay(DELAY_TIME);
   SD_SCL=1;
   if(is_init) delay(DELAY_TIME);
   SD_SI=Data1;
   SD_SCL=0;
   if(is_init) delay(DELAY_TIME);
   SD_SCL=1;
   if(is_init) delay(DELAY_TIME);
   SD_SI=Data0;
   SD_SCL=0;
   if(is_init) delay(DELAY_TIME);
   SD_SCL=1;
   if(is_init) delay(DELAY_TIME);
}

unsigned char SD_spi_readByte()                                  //SPI 读一个字节

{
   SD_SO=0xff;
   SD_SCL=1;
   if(is_init) delay(DELAY_TIME);
   SD_SCL=0;
   if(is_init) delay(DELAY_TIME);
   Data7=SD_SO;                                                // 读取第7 位
   SD_SCL=1;                                                   // 第1 个时钟上升沿
   if(is_init) delay(DELAY_TIME);
   SD_SCL=0;
   if(is_init) delay(DELAY_TIME);
   Data6=SD_SO;                                                // 读取第6 位
   SD_SCL=1;                                                   // 第2 个时钟上升沿
   if(is_init) delay(DELAY_TIME);
   SD_SCL=0;
   if(is_init) delay(DELAY_TIME);
   Data5=SD_SO;                                                // 读取第5 位
   SD_SCL=1;                                                   // 第3 个时钟上升沿
   if(is_init) delay(DELAY_TIME);
   SD_SCL=0;
   if(is_init) delay(DELAY_TIME);
   Data4=SD_SO;                                                // 读取第4 位
   SD_SCL=1;                                                   // 第4 个时钟上升沿
   if(is_init) delay(DELAY_TIME);
   SD_SCL=0;
   if(is_init) delay(DELAY_TIME);
   Data3=SD_SO;                                                // 读取第3 位
   SD_SCL=1;                                                   // 第5 个时钟上升沿
   if(is_init) delay(DELAY_TIME);
   SD_SCL=0;
   if(is_init) delay(DELAY_TIME);
   Data2=SD_SO;                                                // 读取第2 位
   SD_SCL=1;                                                   // 第6 个时钟上升沿
   if(is_init) delay(DELAY_TIME);
   SD_SCL=0;
   if(is_init) delay(DELAY_TIME);
   Data1=SD_SO;                                                // 读取第1 位
   SD_SCL=1;                                                   // 第7 个时钟上升沿
   if(is_init) delay(DELAY_TIME);
   SD_SCL=0;
   if(is_init) delay(DELAY_TIME);
   Data0=SD_SO;                                                // 读取第0 位
   return (Data);
}

unsigned char SD_Write_Cmd(unsigned char *pcmd)
{
   unsigned char temp,time=0;
   SD_CS=1;
   SD_spi_writeByte(0xff);                                     //提高兼容性,如果没有这里,有些SD 卡可能不支持
   SD_CS=0;
   SD_spi_writeByte(pcmd);
       SD_spi_writeByte(pcmd);
   SD_spi_writeByte(pcmd);
   SD_spi_writeByte(pcmd);
   SD_spi_writeByte(pcmd);
   SD_spi_writeByte(pcmd);
   do
   {
          temp = SD_spi_readByte();                                                                  //一直读,直到读到的不是0xff 或超时                              
          time++;
   }while((temp==0xff)&&(time<TRY_TIME));
   return(temp);
}

unsigned char SD_Reset()                                          //SD 卡复位,进入SPI 模式,使用CMd0(命令0)
{
   unsigned char time,temp,i;
   unsigned char pcmd[] = {0x40,0x00,0x00,0x00,0x00,0x95};      //命令0 的字节序列
   is_init=1;                                                   // 将is_init 置为1,此时模拟SPI 通信速速会变慢。
   SD_CS=1;                                                   // 关闭片选
   for(i=0;i<0x0f;i++)                                          //复位时,首先要发送最少74 个时钟信号
   {
         SD_spi_writeByte(0xff);                              //120 个时钟
   }
   SD_CS=0;                                                
   time=0;           
   do
   {
          temp=SD_Write_Cmd(pcmd);                              // 写入CMD0
          time++;
          if(time>=TRY_TIME)
          {
               SD_CS=1;                                           // 关闭片选
               return(INIT_CMD0_ERROR);                           // CMD0 写入失败
          }                                                                           
          }while(temp!=0x01);
   SD_CS=1;                                                   // 关闭片选
   SD_spi_writeByte(0xff);                                    // 按照SD 卡的操作时序在这里补8 个时钟
   return 0;                                                    // 返回0,说明复位操作成功
}

turf456 发表于 2014-10-2 12:40:42

电路啥样的?

登云钓月 发表于 2014-10-2 13:04:22

建议使用12或者15系列单片机。

dsp56789 发表于 2014-10-2 13:45:58

mark,学习一下

MR_ZJY 发表于 2014-10-2 13:47:32

硬件有保证?

sungngai 发表于 2014-10-2 13:58:16

turf456 发表于 2014-10-2 12:40
电路啥样的?

就是89C52最小系统+SD卡读写模块,最小系统是自己做的,调试过,用了半年没问题的。SD卡读写模块也是自己做的,后来为了排除硬件问题自己又买了一个SD卡读写模块。这是SD卡模块的原理图,SD_SO接P2^3,SD_SCL接P2^2,
SD_SI接P2^1,SD_CS接P2^0;、,用杜邦线连上最小系统的

sungngai 发表于 2014-10-2 14:02:33

MR_ZJY 发表于 2014-10-2 13:47
硬件有保证?

嗯嗯,应该没问题的,其实就是89C52最小系统+SD卡读写模块,最小系统是自己做的,调试过,用了半年没问题的。SD卡读写模块也是自己做的,后来为了排除硬件问题自己又去买了一个SD卡读写模块。现在就用买回来的SD读写模块用杜邦线接上最小系统,我觉得硬件上还是可靠的,我就想问问程序问题

sungngai 发表于 2014-10-2 14:05:44

登云钓月 发表于 2014-10-2 13:04
建议使用12或者15系列单片机。

嗯,其实我一开始就想用12来做的,可是做最小系统的时候有多出来的52芯片,而且我百度了一下89C52可以带得起来,所以就用这个来做了。其实我想问问程序有没有问题,就读,写,写命令和复位这四个函数
页: [1]
查看完整版本: SD卡复位失败,现在实在没有头绪了,只能在这里请教