打印

SD卡的复位时怎样的,为什么我的代码总是复位不成功?

[复制链接]
3483|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
yinlb1987|  楼主 | 2010-1-21 15:09 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
以下是代码,单片机用的是stc12C5A32AD,带spi接口的,发送CMD0之后的响应总是0xff,而不是0x01,希望各位给我看看,是哪个地方的问题。程序参考了ZLG的SD驱动程序。
#include"stc8051.h"
//#include "sdcmd.h"
#include "serial.h"

#define   SD_NO_ERR                                     0x00                        // 函数执行成功
#define   SD_ERR_CMD_TIMEOUT             0x11                        // 卡命令响应超时
#define SD_IDLE_WAIT_MAX             1000
#define          SD_ERR_TIMEOUT_WAITIDLE         0x34                        // 初始化SD卡时,等待SD卡进入空闲状态超时错误
#define   SD_CMD_TIMEOUT                            200


#define CMD0 0
#define CMD1 1


sbit SCLK=P1^7;
sbit MISO=P1^6;
sbit MOSI=P1^5;
sbit CS=P2^7;


void Delay(uchar N){
        uint j=0;
        while(N--){
                 for(j=0;j<1000;j++)
                        ;
        }

}

//spi传输完成中断处理函数
void SPI_Interrupt_Routine()interrupt 9{
       

        SPSTAT=0XC0;

}

//spi接收一字节数据
uchar SPI_RecByte(){
        uchar BYTE;
        SPDAT=0x00;
        while(!(SPSTAT&0x80));
        BYTE=SPDAT;
        return BYTE;       

}
//spi发送一字节
uchar SPI_SendByte(uchar dat){
        SPDAT=dat;
        while(!(SPSTAT&0x80));
        return SPDAT;
//        Prints("send byte end\t\n");

}

//spi从机被选中
void SPI_CS_Assert(){
        CS=0;
}

void SPI_CS_Deassert(){
        CS=1;

}
//SPCTL位stc单片机SPI总线控制寄存器
//复位 时 时钟<400k
void SPI_Clk400k(){
        SPCTL=0xd2;//cpu_clk/64          11.0592M/64             CPOL=0,CPHA=0,MASTER=1

}
void SPI_ClkMax(){

        SPCTL=0Xd0;//cpu_clk/4
}

/********************************************************************************************************************
** 函数名称: void SD_SPIDelay()                                                Name:          void SD_SPIDelay()
** 功能描述: SPI总线延时                                                        Function: SPI Bus delay
** 输   入: INT8U value: 延时值,不超过255                    Input:          INT8U value : delay value,do not beyond 255
** 输   出: 无                                                                                Output:          NULL
*********************************************************************************************************************/
void SD_SPIDelay(uchar value)
{
    uchar i;

    for (i = 0; i < value; i++)
        SPI_SendByte(0xff);                                                         /* 发送0xFF clock out 0xFF */
}



/********************************************************************************************************************
** 函数名称: uchar SD_SendCmd()                                               
** 功能描述: 向卡发送命令,并取得响应               
** 输   入: uchar cmd            : 命令字                               
                         uchar *param        : 命令参数,长度为5字节               
                         uchar resptype : 响应类型                                                  
                         uchar *resp        : 响应,长度为1-5字节               
** 输   出: 0:   正确    >0:   错误码                                 
********************************************************************************************************************/
void SD_SendCmd(uchar cmd, uchar *param){
        uchar i;
   
        Prints("enter sendcmd        \n");
        SPI_CS_Assert();
    SPI_SendByte((cmd & 0x3F) | 0x40);                                 /* 发送命令头和命令字 send command header and word */
   
//        Prints("header send end\t\n");
    for (i = 0; i <=4;i++){
        SPI_SendByte(param[i]);                                                 /* 发送参数 send parameters */
        //        Delay(1);
        }
        Prints("send cmd end\n");
//        if(Is_Reset)
  //                 SPI_SendByte(0x95);                                                                  /* 不用crc  ,0x95复位用 */
//        else
//               
         SPI_SendByte(0xff);                                  //命令发送完之后,在发送1*8个时钟
//         SPI_SendByte(0xff);
}  
   
                                         

/********************************************************************************************************************
** 函数名称: INT8U SD_ResetSD()                                                Name:          INT8U SD_ResetSD()
** 功能描述: 复位SD/MMC卡                                                        Function: reset SD/MMC card
** 输   入: 无                                                                                Input:          NULL
** 输   出: 0:   正确    >0:   错误码                                  Output:          0:  right                >0:  error code
*********************************************************************************************************************/
uchar SD_ResetSD()
{
        uchar param[5] = {0,0,0,0,0x95};
        uchar i=0,tmp=0x00;
        Prints("enter reset\n");
//        for(i=0;i<10;i++){
//                 SPI_SendByte(0x00);
//        }
                         
//        SPI_CS_Assert();
//        Prints("wait for response\t\n");       
        SPI_CS_Deassert();
//        Delay(100);
        SD_SPIDelay(15);                                                                 //发送74+个时钟
        SD_SendCmd(CMD0,param);               
    do                                                                                                  /* 等待响应,CMD0响应为0x01 */
    {                                                                                                 
        tmp = SPI_RecByte();
            //tmp=SPI_SendByte(0xff);
        i++;
    }while ((tmp!=0x01) && (i < SD_CMD_TIMEOUT));

           PrintNum(tmp);
        Prints("\n");          
        SPI_CS_Deassert();
    if (i >= SD_CMD_TIMEOUT)
    {               
                Prints("error:reset timeout\n");

                                                                                                         
        return SD_ERR_CMD_TIMEOUT;                                         /* 返回命令超时 return response timeout of command */
    }
   
        SPI_SendByte(0xff);
  
    return SD_NO_ERR;               
}

