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

📄 sd.c

📁 基于LPC2148实现SD卡读写和FAT文件系统的实现
💻 C
字号:
#include"lpc214x.h"
#include "PCF8833.h"

#define SD_Disable() IO0SET |= 1 << 20  //SD Chip Select Pin is P0.7
#define SD_Enable() IO0CLR |= 1 << 20 

INT8U CMD[]={0x40, 0x00, 0x00, 0x00, 0x00, 0x95};


INT8U SPI_RW(INT8U data) 
{ 
	SSPDR = data;
	while((SSPSR & 0x01) == 0);     	 
	return(SSPDR);
}

void spi_init (void)
{

   INT32U i;

   /* SSEL is GPIO, output set to high. */
   IODIR0  |= 1<<20;
   IOSET0   = 1<<20;
   /* SCK1, MISO1, MOSI1 are SSP pins. */
   PINSEL1  = (PINSEL1 & ~0x000003FC) | 0x000000A8;

   /* Enable SPI in Master Mode, CPOL=1, CPHA=1 (Clock low-active). */
   SSPCR0 = 0x00C7;
   SSPCR1 = 0x0002;
   SSPCPSR = 0x7E;

   /* Send SPI Command with card not selected at 400 KBit. */
   for (i = 0; i < 16; i++) {
      SPI_RW (0xFF);
   }

   /* Enable SSP auto select. */
}


 
INT8U Write_Command_SD(INT8U *CMD) 
{
    INT8U i = 0, response = 1, retry = 0;
 
    SD_Disable();
    SPI_RW(0xff);
    SD_Enable();
    for(i = 0; i < 0x06; i++) 
    { 
    	SPI_RW(*CMD++);
    } 
    
    SPI_RW(0xff);
    
    do 
    {
    	response = SPI_RW(0xff);
        retry++;
    }
    while((response== 0xff) && (retry < 100)); 
    return(response);
}


INT8U SD_write_sector(INT32U Number_Sector, INT8U* Buffer) 
{  
    INT8U response,response_1,retry;
    INT16U i;
    //Command 24 is a writing blocks command for SD/SD-Card.
    INT8U CMD[] = {0x58, 0x00, 0x00, 0x00, 0x00, 0xFF}; 
	INT8U CMD_SET_BLOCKLEN[]={0x50,0x00,0x00,0x02,0x00,0xFF};	  //设定读取块大小 
	retry = 0;	
	SSPCPSR = 0x7E;
    do 
    {  //Retry 100 times to send command.
    	response = Write_Command_SD(CMD_SET_BLOCKLEN);
       	if(++retry >= 100)
     		return(1); //block read Error!
    }
    while(response != 0);

	SPI_RW(0XFF);
    
   
    Number_Sector  <<= 9; //addr = addr * 512
         

    CMD[1] = ((Number_Sector & 0xFF000000) >> 24 );
    CMD[2] = ((Number_Sector & 0x00FF0000) >> 16 );
    CMD[3] = ((Number_Sector & 0x0000FF00) >> 8 );
    CMD[4] = ((Number_Sector & 0x000000FF) >> 0) ;
    //Send Command CMD24 to SD/SD-Card (Write 1 Block/512 Bytes)
    retry = 0;
    do 
    {  //Retry 100 times to send command.
       response = Write_Command_SD(CMD);
       if(++retry >= 100) 
       { 
           return(1); //send commamd Error!
       }
    }
    while(response != 0); 
    
  
//   for(i = 0; i < 20; i++)
       SPI_RW(0xff);
         
    //Send Start Byte to SD/SD-Card
    SPI_RW(0xfe); 
	  
    SSPCPSR = 0x04;    
    //Now send real data Bolck (512Bytes) to SD/SD-Card
    for(i = 0; i < 512; i++)
       SPI_RW(* Buffer++); //send 512 bytes to Card
 
    //CRC-Byte 
    SPI_RW(0xFF); //Dummy CRC
    SPI_RW(0xFF); //CRC Code
//    retry=0;
    
	do
	{
    response=SPI_RW(0xFF);//Read Response
	}
	while(response==0xff);
	
    do
	{
	     response_1=SPI_RW(0xFF);
	}
	while(response_1!=0xFF);
    SD_Disable();
	SPI_RW(0xff);
    if ((response&0x1f)!=0x05) return(1);

    return(0);

}

