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

📄 sd.c

📁 基于STC51通过GPS自主定位导航FAT文件系统程序
💻 C
字号:
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&SD卡驱动&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//*文件名称:sd.c

//*文件作用:SD卡驱动

//*文件作者:翟  鹏

//*创建日期:2004年5月
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&



#include <include.h>



static uchar bdata Data=0;
sbit Data0=Data^0;
sbit Data1=Data^1;
sbit Data2=Data^2;
sbit Data3=Data^3;
sbit Data4=Data^4;
sbit Data5=Data^5;
sbit Data6=Data^6;
sbit Data7=Data^7;

static uchar xdata CMD17[]={0x51,0x00,0x00,0x00,0x00,0xFF};//cmd17



//***********************************************************************************************************************
//函数作用:io口模拟spi
//参数说明:
//注意事项:
//返回说明:无
//***********************************************************************************************************************
static void sd_write(void)
{
	SD_CLK=0;
	SD_DI=Data7;
	SD_CLK=1;

	SD_CLK=0;
	SD_DI=Data6;
	SD_CLK=1;

	SD_CLK=0;
	SD_DI=Data5;
	SD_CLK=1;
	
	SD_CLK=0;
	SD_DI=Data4;
	SD_CLK=1;
	
	SD_CLK=0;
	SD_DI=Data3;
	SD_CLK=1;
	
	SD_CLK=0;
	SD_DI=Data2;
	SD_CLK=1;
	
	SD_CLK=0;
	SD_DI=Data1;
	SD_CLK=1;
	
	SD_CLK=0;
	SD_DI=Data0;
	SD_CLK=1;
}  
 
//***********************************************************************************************************************
//函数作用:io口模拟spi
//参数说明:
//注意事项:
//返回说明:无
//***********************************************************************************************************************
static void sd_read(void)
{
	SD_CLK=0;
	SD_CLK=1;
	Data7=SD_DO;

	SD_CLK=0;
	SD_CLK=1;
	Data6=SD_DO;
	
	SD_CLK=0;
	SD_CLK=1;
	Data5=SD_DO;
	
	SD_CLK=0;
	SD_CLK=1;
	Data4=SD_DO;
	
	SD_CLK=0;
	SD_CLK=1;
	Data3=SD_DO;
	
	SD_CLK=0;
	SD_CLK=1;
	Data2=SD_DO;
	
	SD_CLK=0;
	SD_CLK=1;
	Data1=SD_DO;
	
	SD_CLK=0;
	SD_CLK=1;
	Data0=SD_DO;
 }

//***********************************************************************************************************************
//函数作用:发送命令----在初始化时使用
//参数说明:
//注意事项:
//返回说明:无
//***********************************************************************************************************************
static uchar sd_send_cmd_init(uchar *cmd)
{
	uchar xdata a,timeout=0;

	SD_CS=1;
	Data=0xff;sd_write();
	SD_CS=0;
	
	Data=cmd[0];sd_write();
	Data=cmd[1];sd_write();
	Data=cmd[2];sd_write();
	Data=cmd[3];sd_write();
	Data=cmd[4];sd_write();
	Data=cmd[5];sd_write();
	
	Data=0xff;
	while(Data==0xff)
	{  
		sd_read();
		for(a=0;a<255;a++);
		for(a=0;a<255;a++);
		for(a=0;a<255;a++);
		if(timeout++>100)break;
	}
		
	return Data;
}

//***********************************************************************************************************************
//函数作用:发送命令----在读写数据时使用
//参数说明:
//注意事项:
//返回说明:无
//***********************************************************************************************************************
static uchar SD_Send_Cmd(void)
{
	uchar xdata timeout=0;
	
	SD_CS=1;
	Data=0xff;sd_write();
	SD_CS=0;
	
	Data=CMD17[0];sd_write();
	Data=CMD17[1];sd_write();
	Data=CMD17[2];sd_write();
	Data=CMD17[3];sd_write();
	Data=CMD17[4];sd_write();
	Data=CMD17[5];sd_write();

	Data=0xff;
	while(Data==0xff)
	{  
		sd_read();
		if(timeout++>100)break;
	}
				
	return Data;
}

