搜索
bottom↓
回复: 1

关于SD卡的驱动

[复制链接]

出0入0汤圆

发表于 2012-9-21 20:50:18 | 显示全部楼层 |阅读模式
我用单片机驱动一个8G的SD卡,FAT32格式,采用SPI模式,现在的情况是第一次调试的时候发送CMD0 返回0x01 发送CMD1返回0x00,正常激活了,后来调试的时候同样的程序发送CMD0 返回0x01 发送CMD1返回还是0x01,一致通过不了,请教大家是不是我程序的问题啊?谢谢:
#include"SD.h"

//**************控制端口定义********************
//定义SD卡引脚定义
#define SD_DO   PORTB.6
#define SD_CLK  PORTB.7
#define SD_DI   PORTB.5
#define SD_CS   PORTB.4

//******************全局变量***************************
unsigned char   DATA[512];//定义512字节缓冲区,注意需要使用


//================================================================================================
//实现功能:写一字节到SD卡,模拟SPI总线方式
//输入参数:n 待写入数据
//================================================================================================
void SdWrite(unsigned char n)
{

        unsigned char i;

        for(i=0;i<8;i++)
        {
         SD_CLK=0;

         if(n&0x80)SD_DI=1;else SD_DI=0;
         n<<=1;
         SD_CLK=1;

        }
       
    SD_DI=1;
}

//================================================================================================
//实现功能:从SD卡读一字节,模拟SPI总线方式
//返回参数:n 读取的8位数据
//================================================================================================
unsigned char SdRead()
{
        unsigned char n=0,i;
                    
    for(i=0;i<8;i++)
        {
         SD_CLK=0;

         SD_CLK=1;
         n<<=1;
         if((PINB&0x40)==0x40) n|=1;else n|=0;
        }
      
        return n;
}

//================================================================================================
//实现功能:读取SD卡的响应
//返回参数:response 响应标志
//================================================================================================
unsigned char SdResponse()
{
    unsigned char response,time=0;;
   
    do
    {  
      response=SdRead();
      time++;
    }
    while((response==0xff)&&(time<100));//100次以内尝试读取响应

    return response;      //返回读取的数据

}

//================================================================================================
//实现功能:发命令到SD卡
//================================================================================================
void SdCommand(unsigned char command, unsigned long argument, unsigned char CRC)
{
        unsigned char i,a[6];
        
        a[0]=command|0x40;
        a[1]=((argument&0xff000000)>>24);
        a[2]=((argument&0x00ff0000)>>16);
        a[3]=((argument&0x0000ff00)>>8);
        a[4]=  argument&0x000000ff;
        a[5]=  CRC;
        
        for(i=0;i<6;i++)
        {   
             SdWrite(a[i]);
        }
}

//================================================================================================
//实现功能:初始化SD卡(参考SD卡初始化时序)
//================================================================================================
unsigned char SdInit(void)
{
        unsigned char i,time=0;
        unsigned char response=0x01;
      
    //send CMD0,如果response=0x01则SD卡成功转到SPI模式
    do
     {
      SD_CS=1;
          for(i=0;i<=9;i++)       //复位时最少写入74个时钟周期
          SdWrite(0xff);
          SD_CS=0;                //复位后CS拉低
        
      SdCommand(0x00,0,0x95); //Send Command 0 to put MMC in SPI mode
      response=SdResponse();
         
      time++;
     }
    while((response!=0x01)&&(time<100));   //等待命令CMD0的响应
    if(time==100)return 0;    //100次仍然不能得到命令CMD0的响应,超时退出

        
    //SD卡在进入SPI模式后,激活命令为Cmd1
        do
        {
         SdWrite(0xff);           //补偿8个时钟
         SdCommand(0x01,0,0xff);  //send CMD1
         response=SdResponse();
        } while(response!=0x00);  //等待返回0x00

    //最后CS拉高
        SD_CS=1;
        SdWrite(0xff);            //补偿8个时钟
        return 1;                 //初始化成功,返回成功信号1
}

//================================================================================================
//实现功能:从SD卡指定地址读取数据,一次最多512字节(参考SD卡读时序)
//================================================================================================
unsigned char SdReadBlock(unsigned char *Block, unsigned long address,unsigned int len)
{
    unsigned int count;

    SD_CS=0;       //使能SD卡

    SdCommand(17,address,0xff);//send command 17读扇区命令
      
    if(SdResponse()==00)//command was a success - now send data
        {
           while(SdRead()!=0xfe); //等待数据的起始令牌号
         for(count=0;count<len;count++) *Block++=SdRead(); //读512个数据
       
         SD_CS=1;
         return 1;
        }
        return 0;
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2012-9-22 07:26:53 | 显示全部楼层
有现成的参考代码
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-6-10 20:06

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表