/*******************************************************************************************************************
** 函数名称: INT8U SD_CalTimeout()                                Name:          INT8U SD_CalTimeout()
** 功能描述: 计算读/写/擦超时时间                                Function: get the information of SD card
** 输   入: INT8U *cardtype: 卡类型接收缓冲         Input:    INT8U *cardtype: card type receive buff
** 输   出: 0:   正确    >0:   错误码                          Output:          0:  right                >0:  error code
** 函数说明: 该命令不断重复发送到SD卡,直到响应R1的Bit0(Idle)位为0,表示SD卡内部初始化处理完成。
                     当响应的Idle位为0时,SD卡就完全进入SPI模式了。当然重复发送命令CMD1是有次数限制的,
                     最大次数为宏定义SD_IDLE_WAIT_MAX.
*******************************************************************************************************************/
uchar SD_ActiveInit(void)
{
        uchar param[5] = {0,0,0,0,0xff},resp;
        unsigned int i = 0;
//        SPI_CS_Assert();

        do
    {                                                                                                        /* 发出CMD1, 查询卡的状态s */
        SD_SendCmd(CMD1, param);
        resp= SPI_RecByte();
  
        i++;
    }
        while ((resp!=0x00) && (i < SD_IDLE_WAIT_MAX));
                                                                                                                /* CMD1的响应为0x00 */
        SPI_CS_Deassert();                                                                                                       
    if (i >= SD_IDLE_WAIT_MAX){
            Prints("error:cmd1 timeout\n");
            return SD_ERR_TIMEOUT_WAITIDLE;                                        /* 超时,返回错误 time out,return error */
        }
        SPI_SendByte(0xff);
        return SD_NO_ERR;
}


/*******************************************************************************************************************
** 函数名称: INT8U SD_Initialize()                                Name:          INT8U SD_Initialize()
** 功能描述: 初始化SD卡                                                        Function: initialize sd card
** 输   入: 无                                                                        Input:          NULL
** 输   出: 0:   正确    >0:   错误码                          Output:          0:  right                >0:  error code
********************************************************************************************************************/
uchar SD_Initialize(void)
{
//        uchar recbuf[4],ret;
    uchar ret=0;
                                                        /* 初始化读写SD卡的硬件条件 Initialize the hardware that access SD Card */
        Prints("enter ini\n");
       
    ret = SD_ResetSD();                                                                /* 5. 发出CMDO命令复位SD卡 send CMD0 command to reset sd card */
    if (ret != SD_NO_ERR)
        return ret;                                                                       
       
        Prints("reset end\n");
        ret = SD_ActiveInit();                                                        /* 6. 激活卡进入初始化过程. active card initialize process */
        if (ret != SD_NO_ERR)
                return ret;
        
//          ret = SD_ReadOCR(4, recbuf);                                          /* 7. 读OCR寄存器,查询卡支持的电压值 read OCR register,get the supported voltage */
//   if (ret != SD_NO_ERR)
  //      return ret;
   
  //  if ((recbuf[1] & MSK_OCR_33) != MSK_OCR_33)
   //     return SD_ERR_VOL_NOTSUSP;                                        /* 不支持3.3V,返回错误码  not support 3.3V,return error code */
   
    SPI_ClkMax();                                                                        /* 8. 设置SPI时钟到最大值 set SPI clock to maximum */
        

//    ret = SD_SetBlockLen(SD_BLOCKSIZE);                                /* 9. 设置块的长度: 512Bytes Set the block length: 512Bytes */
//    if (ret != SD_NO_ERR)  
//        return ret;
        
//        return (SD_GetCardInfo());                                                /* 10. 读CSD寄存器,获取SD卡信息 read CSD register, get the information of SD card */
        return 0;
}

void main()
{

        uchar rec_code=0x0;
        uchar buffer[128]={0xff};
        uchar i=0;
//        unsigned long len=128;
//        P1M0=0Xff;
//        P1M1=0Xff;
       
        ComInit();
//        CS=0;
//        P1=0XFF;
//        while(1);
//        PrintNum(0xf0);
//        SPCTL=0XD0;           //CLK/4
//        SPCTL=0XD2;  //CLK/64
        SPI_Clk400k();
        SPSTAT=0XC0;                          //spi中断标志清零
        IE2|=0x02;  //使能spi中断
        EA=1;
       

//        SPI_SendByte(0xff);
/*        PrintNum(0x0f);
        PrintNum(SPI_SendByte(0x00));
        PrintNum(SPI_SendByte(0xff));
        while(1);
*/
        rec_code=SD_Initialize();
        PrintNum(rec_code);
        Prints("\t\n");
//        SPI_ClkMax();
/*        rec_code=SD_ReadCID(16,buffer);
        PrintNum(rec_code);
        Prints("\t\n");
        if(rec_code==0){
                for(i=0;i<16;i++){
                         PrintNum(buffer[i]);
                        Prints("\t");
       
                }
        }
*/
        while(1){
         //        PrintNum(0xf0);
         ;

        }


}

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

257

主题

271

帖子

0

粉丝