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

📄 sd.c

📁 汽车仪表板开发
💻 C
字号:
#include "sd.h"


void SPI1_Init(INT8U speed)
{  
	SPI1_CS_GPIO();		
	SPI1_CS_OUT();
					
	PINSEL1 &= ~((0x03 << 2) + (0x03 << 4) + (0x03 << 6)); 
	PINSEL1 |=  (0x02 << 2) + (0x02 << 4) + (0x02 << 6);
	
	SSPCR0 = (0x00 << 8) |              			// SCR=0  
             (0x00 << 7) |             				// CPHA =0时钟输出相位,仅SPI模式有效 
             (0x00 << 6) |              		    // CPOL =0时钟输出极性,仅SPI模式有效
             (0x00 << 4) |              		    // FRF =00 帧格式 00=SPI,01=SSI,10=Microwire,11=保留
             (0x07 << 0);               			// DSS  数据长度,0000-0010=保留,0011=4位,0111=8位,1111=16位

    SSPCR1 = (0x01 << 3) |              			// SOD  从机输出禁能,1=禁止,0=允许
             (0x00 << 2) |              			// MS   主从选择,0=主机,1=从机
             (0x01 << 1) |              			// SSE  SSP使能,1=允许SSP与其它设备通信
             (0x00 << 0);               			// LBM  回写模式
             
    SSPCPSR	= speed; 								//2-254 偶数	
  	SSPIMSC	= 0x00;								    // 取消所有中断使能		
    SSPICR	= 0x00;                     			// 中断清除寄存器
}								
/**************************************************************************************************
**Name: 	  
**Function:   
**Input:	  
**Output:	  
**************************************************************************************************/
INT8U SPI1_SrByte(INT8U byte)
{
	SSPDR = byte;

	while( (SSPSR & 0x01) == 0 );	    			// 等待TFE置位,即发送FIFO空  										

	return(SSPDR);
}

/**************************************************************************************************
**Name: 	  
**Function:   
**Input:	  
**Output:	  
**************************************************************************************************/
INT8U SD_WriteCom(uint8 cmd,uint32 arg)
{
	uint8 temp=20;
   	uint8 retry=0;
	
	SPI1_SrByte(0xff); 
	
  	SPI1_CS_CLR();      							//SD卡使能
    
    while(temp--);
    
   	SPI1_SrByte((cmd & 0x3f) | 0x40);   				//送头命令
   	
   	SPI1_SrByte(arg>>24);
   	SPI1_SrByte(arg>>16);     				//send 6 Byte Command to MMC/SD-Card
   	SPI1_SrByte(arg>>8);
   	SPI1_SrByte(arg);
   	
	SPI1_SrByte(0x95);       				//仅仅对RESET有效的CRC效验码

    SPI1_SrByte(0xff); 
	while((temp = SPI1_SrByte(0xff)) == 0xff)	/* wait response */
		if(retry++ > 0xfe) break;				/* time out error */
		
		
    SPI1_CS_SET();
    SPI1_SrByte(0xff);
    
	return(temp);
}
/**************************************************************************************************
**Name: 	  
**Function:   
**Input:	  
**Output:	  
**************************************************************************************************/
INT8U SD_ReadBlock(INT32U sector,INT8U *buffer)
{
	INT16U  i,retry=0;
	INT8U   temp=0;
	
	SPI1_Init(2);
 
	temp = SD_WriteCom(17,sector<<9);     			//读出RESPONSE
	
	if(temp != 0x00)
	   return temp;

    SPI1_CS_CLR(); 
    
	//等数据的开始	//wait to start recieve data
	while(SPI1_SrByte(0xff) != 0xfe)
	  {
	   if(retry++ > 0xfffe)
		 {
		    SPI1_CS_SET();
		    return 1;
		  }	
	  }									

   	for(i=0; i<512; i++)
	{
		*buffer++ = SPI1_SrByte(0xff);
	}
	
   	SPI1_SrByte(0xff);							//CRC - Byte
   	SPI1_SrByte(0xff);							//CRC - Byte


	SPI1_CS_SET(); 
	SPI1_SrByte(0xff);

	return 0;
}
/*******************************************************************************************************************
** 函数名称: INT8U SD_WriteBlockData()				Name:	  INT8U SD_WriteBlockData()
** 功能描述: 向sd卡写数据块							Function: write block data to sd card
** 输   入: INT8U bmulti  : 是否为多块操作1:是0:否 Input:	  INT8U bmulti   : multi blocks operate 1:Y 0:N 
			 INT32U len    : 长度						  	  INT32U len     : length
			 INT8U *sendbuf: 发送缓冲区					 	  INT8U *sendbuf : the buffer of send
** 输   出: 0:   正确    >0:   错误码		  		Output:	  0:  right		>0:  error code
********************************************************************************************************************/
INT8U SD_WriteBlock(INT32U sector, INT8U *buffer)
{
	INT16U i,retry;
	INT8U temp;
		
    temp = SD_WriteCom(24, sector<<9);        //写命令	//send command
	if(temp != 0x00)
		return temp;
		
	SPI1_CS_CLR();	
	
	SPI1_SrByte(0xff);
	SPI1_SrByte(0xff);
	SPI1_SrByte(0xff);

    SPI1_SrByte(0xfe);                       //发开始符			//send start byte "token"

	for(i=0; i<512; i++)                    //送512字节数据		//send 512 bytes data
	{
		SPI1_SrByte(buffer[i]);
	}						                 

	SPI1_SrByte(0xff);			//dummy crc
	SPI1_SrByte(0xff);
	
	temp = SPI1_SrByte(0xff);
	
	if( (temp & 0x1f) != 0x05)       //等待是否成功	//judge if it successful
	{
		SPI1_CS_SET();
		return temp;
	}
	//等待操作完		//wait no busy
	while(!SPI1_SrByte(0xff))
	  if(retry++ > 0xfffe)
	   {
	      SPI1_CS_SET();
	      return 1;
	   }

	SPI1_CS_SET();
	SPI1_SrByte(0xff);// extra 8 CLK

	return 0;
	    				
 }
/**************************************************************************************************
**Name: 	  
**Function:   
**Input:	  
**Output:	  
**************************************************************************************************/
INT8U SD_Init(void)
{
	uint8 retry=0;
   	uint8 temp=0;
   	uint8 i;

	
	SPI1_Init(120);
    

	do
	{
		for(i=0;i<10;i++) SPI1_SrByte(0xff);
		temp = SD_WriteCom(0, 0);//发idle命令	//send idle command
		retry++;
		if(retry>0xfe) return 1;//超时退出		//time out
	} while(temp != 0x01);	
	
   	retry=0;
   	
   	do
	{
		temp = SD_WriteCom(1, 0);//发active命令	//send active command
		retry++;
		if(retry>0xfe) return 1;//超时退出		//time out
	} while(temp);
	
	SPI1_Init(2);		/* Use High Speed SPI*/

	
	temp = SD_WriteCom(59, 0);//关crc		//disable CRC

	temp = SD_WriteCom(16, 512);//设扇区大小512	//set sector size to 512
	
	
	
	return 0;//正常返回		//normal return
}

⌨️ 快捷键说明

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