//***********************************************************************************************************************
//函数作用:初始化
//参数说明:
//注意事项:
//返回说明:无
//***********************************************************************************************************************
uchar SD_Init(void)
{  
	uchar xdata retry;  
	uchar xdata CMD[]={0x40,0x00,0x00,0x00,0x00,0x95};//cmd0

	SD_CS=1;
	Data=0xff;sd_write();
	SD_CS=0;
	
	//Send the 1st command  	
	retry=0;
	while(sd_send_cmd_init(CMD)!=0x01)
	{
		dog();
		if(retry++>200)return 1;
	}
	//Send the 2nd command  
	retry=0;
	CMD[0]=0x41;
	CMD[5]=0xFF;
	while(sd_send_cmd_init(CMD)!=0x00)  
	{
		dog();
		if(retry++>200)return 2;
	}      
	//Send the third command  set block size
	retry=0;
	CMD[0]=0x50;
	CMD[3]=((512&0xFF00)>>8);
	CMD[4]=(512&0x00FF);
	CMD[5]=0xFF;
	while(sd_send_cmd_init(CMD)!=0x00)
	{
		dog();
		if(retry++>200)return 3;
	} 
	
	SD_CS=1;  
	return 0;  
}

//***********************************************************************************************************************
//函数作用:设置当前扇区地址
//参数说明:
//注意事项:
//返回说明:无
//***********************************************************************************************************************
void SD_Set_SectorAddr(ulong addr)
{	
	(ulong)addr<<=9;
	*((ulong *)&CMD17[1])=addr;
}

//***********************************************************************************************************************
//函数作用:读取当前扇区的某个字节
//参数说明:
//注意事项:
//返回说明:无
//***********************************************************************************************************************
uchar SD_Read_SectorByte(uint ByteAddr, uchar *ch)
{
	uint data a; 
	uchar data retry=0; 

	//Send the read command
	while(SD_Send_Cmd()!=0)
	{
		dog();
		if(retry++>200)return 1;
	}
	//Send the start byte  
	retry=0;
	Data=0;
	while(Data!=0xfe)  
	{
		sd_read();
		if(++retry>=200)return 1;
		dog();
	}                                                                             
	//Read off all the bytes in the block  
	for(a=0;a<512;a++)
	{
		sd_read();
		if(a==ByteAddr)*ch=Data;
	}   
	//Read CRC byte
	sd_read();
	sd_read();
	   
	// Set SD_Chip_Select to high  
	SD_CS=1;
	return 0;  
}

//***********************************************************************************************************************
//函数作用:读取当前扇区的某些字节
//参数说明:
//注意事项:
//返回说明:无
//***********************************************************************************************************************
uchar SD_Read_Sector_Offset(uint Offset, uchar *buf, uint length)
{
	uint  data a;
	uchar data retry=0; 
	
	//Send the read command
	while(SD_Send_Cmd()!=0)
	{
		dog();
		if(retry++>200)return 1;
	}
	//Send the start byte  
	retry=0;
	Data=0;
	while(Data!=0xfe)  
	{
		sd_read();
		if(++retry>=200)return 1;
		dog();
	}                                                                          
	//Read all the bytes in the block
	for(a=0;a<512;a++)
	{
		sd_read();
		if(a>=Offset && length)
		{
			*buf=Data;
			buf++;
			length--;
		}
	}   
	//Read CRC byte
	sd_read();
	sd_read();
	   
	// Set SD_Chip_Select to high  
	SD_CS=1;
	return 0;  
}

