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

📄 sd.c

📁 SD卡驱动程序,用于ARM7单片机,完全能用
💻 C
📖 第 1 页 / 共 4 页
字号:
** 输   入: INT32U blockaddr: 块地址				
			 INT8U *sendbuf  : 发送缓冲区,长度512Bytes	  	  
** 输    出: 0:   成功    >0:  错误码				
****************************************************************************/
unsigned char SD_WriteBlock(unsigned int blockaddr, unsigned char *sendbuf)
{
	unsigned char ret,tmp[2];
	
    if (SD_INSERT_STATUS())							
    {	
    	return SD_ERR_NO_CARD;   								/* 卡没完全插入卡中 card is not inserted entirely */
	}
	if(sds.block_len==0x11)
	{

	}
	if (blockaddr >= (sds.block_num*(sds.block_len/SD_BLOCKSIZE)))	
	{
		
		return SD_ERR_OVER_CARDRANGE;							/* 操作超出卡容量范围 operate over the card range */
	}
	
	
	if(SD_WP_STATUS())
	{		
		return SD_ERR_WRITE_PROTECT;							/* 卡有写保护 */
	}
	
	
	ret = SD_WriteSingleBlock(blockaddr);						/* 写单块命令 write single block */
	if (ret != SD_NO_ERR)
	{			
		return ret;
	}
	
	
	ret = SD_WriteBlockData(0, SD_BLOCKSIZE, sendbuf);			/* 写入数据 write data */
 	if (ret == SD_NO_ERR)										/* 读Card Status寄存器, 检查写入是否成功 */
 	{															/* read Card Status register to check write wheather sucessfully */
 		ret = SD_ReadCard_Status(2, tmp);
		if (ret != SD_NO_ERR)
		{			
			return ret;											/* 读寄存器失败 read register fail */
		}
		
		if((tmp[0] != 0) || (tmp[1] != 0))
		{
			ret = SD_ERR_WRITE_BLK; 			     			/* 响应指示写失败 response indicate write fail */
		}
		 //Uart0_SendByte(0xbf);
 	}
	
	
 	return ret;		
}



/***********************************************************************
** 函数名称: SD_ReadByte()					
** 功能描述: 从SD/MMC卡中读一个块					
** 输   入: INT32U ByteAddr:  字节地址				
** 输    出: 返回数据				
*************************************************************************/
unsigned char SD_ReadByte(unsigned int ByteAddr)
{
	unsigned int blockaddr,bitaddr;
	unsigned char buff[512];
	if( (sds.block_num*sds.block_len)<= ByteAddr )
	{
		return SD_BLOCKADDR_ERR;
	}	
	blockaddr = ByteAddr/SD_BLOCKSIZE;
	bitaddr = ByteAddr%SD_BLOCKSIZE;
	if(SD_ReadBlock(blockaddr,buff)!=SD_NO_ERR)return 0;	
	return buff[bitaddr];
}




/***********************************************************************
** 函数名称: SD_WriteByte()					
** 功能描述: 从SD/MMC卡中写一个块					
** 输   入: INT32U ByteAddr:  字节地址				
** 输    出:  0:   成功    >0:  错误码				
*************************************************************************/
unsigned char SD_WriteByte(unsigned int ByteAddr,unsigned char Data)
{
	unsigned int blockaddr,bitaddr;
	unsigned char buff[512];
	unsigned char tmp;
	if( (sds.block_num*sds.block_len)<= ByteAddr )
	{
		return SD_BLOCKADDR_ERR;
	}
	blockaddr = ByteAddr/SD_BLOCKSIZE;
	bitaddr = ByteAddr%SD_BLOCKSIZE;
	tmp = SD_ReadBlock(blockaddr,buff);
	if(tmp!=SD_NO_ERR)return tmp;
	
	
	if(buff[bitaddr] == Data)
	{
		return 0;
	}
	else
	{
		buff[bitaddr] = Data;
	}
	
	
	tmp = SD_WriteBlock(blockaddr,buff);
	
	
	return tmp;	
}




