⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sd.c

📁 sd卡底层的操作子程序
💻 C
字号:
//#include "common.h"
#include "sd.H"
#include "Display.h"
#include "Ecs08.H"
//extern unsigned char xdata DBUF[BUFFER_LENGTH];
//================================================================
void SpiInit(void)
{

	// master mode
	// clock = f/4
	// select clock phase positive-going in middle of data
	// Data order MSB first
	// enable SPI
	 SPCR=0X50;

}
//============================================================
//硬件SPI往SD卡写一字节
void SdSpiWrite(unsigned char  Byte)
{
  SPDR = Byte;
  while (!(SPSR&0x80));
  //SPSR = SPSR&0x3f;

}
//================================================================
//硬件SPI从SD卡读一字节
unsigned char SdSpiRead()
{
 unsigned char Byte;
 SPDR = 0xFF;
 while (!(SPSR&0x80));
 Byte = SPDR;
 //SPSR = SPSR&0x3f;
 return Byte;
}

//================================================================
//SPI读SD卡响应
unsigned char SdSpiResponse()
{
  unsigned char i=0,response;

  while(i<=8)
  {
    response=SdSpiRead();
    if(response==0x00)
      break;
    if(response==0x01)
      break;
    i++;
  }
  return response;
}
//================================================================
void SdSpiCommand(unsigned char command, unsigned long argument, unsigned char CRC)
{
  //SD_CS=0;
  SdSpiWrite(command|0x40);
  SdSpiWrite(((unsigned char *)&argument)[0]);
  SdSpiWrite(((unsigned char *)&argument)[1]);
  SdSpiWrite(((unsigned char *)&argument)[2]);
  SdSpiWrite(((unsigned char *)&argument)[3]);
  SdSpiWrite(CRC);
  //SD_CS=1;
}

//============================================================
//往SD卡定一字节 www.mcusky.com
void SdWrite(unsigned char  n)
{

  unsigned char i;
  SD_CS=0;
  for(i=8;i;i--)
   {
    SD_CLK=0;
    SD_DI=(n&0x80);
    n<<=1;
    SD_CLK=1;
   }
  SD_DI=1;
  SD_CS=1;
}
//================================================================
//从SD卡读一字节 www.mcusky.com
unsigned char SdRead()
{
 unsigned char n,i;
 SD_CS=0;
 for(i=8;i;i--)
  {
   SD_CLK=0;
   SD_CLK=1;
   n<<=1;
   if(SD_DO) n|=1;

  }
  SD_CS=1;
 return n;
}
//================================================================
//读SD卡响应 www.mcusky.com
unsigned char SdResponse()
{
  unsigned char i=0,response;
  SD_CS=0;
  while(i<=8)
  {
    response=SdRead();
    if(response==0x00)
      break;
    if(response==0x01)
      break;
    i++;
  }
  SD_CS=1;
  return response;
}
//================================================================
void SdCommand(unsigned char command, unsigned long argument, unsigned char CRC)
{

  SdWrite(command|0x40);
  SdWrite(((unsigned char *)&argument)[0]);
  SdWrite(((unsigned char *)&argument)[1]);
  SdWrite(((unsigned char *)&argument)[2]);
  SdWrite(((unsigned char *)&argument)[3]);
  SdWrite(CRC);
}
//================================================================
unsigned char SdInit(void)
{
  int delay=0, trials=0;
  unsigned char i;
  unsigned char response=0x01;

  SD_CS=1;
  for(i=0;i<=9;i++)
    SdWrite(0xff);
  SD_CS=0;

  //Send Command 0 to put MMC in SPI mode
  SdCommand(0x00,0,0x95);


  response=SdResponse();

  if(response!=0x01)
   {
    return 0;
   }

  while(response!=0x00)
  {
    SD_CS=1;
    SdWrite(0xff);
    SD_CS=0;
    SdCommand(0x01,0x00ffc000,0xff);
    response=SdResponse();
  }

  SD_CS=1;
  SdWrite(0xff);
  return 1;
}
//================================================================
/*
unsigned char SdWriteBlock(unsigned char DRamA16,unsigned char  *Block, unsigned long address)
{
  unsigned char  count;
  unsigned char dataResp;
  //Block size is 512 bytes exactly

  SleDRam(DRamA16);

  //Then send write command
  SdSpiCommand(0x18,address,0xff);

  if(SdSpiResponse()==00)
  {

	SdSpiWrite(0xff);
    //command was a success - now send data
    //start with DATA TOKEN = 0xFE
    SdSpiWrite(0xfe);
    //now send data
    for(count=0;count<128;count++)
    {
          SdSpiWrite(*Block++);
	  SdSpiWrite(*Block++);
	  SdSpiWrite(*Block++);
	  SdSpiWrite(*Block++);
    }
    //data block sent - now send checksum
    SdSpiWrite(0xff);
    SdSpiWrite(0xff);
    //Now read in the DATA RESPONSE token
    dataResp=SdSpiRead();
    //Following the DATA RESPONSE token
    //are a number of BUSY bytes
    //a zero byte indicates the MMC is busy

    while(SdSpiRead()==0);

    dataResp=dataResp&0x1f;	//mask the high byte of the DATA RESPONSE token


    if(dataResp==0x0b)
      {
      //printf("DATA WAS NOT ACCEPTED BY CARD -- CRC ERROR\n");
      return 0;
      }
    if(dataResp==0x05)
      return 1;

    //printf("Invalid data Response token.\n");
    return 0;
 }
  //printf("Command 0x18 (Write) was not received by the MMC.\n");
  return 0;
}*/
//=======================================================================
unsigned char SdReadBlock(unsigned char DRamA16,unsigned char xdata *RamAddr, unsigned long address)
{
   unsigned char count;
    //unsigned char  tmp8[4];
    //unsigned char xdata *ptr0;
  //Block size is 512 bytes exactly
  //SleNothing();PRAM_CE = 0;
   //count= DRamA16;
  //SleDRam(DRamA16);
  switch(DRamA16)
   {case 0x0: SleNothing();SleDRam(DRam0);break;
    case 0x1: SleNothing();SleDRam(DRam1);break;
    case 0x2: SleNothing();PRAM_CE = 0;break;
    default : return 0;
   }

  SD_CS=0;//这句不能拿掉,去掉使SD卡不能读写
  //Then send write command
  SdSpiCommand(0x11,address,0xff);

  if(SdSpiResponse()==00)
  {
    //command was a success - now send data
    //start with DATA TOKEN = 0xFE
    while(SdSpiRead()!=0xfe);

    for(count=0;count<128;count++)
    {
          *RamAddr++=SdSpiRead();
	  *RamAddr++=SdSpiRead();
	  *RamAddr++=SdSpiRead();
	  *RamAddr++=SdSpiRead();
           //if((count==31)||(count==63)||(count==95)) {RamAddr=RamAddr-128;}
    }
    //data block sent - now send checksum

    SdSpiRead();
    SdSpiRead();
    //Now read in the DATA RESPONSE token

    //SdSpiRead();
    return 1;
 }
  return 0;
}