INT8U SD_Read_Block(INT8U *CMD, INT8U *Buffer, INT16U Bytes) 
{  
    INT16U i; 
    INT8U retry,response;
    INT16U Block_Len=0;
    INT8U CMD_SET_BLOCKLEN[]={0x50,0x00,0x00,0x00,0x00,0xFF};
    SSPCPSR = 0x7E; 
    if(Bytes != Block_Len)  
    {
        CMD_SET_BLOCKLEN[3] = (INT8U)((Bytes & 0x0000FF00) >> 8 );
    	CMD_SET_BLOCKLEN[4] = (INT8U)((Bytes & 0x000000FF) >> 0 );
    
    	retry = 0;	
    	do 
    	{  //Retry 100 times to send command.
    		response = Write_Command_SD(CMD_SET_BLOCKLEN);
        	if(++retry >= 100)
        		return(1); //block read Error!
    	}
    	while(response != 0);
    	Block_Len = Bytes;
    }
    //Send reads a block Command CMD to SD/SD-Card
    retry = 0;	
    do 
    {  
    	response = Write_Command_SD(CMD);
        if(++retry >= 100)
        	return(1); //block read Error!
    }
    while(response != 0);
                         
    //Read Start Byte form SD/SD-Card (FEh/Start Byte)
//    while(SPI_RW(0xff) != 0xfe) ; 
    retry=0;
    for(i=0;i<1000;i++)
	{
	    response=SPI_RW(0xff);
		retry++;
		if(response==0xfe)
		i=1000;
		if(retry==1000)  
		return(1);
	}
	
	SSPCPSR = 0x04;    
    //Write blocks(normal 512Bytes) to SD/SD-Card
    for(i = 0; i < Bytes; i++)
    	*Buffer++ = SPI_RW(0xff);
    
    //CRC-Byte
    SPI_RW(0xff);//CRC - Byte 
    SPI_RW(0xff);//CRC - Byte
         
    SD_Disable();
    return(0);
}



SD_INIT()
{
   INT8U retry, response;
   INT16U i;  
   for(i=0;i<250;i++) 
  __asm
  {
  	NOP
  }
  for(i = 0; i < 0x0f; i++)
  { 
  	SPI_RW(0xff); 
  }       
  //Send Command CMD0 to SD/SD Card
  retry = 0;
  do 
  { //retry 200 times to send CMD0 command 
    
    response = Write_Command_SD(CMD);			 //CMD0   响应为01 
    retry++;
  } 
  while((response != 1) && (retry < 200)); 

   retry=0;
   do
   {
        CMD[0]=0x77;
        CMD[5]=0x55;
        Write_Command_SD(CMD);	                  //CMD55 响应为01	 
        CMD[0]=0X69;
        response=Write_Command_SD(CMD);				  //ACMD41   响应为00   
		retry++;
   }
   while((response!=0)&&(retry<200)) ;
//  return(response);
}



void SD_WRITE(INT8U* Buffer,INT32U Number_Sector)
{
   INT8U retry, response;
   retry=0;
  do
  {
      response=SD_write_sector(Number_Sector,Buffer);
	  retry++;
   }
   while((response!=0x00)&&(retry<20))	;
}

void SD_READ(INT8U *Buffer, INT16U Bytes,INT32U Number_Sector)
{
   INT8U response,retry;
   INT8U CMD[]={0X51,0X00,0X00,0X00,0X00,0XFF};
   Number_Sector=Number_Sector<<9;
   CMD[1] = ((Number_Sector & 0xFF000000) >> 24 );
   CMD[2] = ((Number_Sector & 0x00FF0000) >> 16 );
   CMD[3] = ((Number_Sector & 0x0000FF00) >> 8 );
   CMD[4] = ((Number_Sector & 0x000000FF) >> 0) ;
   retry=0;
   do
   {
      response=SD_Read_Block(CMD,Buffer,Bytes);
	  retry++;
   }
   while((response!=0)&&(retry<100));
}

⌨️ 快捷键说明

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