打印

sd卡的spi初始化问题~~~~~~高手帮忙啊

[复制链接]
3893|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
mcu_protel|  楼主 | 2008-4-19 11:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
给sd卡初始化为spi模式
cmd0,cmd1都没有正确响应
每次响应都不是0x01和0x00,程序中加上响应判断就初始化不成功
如果忽略响应,依次发送cmd0,cmd1,那么初始化就很成功,不过每个命令都要反复发送多次才可以,只发送一次也是不成功

各位高手,你们帮帮我啊,郁闷了很多天了

相关帖子

沙发
mcu_protel|  楼主 | 2008-4-19 11:44 | 只看该作者

进来的有什么

想法都说说啊

使用特权

评论回复
板凳
古道热肠| | 2008-4-19 12:11 | 只看该作者

用我用的SD卡驱动试试吧

原因自己去找,提醒一下SD卡未初始化时,SPI通信CLK频率一定要低。
#include "..incincludes.h"

#include "New_sd.h"


sbit c_SPI_CS = P2^4;        //Sht-mp3 Config

//set MMC_Chip_Select to high (MMC/SD-Card Invalid)
#define SD_Disable()   c_SPI_CS = 1
//set MMC_Chip_Select to low (MMC/SD-Card Active)
#define SD_Enable()    c_SPI_CS = 0

sbit c_SPI_SI = P1^5;
sbit c_SPI_SO = P1^6;
sbit c_SPI_CLK = P1^7;

sbit c_SD_In = P2^7;
sbit c_SD_WP = P2^6;
sbit c_SD_Power = P2^3;

#define Macro_Set_SI_High()      c_SPI_SI = 1
#define Macro_Set_SI_Low()      c_SPI_SI = 0
#define Macro_Set_CLK_High()      c_SPI_CLK = 1
#define Macro_Set_CLK_Low()      c_SPI_CLK = 0

//bool bSPICLK_LowSpeed;

static void SD_PowerOn(void)
{
    c_SD_Power = 0;
}
/*
static void SD_PowerOff(void)
{
    c_SD_Power = 1;
}
*/
//extern uint8 BUFFER[512];

uint8 SD_SPI_ReadByte(void);
void SD_SPI_WriteByte(uint8 ucSendData);


//#define SPI_ReadByte()  SD_SPI_ReadByte()
//#define SPI_TransferByte(x) SD_SPI_WriteByte(x)
/*
static uint8 SPI_ReadByte(void)
{
    uchar ucReadData;
    uchar ucCount;

    ucReadData = 0;
    Macro_Set_SI_High();

    for(ucCount=0; ucCount<8; ucCount++)
    {
        ucReadData <<= 1;
            //降低时钟频率
        Macro_Set_CLK_Low();
        //降低时钟频率
//        if(bSPICLK_LowSpeed)
//        {
//            Delay_100us();
//        }

        Macro_Set_CLK_High();
//        if(bSPICLK_LowSpeed)
//        {
//            Delay_100us();
//        }
    
        if(c_SPI_SO)
        {
            ucReadData |= 0x01;
        }
    }

    return(ucReadData);

 //  SPDR = 0xFF;
 //  while (!(SPSR & 0x80)); 
 //  return SPDR;
}
static void SPI_TransferByte(uint8 ucSendData)  
{   
    uchar ucCount;
    uchar ucMaskCode;

    ucMaskCode = 0x80;
    for(ucCount=0; ucCount<8; ucCount++)
    {
        Macro_Set_CLK_Low();

        if(ucMaskCode & ucSendData)
        {
            Macro_Set_SI_High();
        }
        else
        {
            Macro_Set_SI_Low();
        }
        //降低时钟频率
//        if(bSPICLK_LowSpeed)
//        {
//            Delay_100us();
//        }

        Macro_Set_CLK_High();
        ucMaskCode >>= 1;

        //降低时钟频率
//        if(bSPICLK_LowSpeed)
//        {
//            Delay_100us();
//        }

    }

 //SPDR=cmp1;
 //while(!(SPSR&(1<<SPIF)));    

*/