//=======================================================================
/*
unsigned char SdReadProgram(unsigned long sector,unsigned char xdata *pRamAddr)
{
   unsigned char count;
    //unsigned char  tmp8[4];
    //unsigned char xdata *ptr0;
   //Block size is 512 bytes exactly
   SleNothing();
   //PRAMEN();
   sector = sector*512;
   PRAM_CE = 0;
   //PRAMEN();
  //Then send write command
  SdSpiCommand(0x11,sector,0xff);

  if(SdSpiResponse()==00)
  {
    //command was a success - now send data
    //start with DATA TOKEN = 0xFE
    while(SdSpiRead()!=0xfe);

    for(count=0;count<128;count++)
    {
          *pRamAddr++=SdSpiRead();
	  *pRamAddr++=SdSpiRead();
	  *pRamAddr++=SdSpiRead();
	  *pRamAddr++=SdSpiRead();
           //if((count==31)||(count==63)||(count==95)) {RamAddr=RamAddr-128;}
    }
    //data block sent - now send checksum

    SdSpiRead();
    SdSpiRead();
    //Now read in the DATA RESPONSE token

    //SdSpiRead();
    return 1;
 }
  return 0;
}
 */
/*
void SdReadOCR(unsigned char *Block)
{
   //unsigned char count;

  SD_CS=0;
  //Then send  command
  SdSpiCommand(0x3A,0,0xff);

  if(SdSpiResponse()==00)
  {


      //for(count=0;count<3;count++)
      *Block++=SdSpiRead();
      *Block++=SdSpiRead();
      *Block++=SdSpiRead();
      *Block++=SdSpiRead();
      //}
    //SD_CS=1;
    SdSpiRead();

  }

}


/*
//================================================================
void ComSendByte(unsigned char c)
{
	SBUF=c;
	while(!TI);
	TI=0;
}
//================================================================
void DelayMs(unsigned char nFactor)
{
 return;

	unsigned char i;
	unsigned int j;

	for(i=0; i<nFactor; i++)
		{
		for(j=0;j<1000;j++)
		         j=j;
		}

} */

unsigned int LSwapINT16(unsigned short dData1,unsigned short dData2)
{
    unsigned int xdata dData;
    dData = ((dData2<<8)&0xff00)|(dData1&0x00ff);
	return dData;
}

unsigned long LSwapINT32(unsigned long dData1,unsigned long dData2,unsigned long dData3,unsigned long dData4)
{
    unsigned long xdata dData;
    dData = ((dData4<<24)&0xff000000)|((dData3<<16)&0xff0000)|((dData2<<8)&0xff00)|(dData1&0xff);
	return dData;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -