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,说明复位操作成功
} 电路啥样的? 建议使用12或者15系列单片机。 mark,学习一下 硬件有保证? 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;、,用杜邦线连上最小系统的 MR_ZJY 发表于 2014-10-2 13:47
硬件有保证?
嗯嗯,应该没问题的,其实就是89C52最小系统+SD卡读写模块,最小系统是自己做的,调试过,用了半年没问题的。SD卡读写模块也是自己做的,后来为了排除硬件问题自己又去买了一个SD卡读写模块。现在就用买回来的SD读写模块用杜邦线接上最小系统,我觉得硬件上还是可靠的,我就想问问程序问题 登云钓月 发表于 2014-10-2 13:04
建议使用12或者15系列单片机。
嗯,其实我一开始就想用12来做的,可是做最小系统的时候有多出来的52芯片,而且我百度了一下89C52可以带得起来,所以就用这个来做了。其实我想问问程序有没有问题,就读,写,写命令和复位这四个函数
页:
[1]