/***********************************************************************
** 函数名称: SD_ReadStr()					
** 功能描述: 从SD/MMC卡中读一多个字李					
** 输   入: INT32U ByteAddr:  字节地址		
			 p:返回的数据,
			 len:读取的数据长度		
** 输    出: 0 成功,其它失败				
*************************************************************************/
unsigned char SD_ReadStr(unsigned int ByteAddr,unsigned char *p,unsigned int len)
{
	unsigned int blockaddr,bitaddr;
	unsigned char buff[512];
	unsigned int len1,len2,c,i,tmp;
	
	if( (sds.block_num*sds.block_len)<= ByteAddr )
	{
		return SD_BLOCKADDR_ERR;
	}
	
		
	blockaddr = ByteAddr/SD_BLOCKSIZE;
	bitaddr = ByteAddr%SD_BLOCKSIZE;
	
	
	if((bitaddr+len)>SD_BLOCKSIZE)
	{
		c = 1 ;	
		len1 = SD_BLOCKSIZE-bitaddr;
		len2 = len - len1;
	}
	else
	{
		c = 0 ;
		len1 = len;
	}
	
	
	tmp = SD_ReadBlock(blockaddr,buff);
	if(tmp!=SD_NO_ERR)
	{
		return tmp;
	}
	
	for( i = 0 ; i < len1 ; i++)
	{
		p[i] = buff[bitaddr+i];
	}
	
	if(c)
	{
		tmp = SD_ReadBlock(blockaddr+1,buff);
		if(tmp!=SD_NO_ERR)
		{
			return tmp;
		}
		
		for( i = 0 ; i < len2 ; i++)
		{
			p[len1+i] = buff[i];
		}	
		
		return SD_NO_ERR;
	}
	else
	{
		return SD_NO_ERR;
	}
}




/***********************************************************************
** 函数名称: SD_WriteStr()					
** 功能描述: 从SD/MMC卡中写一个块					
** 输   入: INT32U ByteAddr:  字节地址				
** 输    出:  0:   成功    >0:  错误码				
*************************************************************************/
unsigned char SD_WriteStr(unsigned int ByteAddr,unsigned char *Data,unsigned int len)
{
/*	unsigned int blockaddr,bitaddr;
	unsigned char buff[512];
	unsigned int len1,len2,c,i,tmp;
	
	if( (sds.block_num*sds.block_len)<= ByteAddr )
	{
		return 0;
	}
	
		
	blockaddr = ByteAddr/SD_BLOCKSIZE;
	bitaddr = ByteAddr%SD_BLOCKSIZE;
	
	
	if((bitaddr+len)>SD_BLOCKSIZE)
	{
		c = 1 ;	
		len1 = SD_BLOCKSIZE-bitaddr;
		len2 = len - len1;
	}
	else
	{
		c = 0 ;
		len1 = len;
	}
	
	
//	tmp = SD_ReadBlock(blockaddr,buff);
	if(tmp!=SD_NO_ERR)
	{
		//return tmp;
	}
	for( i = 0 ; i < len1 ; i++ )
	{
		buff[bitaddr+i] = Data[i]; 
	}
	*/
	unsigned int blockaddr,bitaddr;
	unsigned char tmp;
	unsigned char buff[528];
	unsigned int len1,len2,i;
	unsigned char c;
	if( (sds.block_num*sds.block_len)<= ByteAddr )
	{
		return SD_BLOCKADDR_ERR;
	}
	
	
	blockaddr = ByteAddr/SD_BLOCKSIZE;
	bitaddr = ByteAddr%SD_BLOCKSIZE;
	
	
	if((bitaddr+len)>SD_BLOCKSIZE)
	{
		c = 1 ;	
		len1 = SD_BLOCKSIZE-bitaddr;
		len2 = len - len1;
	}
	else
	{
		c = 0 ;
		len1 = len;
	}
	
	tmp = SD_ReadBlock(blockaddr,buff);
	
	
	if(tmp!=SD_NO_ERR)
	{
		//return tmp;
	}
	for( i = 0 ; i < len1 ; i++ )
	{
		buff[bitaddr+i] = Data[i]; 
	}
	
	
	tmp = SD_WriteBlock(0,buff);
	if(tmp!=SD_NO_ERR)
	{
		return tmp;
	}

	if(c)
	{
		
	}
	
	if(c)
	{
		tmp = SD_ReadBlock(blockaddr+1,buff);
		if(tmp!=SD_NO_ERR)
		{
			return tmp;
		}
		
		for( i = 0 ; i < len2 ; i++ )
		{
			buff[i] = Data[len1+i]; 
		}
		
		tmp = SD_WriteBlock(blockaddr+1,buff);
		if(tmp!=SD_NO_ERR)
		{
			return tmp;
		}
		return SD_NO_ERR;	
	}
	else
	{
		return SD_NO_ERR;
	}
	
	
}