static uint8 SPI_ReadByte(void)
{
    uchar ucReadData;
    uchar ucCount;

    ucReadData = 0;
    Macro_Set_SI_High();

    for(ucCount=0; ucCount<8; ucCount++)
    {
        ucReadData <<= 1;
            //降低时钟频率
        Macro_Set_CLK_Low();
        //降低时钟频率
//        if(bSPICLK_LowSpeed)
//        {
//            Delay_100us();
//        }

        Macro_Set_CLK_High();
//        if(bSPICLK_LowSpeed)
//        {
//            Delay_100us();
//        }
    
        if(c_SPI_SO)
        {
            ucReadData |= 0x01;
        }
    }

    return(ucReadData);

 //  SPDR = 0xFF;
 //  while (!(SPSR & 0x80)); 
 //  return SPDR;
}
static void SPI_TransferByte(uint8 ucSendData)  
{   
    uchar ucCount;
    uchar ucMaskCode;

    ucMaskCode = 0x80;
    for(ucCount=0; ucCount<8; ucCount++)
    {
        Macro_Set_CLK_Low();

        if(ucMaskCode & ucSendData)
        {
            Macro_Set_SI_High();
        }
        else
        {
            Macro_Set_SI_Low();
        }
        //降低时钟频率
//        if(bSPICLK_LowSpeed)
//        {
//            Delay_100us();
//        }

        Macro_Set_CLK_High();
        ucMaskCode >>= 1;

        //降低时钟频率
//        if(bSPICLK_LowSpeed)
//        {
//            Delay_100us();
//        }

    }

 //SPDR=cmp1;
 //while(!(SPSR&(1<<SPIF)));    




void SD_Port_Init(void)
//****************************************************************************
{

    c_SPI_SO = 1;
    c_SD_In = 1;
    c_SD_WP = 1;

     SD_PowerOn();
}

//****************************************************************************
//Send a Command to MMC/SD-Card
//Return: the second byte of response register of MMC/SD-Card
uint8 Write_Command_SD(uint8 *cmd)
//****************************************************************************
{
        uint8 tmp,i;
        uint8 retry=0;
        SD_Disable();
        SPI_TransferByte(0xFF);
        SD_Enable();
        for(i=0;i<6;i++)
        {
        SPI_TransferByte(*cmd++);
        }
        SPI_ReadByte();
        
        do{
                tmp = SPI_ReadByte();
        }while((tmp==0xff)&&(retry++ <100));
        return(tmp);
}

//****************************************************************************
//Send a Command to MMC/SD-Card
//Return: the second byte of response register of MMC/SD-Card
uint8 Write_Command_SD_HighSpeed(uint8 *cmd)
//****************************************************************************
{
        uint8 tmp,i;
        uint8 retry=0;
        SD_Disable();
        SD_SPI_WriteByte(0xFF);
        SD_Enable();
        for(i=0;i<6;i++)
        {
        SD_SPI_WriteByte(*cmd++);
        }
        SD_SPI_ReadByte();
        
        do{
                tmp = SD_SPI_ReadByte();
        }while((tmp==0xff)&&(retry++ <100));
        return(tmp);
}

//****************************************************************************
//Routine for Init MMC/SD card(SPI-MODE)
uint8 SD_Init(void)
//****************************************************************************
{
        uint8 retry,temp;
        uint8 i;

       uint8  CMD[] = {0x40,0x00,0x00,0x00,0x00,0x95};
   SD_Port_Init(); //Init SPI port  

//   for (i = 0; i < 200; i++) asm("nop"); //Wait MMC/SD ready...
      for (i = 0; i < 200; i++)
        {
            _nop_();
        }
   //Active SPI bus at low speed 
 //  SPCR=0x53; //SPI Master,MSB First 
 //  SPSR=0x00; //double speed disable,Fsck=Fosc/128 

   for (i = 0; i < 16; i++)
      SPI_TransferByte(0xff); //send 74 clock at least!!! 
    
   //Send Command CMD0 to MMC/SD Card
   SD_Enable();
   retry = 0;
   do
   { //retry 200 times to send CMD0 command 
     temp = Write_Command_SD(CMD);
     if (retry++ == 200) 
       return INIT_CMD0_ERROR;//CMD0 Error!
   }
   while (temp != 1);
   
   //Send Command CMD1 to MMC/SD-Card
   CMD[0] = 0x41; //Command 1
   CMD[5] = 0xFF;
   retry = 0;
   do
   { //retry 100 times to send CMD1 command 
     temp = Write_Command_SD(CMD);
     if (retry++ == 100) 
       return INIT_CMD1_ERROR;//CMD1 Error!
   } 
   while (temp != 0);
   
   //Active High-speed SPI mode(Fsck=Fosc/2) 
 //  SPCR = 0x50; 
 //  SPSR = 0x00; 

   SD_Disable();  //set MMC_Chip_Select to high 
   return INIT_OK; //All commands have been taken.
}

uint8 SD_Read_Block(uint8 *CMD,uint8  *Buffer,uint16 Bytes)
//****************************************************************************
{  
   uint16 i;
   uint8 retry, temp;
    
   //Send Command CMD to MMC/SD-Card
   retry=0;

//#if 1
   do
   {  //Retry 100 times to send command.
//      temp=Write_Command_SD(CMD);
        temp=Write_Command_SD_HighSpeed(CMD);
      if(retry++ == 100) 
        return READ_BLOCK_ERROR; //block write Error!
   }
   while (temp != 0); 
               
   //Read Start Byte form MMC/SD-Card (FEh/Start Byte)
   while (SPI_ReadByte() != 0xfe);
//#endif


   //Read blocks(normal 512Bytes) to MMC/SD-Card
#if 1
   for (i = 0; i < Bytes; i++)                //int count for loop cost 13 machine cycle
   {
//      *Buffer++ = SPI_ReadByte();            //Cost 70 Machine Cycle
                                            //When define point is a Xdata point then Cost 62 Machine Cycle
      *Buffer++ = SD_SPI_ReadByte();            //Cost 70 Machine Cycle
     // put_c(*Buffer);
   }
#endif 

/*
    i = Bytes;
    while(i--)                                //When Delete {} 2 Machine Cycle is save.

      *Buffer++ = SPI_ReadByte();            //Cost 70 Machine Cycle
*/
       

   //CRC-Byte
   SPI_ReadByte();//CRC - Byte 
   SPI_ReadByte();//CRC - Byte
    
   //set MMC_Chip_Select to high (MMC/SD-Card invalid)
   SD_Disable();
   return READ_BLOCK_OK;
}

//****************************************************************************
//Routine for writing a Block(512Byte) to MMC/SD-Card
//Return 0 if sector writing is completed.
uint8 SD_read_sector(uint32 addr,uint8  *Buffer)
//****************************************************************************
{
       //Command 16 is reading Blocks from MMC/SD-Card
   uint8  CMD[] = {0x51,0x00,0x00,0x00,0x00,0xFF}; 
   
//   asm("cli"); //clear all interrupt.
   //Address conversation(logic block address-->byte address)  
   addr = addr << 9; //addr = addr * 512

   CMD[1] = ((addr & 0xFF000000) >>24 );
   CMD[2] = ((addr & 0x00FF0000) >>16 );
   CMD[3] = ((addr & 0x0000FF00) >>8 );

   return SD_Read_Block(CMD, Buffer, 512);
        
}

/*
uint8 SD_write_sector(uint32 addr,uint8 *Buffer)
//****************************************************************************
{  
   uint8 tmp,retry;
   uint16 i;
   //Command 24 is a writing blocks command for MMC/SD-Card.
   uint8 CMD[] = {0x58,0x00,0x00,0x00,0x00,0xFF}; 
   
   asm("cli"); //clear all interrupt.
   addr = addr << 9; //addr = addr * 512
    
   CMD[1] = ((addr & 0xFF000000) >>24 );
   CMD[2] = ((addr & 0x00FF0000) >>16 );
   CMD[3] = ((addr & 0x0000FF00) >>8 );

   //Send Command CMD24 to MMC/SD-Card (Write 1 Block/512 Bytes)
   retry=0;
   do
   {  //Retry 100 times to send command.
      tmp = Write_Command_SD(CMD);
      if(retry++ == 100) 
        return(tmp); //send commamd Error!
   }
   while(tmp != 0); 
   
   //Before writing,send 100 clock to MMC/SD-Card
   for (i = 0; i < 100; i++)
      SPI_ReadByte();
    
   //Send Start Byte to MMC/SD-Card
   SPI_TransferByte(0xFE);    
    
   //Now send real data Bolck (512Bytes) to MMC/SD-Card
   for (i = 0; i < 512; i++)
      SPI_TransferByte(*Buffer++); //send 512 bytes to Card

   //CRC-Byte 
   SPI_TransferByte(0xFF); //Dummy CRC
   SPI_TransferByte(0xFF); //CRC Code
   
    
   tmp=SPI_ReadByte();   // read response
   if((tmp & 0x1F) != 0x05) // data block accepted ?
   {
     SD_Disable();
     return WRITE_BLOCK_ERROR; //Error!
   }
   //Wait till MMC/SD-Card is not busy
   while (SPI_ReadByte() != 0xFF){};
    
   //set MMC_Chip_Select to high (MMC/SD-Card Invalid)
   SD_Disable();
   return 0;

*/
extern unsigned char xdata Page_Buf[512];        //文件缓冲区。

void SD_SPI_WriteByte(uint8 ucSendData);

//测试SD卡SPI接口性能
void TestSD_SPIFunc(void)
{
    uchar ucCount;
    uchar ucReadData;


    ucCount = 0;        //开始

    for(ucCount=0; ucCount<10; ucCount++)
    {
//        SPI_TransferByte(0x88);            //用C语言实现的写字节机器周期数为188
        SD_SPI_WriteByte(0x88);
                                        //用C51的bData变量,采用位指令直接传送操作,共用机器机器49
    }

    for(ucCount=0; ucCount<50; ucCount++)
    {
        ucReadData = SPI_ReadByte();    //用C语言实现的SPI读字节机器赌周期为154
                                        //自用C51的bData变量,采用位指令操作读字节机器周期为49

    }
    ucCount= 88;        //结束
    SD_read_sector(0,Page_Buf);
}

使用特权

评论回复
地板
好不厉害| | 2008-4-19 13:27 | 只看该作者

弱问一句

收藏夹咋不能用了
21ic经常间歇性抽风啊

使用特权

评论回复
5
mcspic| | 2008-4-19 14:17 | 只看该作者

RE:

你初始化时SPI的速度是多少呢,好象最高不超过400KHZ。

使用特权

评论回复
6
mcu_protel|  楼主 | 2008-4-21 09:37 | 只看该作者

非常感谢大家的帮助

现在已经初始化通过了,我换了一个sd卡就可以了,程序没问题,可能是硬件问题吧

使用特权

评论回复
7
mcu_protel|  楼主 | 2008-4-21 09:58 | 只看该作者

顺便问一下

使用特权

评论回复
8
mcu_protel|  楼主 | 2008-4-21 10:01 | 只看该作者

顺便问一下古道热肠

您使用VS1003播放的mp3最高速率是多大?
我用的stc单片机,晶振26M的放128k都卡的要命,64k没问题真是不理想啊!!

使用特权

评论回复
9
mcu_protel|  楼主 | 2008-4-21 15:19 | 只看该作者

古道兄呢?

古道兄

使用特权

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

本版积分规则

6

主题

27

帖子

0

粉丝