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

📄 sd.c

📁 C51读写SD卡,SD卡使用SPI模式进行读写
💻 C
字号:
/********************************************************************************************************************
** 函数名称: uchar SD_SendCmd()					
** 功能描述: 向卡发送命令,并取得响应			
** 输   入: uchar cmd	    : 命令字0-63			
			 ulong arg	: 命令参数,长度为4字节			 
		 
** 输   出: 0:   正确    >0:   错误码		  	
********************************************************************************************************************/
uchar SD_SendCmd(uchar cmd, ulong arg,uchar *rebuff)
{
	uchar i;
	uchar tmp;
	uchar rlen;
	
  rlen = 0;
  switch (cmd)								 /* 根据不同的命令,得到不同的响应长度 */
  {	
    case 0:  rlen=1;    break;									
 	 	case 1:  rlen = 1;  break;
     		 
  	case 2:  rlen = 2;	 break;
     		 
 		case 58:  rlen = 5;	 break;
     		 
  	default:  write_byte_spi(0xFF);	
    		      CS_SD_DIS;						 
      	      return 0;		 /* 返回命令响应类型错误 return error of command response type */
  }
	
  CS_SD_DIS;
  for(i=0;i<10;i++)
  {
    write_byte_spi(0xff);
  }  
	
	CS_SD_EN;
   
  write_byte_spi((cmd & 0x3F) | 0x40);				 /* 发送命令头和命令字  */
    
	write_byte_spi(arg>>24);
	write_byte_spi(arg>>16);
	write_byte_spi(arg>>8);
	write_byte_spi(arg);
	
	write_byte_spi(0x95);

//用SD模式需要用CRC校验,SPI不用
/*#if SD_CRC_EN
	tmp = SD_GetCmdByte6((cmd & 0x3F) | 0x40, param);
	SPI_SendByte(tmp);
#else
    SPI_SendByte(0x95);							 	 /* CRC校验码,只用于第1个命令 CRC,only used for the first command 
#endif*/ 

    i = 0;				
    do 												 /* 等待响应,响应的开始位为0 */
    {												 /* Wait for a response,a response is a start bit(zero) */ 
        (*rebuff) = read_byte_spi();
        i++;
    }while ((((*rebuff) & 0x80) != 0) && (i < 100));
    
    if (i >= 100)
    {												 
        CS_SD_DIS;
        return 0;					 /* 返回命令超时 return response timeout of command */
    }
    
    for (i = rlen - 1; i >= 0; i--)
    {
        rebuff[i] = tmp;
        tmp = read_byte_spi();					 	 /* 循环的最后发送8clock  at the last recycle,clock out 8 clock */
    }
    
  /*  for (i = rlen - 1; i >= 0; i--)
    {
        resp[i] = tmp;
        tmp = read_byte_spi();					 	 /* 循环的最后发送8clock  
    }*/
      
    CS_SD_DIS;
    return 1;								 /* 返回执行成功 return perform sucessfully */
}
/********************************************************************************************************************
** 函数名称: uchar SD_SendCmd()					
** 功能描述: 向卡发送命令,并取得响应			
** 输   入: uchar cmd	    : 命令字0-63			
			 ulong arg	: 命令参数,长度为4字节			 
		 
** 输   出: 0:   正确    >0:   错误码		  	
********************************************************************************************************************/
uchar SD_SendCmd2(uchar cmd, ulong arg)
{
	uchar i;
	uchar tmp;
		
  CS_SD_DIS;
  for(i=0;i<10;i++)
  {
    write_byte_spi(0xff);
  }  
	
	CS_SD_EN;
   
  write_byte_spi((cmd & 0x3F) | 0x40);				 /* 发送命令头和命令字  */
    
	write_byte_spi(arg>>24);
	write_byte_spi(arg>>16);
	write_byte_spi(arg>>8);
	write_byte_spi(arg);
	
	write_byte_spi(0x95);

//用SD模式需要用CRC校验,SPI不用
/*#if SD_CRC_EN
	tmp = SD_GetCmdByte6((cmd & 0x3F) | 0x40, param);
	SPI_SendByte(tmp);
#else
    SPI_SendByte(0x95);							 	 /* CRC校验码,只用于第1个命令 CRC,only used for the first command 
#endif*/ 

    i = 0;				
    do 												 /* 等待响应,响应的开始位为0 */
    {												 /* Wait for a response,a response is a start bit(zero) */ 
        tmp = read_byte_spi();
    }while (tmp !=0);
      
    CS_SD_DIS;
    return 1;								 /* 返回执行成功 return perform sucessfully */
}
/********************************************************************************************************************
** 函数名称: uchar SD_SendCmd()					
** 功能描述: 向卡发送命令,并取得响应			
** 输   入: uchar cmd	    : 命令字0-63			
			 ulong arg	: 命令参数,长度为4字节			 
		 
** 输   出: 0:   正确    >0:   错误码		  	
********************************************************************************************************************/
uchar SD_SendCmd3(uchar cmd, ulong arg)
{
	uchar i;
	uchar tmp=0xff;
		
  /*CS_SD_DIS;

  write_byte_spi(0xff); */
	
	CS_SD_EN;
   
  write_byte_spi((cmd & 0x3F) | 0x40);				 /* 发送命令头和命令字  */
    
	write_byte_spi(arg>>24);
	write_byte_spi(arg>>16);
	write_byte_spi(arg>>8);
	write_byte_spi(arg);
	
	write_byte_spi(0x95);

//用SD模式需要用CRC校验,SPI不用
/*#if SD_CRC_EN
	tmp = SD_GetCmdByte6((cmd & 0x3F) | 0x40, param);
	SPI_SendByte(tmp);
#else
    SPI_SendByte(0x95);							 	 /* CRC校验码,只用于第1个命令 CRC,only used for the first command 
#endif*/ 

    i = 0;				
    while(tmp==0xff) 												 /* 等待响应,响应的开始位为0 */
    {												 /* Wait for a response,a response is a start bit(zero) */ 
        tmp = read_byte_spi();
        if(i++>=100) 
        {
          CS_SD_DIS;
          return 2;
        }
    }
    //等待8个时钟脉冲,sd卡内部完成操作
    CS_SD_DIS;
    write_byte_spi(0xff); 
    return tmp;								 /* 返回执行成功 return perform sucessfully */
}
/* SD卡初始化(SPI-MODE) */
/*--------------------------------------------------------------------
*reBUF数组需要大于5个元素
*
*/
uchar sd_init(void)
{
	uchar i;
	//检测卡是否完全插入
  //if(SD_ChkCard==1) return 0;
	/*CS_SD_DIS;                              //不选SD卡
  for(i=0;i<25;i++)
	{											
		write_byte_spi(0xff);
	}*/
	/* send command CMD0 to SD Card (reset SD Card) */
	publicdata[5]=SD_SendCmd3(0,0);
	/* send command CMD1 to SD Card (atcive SD Card Model:SPI) 

⌨️ 快捷键说明

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