/****************************************************************************
* 名    称:SDInit()
* 功    能:SD卡初始化。
* 入口参数:无
* 出口参数:其它 失败 0成功
****************************************************************************/
unsigned int SDInit( void )
{
	unsigned char recbuf[4];
	SD_HardWareInit();
	if(SD_INSERT_STATUS())							/* 检查卡是否插入 check weather card is inserted */
    {
    	return 0x01;									//没有插入
    }
	if(SD_WP_STATUS())
	{
		return 0x02;									//写保护
	}
	
	SPI_CS_CLR();	
	SD_SPIDelay(25);
	SPI_CS_Deassert();
	SD_SPIDelay(2);
	
	
	if(SD_ResetSD())return 3;						/* 5. 发出CMDO命令复位SD卡 send CMD0 command to reset sd card */
	
	
	if(SD_ActiveInit()!=SD_NO_ERR)return 4;			/* 6. 激活卡进入初始化过程. active card initialize process */
	
	
	if (SD_ReadOCR(4, recbuf)!= SD_NO_ERR)return 5;	/* 7. 读OCR寄存器,查询卡支持的电压值 read OCR register,get the supported voltage */
	if ((recbuf[1] & 0xC0) != 0xC0)
    { 
        return 6;									/* 不支持3.3V,返回错误码  not support 3.3V,return error code */
    }
	
	SPI_ClkToMax();									/* 8. 设置SPI时钟到最大值 set SPI clock to maximum */
	
	#if SD_CRC_EN        
    ret = SD_EnableCRC(1);							/* 使能CRC校验 enable CRC check */
	if (ret != SD_NO_ERR)  
	  	goto SD_ERR;
	#endif
	
	if(SD_SetBlockLen(SD_BLOCKSIZE)!=0)return 7;				/* 9. 设置块的长度: 512Bytes Set the block length: 512Bytes */
	
	if(SD_GetCardInfo()!=0)return 8;				/* 10. 读CSD寄存器,获取SD卡信息 read CSD register, get the information of SD card */ 
//	if(SD_SetBlockLen(SD_BLOCKSIZE)!=0)return 7;	/* 9. 设置块的长度: 512Bytes Set the block length: 512Bytes */	
	return 0;
			
}

/*
 SD卡命令 (2008-07-14 15:16:51) 
 标签:杂谈   分类:WinCE 

 SD卡命令共分为12类,分别为class0到class11,

 不同的SDd卡,主控根据其功能,支持不同的命令集 如下:

 Class0 :(卡的识别、初始化等基本命令集)

 CMD0:复位SD 卡.

 CMD1:读OCR寄存器.

 CMD9:读CSD寄存器.

 CMD10:读CID寄存器.

 CMD12:停止读多块时的数据传输

 CMD13:读 Card_Status 寄存器

 Class2 (读卡命令集):

 CMD16:设置块的长度

 CMD17:读单块.

 CMD18:读多块,直至主机发送CMD12为止 .

 

 Class4(写卡命令集) :

 CMD24:写单块.

 CMD25:写多块.

 CMD27:写CSD寄存器 .

 Class5 (擦除卡命令集):

 CMD32:设置擦除块的起始地址.

 CMD33:设置擦除块的终止地址.

 CMD38: 擦除所选择的块.

 Class6(写保护命令集):

 CMD28:设置写保护块的地址.

 CMD29:擦除写保护块的地址.

 CMD30: Ask the card for the status of the write protection bits

 

 class7:卡的锁定,解锁功能命令集  

 class8:申请特定命令集 。 

 class10 -11 :保留

 其中 class1,    class3,class9:SPI模式不支持    



*/

⌨️ 快捷键说明

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