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

📄 dsp28_spi_sd.c

📁 DSP2812 SPI接口控制SD卡读写操作
💻 C
字号:
 
#include "DSP28_Device.h"

#define SPI_SEL_REG *(Uint16 *)0x2004
#define SPI_SD  0X04
/////////////////////////////////////////////////

void delay(unsigned int);
void ldelay(unsigned int);
///////////////////////////////////////////
unsigned int DBUF[512];
//============================================================
void SPI_ENABLE()
{
	SPI_SEL_REG=SPI_SD;	//使能SPI_SD
}
/////////////////////////////////////////////////
void SPI_DISABLE()
{
	SPI_SEL_REG=0xFF;	//DISABLE SPI_SD
}
//////////////////////////////////////////////
//往SD卡定一字节 
void SdWrite(unsigned int  n)
{
    
  	
    while (1)
    {
	if(Spi_TxReady() == 1)
		{
		SpiaRegs.SPITXBUF =( n<<8);
		break;
		}
	}
	delay(500);  
   
} 

/////////////////////////////////////////////  
//从SD卡读一字节 
unsigned int SdRead()
{
 	unsigned int n;
 	
 	SdWrite(0xff); //因为读写是同时进行的,也就是循环缓存,只有写了之后,数据才会输出
 	
 	while (1)
    {
 		if(Spi_RxReady()==1)
 		{
 		n=SpiaRegs.SPIRXBUF&0x00ff;
 		break;
 		}
 	}
 	delay(500); 
 	return n;
}
///////////////////////////////////////////////
//读SD卡响应 
unsigned int SdResponse()
{
  unsigned int i=0,response;
  
  while(i<=8)
  {
    response=(SdRead()&0x00ff);
    if(response==0x0000)
      break;
    if(response==0x0001)
      break;
    i++;
  }
  return response;
}  
///////////////////////////////////////////////
void SdCommand(unsigned int command, unsigned long argument, unsigned int CRC)
{
  
  SdWrite(command|0x40);
  SdWrite(((unsigned int *)&argument)[0]);
  SdWrite(((unsigned int *)&argument)[0]>>8);
  SdWrite(((unsigned int *)&argument)[1]);
  SdWrite(((unsigned int *)&argument)[1]>>8);
  SdWrite(CRC);
}
///////////////////////////////////////////////////////////////////////////////
unsigned int SdInit(void)
{
 
  unsigned int i;
  unsigned int response=0x0001;
   
  delay(1000); //wait SD card ready
  SPI_ENABLE();
  for(i=0;i<=16;i++)
    SdWrite(0xff);  //send 74 clock at least!!!
  SPI_DISABLE(); 
  SdWrite(0xff);  
  SdWrite(0xff);  ///delay
    
     
  SPI_ENABLE();    
  //Send Command 0 to put MMC in SPI mode CMD0
  SdCommand(0x00,0,0x95);

  
  response=SdResponse();
  
  if(response!=0x0001)
   {
    return 0;
   } 
  
  while(response==0x0001)  //CMD1
  {
    SPI_DISABLE();
    SdWrite(0xff);
   SPI_ENABLE();// SPI_ENABLE();//SD_CS=0;
    SdCommand(0x01,0x00ffc000,0xff);
    response=SdResponse();
  } 
    
  SPI_DISABLE();
  SdWrite(0xff);
  return 1;  
}

//================================================================
unsigned int SdWriteBlock(unsigned int *Block, unsigned long address)
{
  unsigned int  count;
  unsigned int dataResp;
  //Block size is 512 bytes exactly
  //First Lower SS
  
  SPI_ENABLE();//SD_CS=0;
  //Then send write command
  SdCommand(0x18,address,0xff);
  
  if(SdResponse()==00)
  {
    SdWrite(0xff);
	SdWrite(0xff);
	SdWrite(0xff);
    //command was a success - now send data
    //start with DATA TOKEN = 0xFE
    SdWrite(0xfe);
    //now send data
    for(count=0;count<128;count++)
    {
      SdWrite(*Block++);
	  SdWrite(*Block++);
	  SdWrite(*Block++);
	  SdWrite(*Block++);
    }
    //data block sent - now send checksum
    SdWrite(0xff);
    SdWrite(0xff);
    //Now read in the DATA RESPONSE token
    dataResp=SdRead();
    //Following the DATA RESPONSE token
    //are a number of BUSY bytes
    //a zero byte indicates the MMC is busy

    while(SdRead()==0);

    dataResp=dataResp&0x000f;	//mask the high byte of the DATA RESPONSE token
    SPI_DISABLE();//SD_CS=1
    SdWrite(0xff);
    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 int SdReadBlock(unsigned int *Block, unsigned long address)
{
   unsigned int count;
  //Block size is 512 bytes exactly
  //First Lower SS
  
//  printf("MMC_read_block\n");
  
  SPI_ENABLE();//SD_CS=0;
  //Then send write command
  SdCommand(0x11,address,0xff);
  
  if(SdResponse()==00)
  {
    //command was a success - now send data
    //start with DATA TOKEN = 0xFE
    while(SdRead()!=0xfe);

    for(count=0;count<128;count++)
    {
      *Block++=SdRead();
	  *Block++=SdRead();
	  *Block++=SdRead();
	  *Block++=SdRead();
    }
    //data block sent - now send checksum
    SdRead();
    SdRead();
    //Now read in the DATA RESPONSE token
    SPI_DISABLE();//SD_CS=1
    SdRead();
    return 1;
 }
//  printf("Command 0x11 (Read) was not received by the MMC.\n");
  return 0;
}

///////////////////////////////////////////
void main(void)
{   
    unsigned int i;
	InitSysCtrl();			//初始化系统

	DINT;					//关中断 
	IER = 0x0000;
	IFR = 0x0000;

	InitPieCtrl();			//初始化PIE控制寄存器
	InitPieVectTable();		//初始化PIE参数表 
	InitPeripherals();		//初始化外设寄存器 
	InitGpio();           	//初始化IO口
   	InitSpi();	          	//初始化SPI	

	EINT;					//Enable INTM
	ERTM;					//Enable DBGM
	GpioDataRegs.GPASET.all|=0x8000;	
   

	SPI_SEL_REG=SPI_SD;	//使能SPI_SD
   	SdInit();
    SdReadBlock(DBUF, 0<<9);
    delay(200);
   	for (i=0;i<512;i++) DBUF[i]=i;
    SdWriteBlock(DBUF, 1<<9);
    for (i=0;i<512;i++) DBUF[i]=0;
    SdReadBlock(DBUF, 1<<9);
    delay(200);
} 	

///////////////////////////////////////////////////////
	
void ldelay(unsigned int k)
{
    while(k>0)
    {
        k--;
        delay(50000);
	}
}	

void delay(unsigned int t)
{
	while(t>0)
		t--;
}

⌨️ 快捷键说明

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