//9.write 512 bytes to a given sector from a  Byte_byte_long  Buffer
/*
uchar SD_Write_Sector(ulong addr,uchar *Buffer) 
{ 
	uint xdata a;
	uchar xdata retry,temp; 
	uchar xdata CMD[]={0x58,0x00,0x00,0x00,0x00,0xFF};//cmd24
	
	addr = addr << 9; //addr = addr * 512  
	CMD[1]=((addr&0xFF000000)>>24);  
	CMD[2]=((addr&0x00FF0000)>>16);  
	CMD[3]=((addr&0x0000FF00)>>8); 
	CMD[4]=(addr&0x000000FF); 
	//Send the write command  
	while(SD_Send_Cmd(CMD)!=0)  
	{  
		if (retry++>50)return 1;  
	}  
	//Send the start byte  
	sd_write(0xfe);                                                                           
	//Read off all the bytes in the block  
	for(a=0;a<512;a++)  
	{  
		sd_write(*Buffer++);
	}   
	while((temp=sd_read())&0x10);
	if((temp&0x0f)!=0x05)return 2;
	//Read CRC byte
	while(!SD_DO);//detect if data_in pb.4 is still busy(high)
	
	// Set SD_Chip_Select to high  
	SD_CS=1;
	return 0;   
}

uchar SD_Read_Sector(ulong addr, uchar *Buffer)
{
	uint xdata a; 
	uchar xdata retry;
	uchar xdata CMD[]={0x51,0x00,0x00,0x00,0x00,0xFF};//cmd17

	addr = addr << 9; //addr = addr * 512  
	CMD[1]=((addr&0xFF000000)>>24);  
	CMD[2]=((addr&0x00FF0000)>>16);  
	CMD[3]=((addr&0x0000FF00)>>8); 
	CMD[4]=(addr&0x000000FF);
	//Send the read command
	while(SD_Send_Cmd(CMD)!=0)
	{
		if (retry++>200)return 1;
	}
	//Send the start byte  
	while(sd_read()!=0xfe)  
	{
	
	}                                                                             
	//Read off all the bytes in the block  
	for(a=0;a<512;a++)
	{
		*Buffer=sd_read();
		Buffer++; 
	}   
	//Read CRC byte
	sd_read();
	sd_read();
	   
	// Set SD_Chip_Select to high  
	SD_CS=1;
	return 0;  
}
*/





/*
//6.硬spi写指令及读响应
uchar SD_Send_Cmd(char *CMD)  
{  
 uchar a;  
 uchar tmp=0xff;  
 uchar Timeout=0;  
 // Raise chip select  -----/ss=1 
 SD_CS=1();  
 // Send an 8 bit pulse  
 Write_Byte_SD(0xFF);  
  
 // Lower chip select  
 SD_CS=0;  
 //Send the 6 byte command  
 for(a=0;a<0x06;a++)  
    {  
     Write_Byte_SD(*CMD++);  
    }  
 //Wait for the response  
 while(tmp==0xff)//
      {  
       tmp=Read_Byte_SD();  
       if(Timeout++>100)  
         {  
          break;  
         }  
      }  
 //for some reason we need to delay here  
//delay_1ms(); 
 return(tmp);//the respone of the byte_write_operation  
} 
 

 




//read xx bytes no matter of misalignment!!
uchar read_antimisaliment(unsigned long addr_temp,uchar *p_buffer, uint length)
{
  uint _length=0x0000;
  SD_CS=0; 
  while(SD_read_sector(addr_temp,p_buffer,length))
  {
  SD_CS=0;//
  length-=0x0001;//to find a suuitable length to avoid misalignment
  _length+=0x0001;// _length+length==xx
  SD_set_length(length);
  }  
  ///
  if(_length==0x0000)
  {
  return 0;
  }
  ///
  addr_temp+=length;
  SD_CS=0;//
  SD_set_length(_length); 
  SD_CS=0;//
  while(SD_read_sector(addr_temp,p_buffer,_length))
  {
  SD_CS=0;
  }
  SD_CS=0;//
  SD_set_length(length+_length);//to read the rest bytes of the xx bytes
  return 0;
  /////////////////
 } 



*/

⌨️ 快捷键说明

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