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

📄 sd_drive.c

📁 Atmega64单片机程序(完整工程)
💻 C
📖 第 1 页 / 共 2 页
字号:
/*--------------File Info-------------------------------------------------------
** 文   件   名:    SD_Driver.c
** 最后修改日期:    2008.3.28
** 版        本:    V1.0
** 描        述:    sd 卡驱动软件包: 用户API函数			
**------------------------------------------------------------------------------
** Created   by:    		
** Created date:			
*******************************************************************************/

#include "SYS_Config.h" 
#include "SD_Config.h" 
#include "SD_Hal.h" 
#include "SD_Cmd.h" 
#include "SD_Drive.h" 


extern INT8U Data_Buf[SD_BLOCKSIZE];//在main函数中定义


sd_struct sds ;/* SD卡信息结构体变量  */

/* 超时时间单位表(单位:0.000000001ns) timeout unit table */
const INT32U time_unit[8]=
{
    1000000000,100000000,10000000,
    1000000,100000,10000,1000,100 
};

/* 超时时间表 timeout value table */
const INT8U time_value[16]=
{
    0,10,12,13,15,20,25,30,35,40,45,50,55,60,70,80 
};

/* 超时时间因数表 timeout factor table */
const INT8U r2w_fator[6]=
{
    1,2,4,8,16,32 
};


/*       
********************************************************************************
用户API函数:  初始化,读,写,擦 SD卡 
				
/******************************************************************************
** 函数名称: INT8U SD_Initialize()				
** 功能描述: 初始化SD卡							
** 输   入: 无									
** 输   出: 0:   正确    >0:   错误码		  	
*******************************************************************************/
INT8U SD_Initialize(void)
{
    INT8U recbuf[4],ret ;
    
    SD_HardWareInit();  //初始化读写SD卡的硬件条件 
       
    if(!SD_ChkCard())   // 检查卡是否插入
        return SD_ERR_NO_CARD ;
    
    SPI_CS_Assert();         /* 1. 置CS为低 assert CS */
    
    SD_SPIDelay(100);        /* 2. 至少延时 74  */
   
    SPI_CS_Deassert();       /* 3. 置CS为高 dessert CS */
    
    SD_SPIDelay(20);         /* 4. 延时2(8 clock)  */
    
    ret=SD_ResetSD();        /* 5. 发出CMDO命令复位SD卡  */
    if(ret!=SD_NO_ERR)
        return ret ;
    
    ret=SD_ActiveInit();     /* 6. 激活卡进入初始化过程.  */
    if(ret!=SD_NO_ERR)
        return ret ;
    
    ret=SD_ReadOCR(4,recbuf);/* 7. 读OCR寄存器,查询卡支持的电压值 */
    if(ret!=SD_NO_ERR)
        return ret ;
    
    if((recbuf[1]&MSK_OCR_33)!=MSK_OCR_33)
	return SD_ERR_VOL_NOTSUSP ;/* 不支持3.3V,返回错误码  */
  
    SPI_Clk_MAX();           /* 8. 设置SPI时钟到最大值 */
    
    #if SD_CRC_EN  
        ret=SD_EnableCRC(1); /* 使能CRC校验 enable CRC check */
        if(ret!=SD_NO_ERR)
            return ret ;
    #endif 
    
    ret=SD_SetBlockLen(SD_BLOCKSIZE);/* 9. 设置块的长度: 512Bytes  */
    if(ret!=SD_NO_ERR)
        return ret ;
    
    return(SD_GetCardInfo());        /* 10. 读CSD寄存器,获取SD卡信息  */
}

/*******************************************************************************
** 函数名称: INT8U SD_ReadBlock()					
** 功能描述: 从SD卡中读一个块						
** 输   入: INT32U blockaddr: 块地址				
	     INT8U *recbuf   : 接收缓冲区,长度512Bytes	 	
** 输   出: 0:   正确    >0:   错误码		  		
*******************************************************************************/
INT8U SD_ReadBlock(INT32U blockaddr,INT8U *recbuf)
{
    INT8U ret ;
    
    if(blockaddr>sds.block_num)
        return SD_ERR_OVER_CARDRANGE ;
    /* 操作超出卡容量范围 operate over the card range */
    
    ret=SD_ReadSingleBlock(blockaddr);
    /* 读单块命令 read single blocks command */
    if(ret!=SD_NO_ERR)
        return ret ;
    
    return(SD_ReadBlockData(SD_BLOCKSIZE,recbuf));
    /* 读出数据 read data from sd card */
}


/*******************************************************************************
** 函数名称: SD_Read_word		
** 功能描述: 块偏移为offset 的长整形数据 						
** 输   入: INT32U blockaddr: 块地址				
	     INT16U offset   : 块内偏移				 
** 输   出: INT32U     
             0xFFFF:   错误码		  		
*******************************************************************************/
#if SD_Read_Word_EN 
INT16U SD_Read_Word(INT32U blockaddr,INT16U offset)
{
    INT8U  *buff;
    INT16U resp;
    
    buff=Data_Buf;
    
    if( SD_ReadBlock(blockaddr,buff)==0 )
    {
        resp=buff[offset+1];
	resp=(resp<<8)+buff[offset];
        return resp;
    }
    return 0xFFFF;
}
#endif

/*******************************************************************************
** 函数名称: SD_Read_Dword		
** 功能描述: 块偏移为offset 的长整形数据 						
** 输   入: INT32U blockaddr: 块地址				
	     INT16U offset   : 块内偏移				 
** 输   出: INT32U     
             0xFFFFFFFF:   错误码		  		
*******************************************************************************/
#if SD_Read_Dword_EN 
INT32U SD_Read_Dword(INT32U blockaddr,INT16U offset)
{
    INT8U  *buff;
    INT32U resp;
    
    buff=Data_Buf;
    
    if( SD_ReadBlock(blockaddr,buff)==0 )
    {
        resp=buff[offset+3];
	resp=(resp<<8)+buff[offset+2];
	resp=(resp<<8)+buff[offset+1];
	resp=(resp<<8)+buff[offset];
	return resp;
    }
    return 0xFFFFFFFF;
}
#endif


/*******************************************************************************
** 函数名称: INT8U SD_ReadMultiBlock()				
** 功能描述: 从SD卡中读多个块						
** 输   入: INT32U blockaddr: 块地址				
	     INT32U blocknum : 块数量					
	     INT8U *recbuf   : 接收缓冲区,每块512字节		 
** 输   出: 0:   正确    >0:   错误码		  		
*******************************************************************************/
#if SD_ReadMultiBlock_EN 
INT8U SD_ReadMultiBlock(INT32U blockaddr,INT32U blocknum,INT8U*recbuf)
{
    INT32U i ;
    INT8U ret ;
    
    if((blockaddr+blocknum)>sds.block_num)
        return SD_ERR_OVER_CARDRANGE ;
    /* 操作超出卡容量范围 operate over the card range */
    
    ret=SD_ReadMultipleBlock(blockaddr);
    /* 读多块命令 read multiple blocks command */
    if(ret!=SD_NO_ERR)
        return ret ;
    
    for(i=0;i<blocknum;i++)
    {
        /* 读出数据 read data from sd card */
        ret=SD_ReadBlockData(SD_BLOCKSIZE,recbuf);
        if(ret==SD_NO_ERR)
            recbuf=recbuf+SD_BLOCKSIZE ;
        else 
            return ret ;
    }
    return(SD_StopTransmission());
    /* 结束数据传输 stop transmission operation */
}
#endif 

/*******************************************************************************
** 函数名称: INT8U SD_WriteBlock()					
** 功能描述: 向SD卡中写入一个块						
** 输   入: INT32U blockaddr: 块地址				
	     INT8U *sendbuf  : 发送缓冲区,长度512Bytes	  	
** 输   出: 0:   正确    >0:   错误码		  		
*******************************************************************************/
INT8U SD_WriteBlock(INT32U blockaddr,INT8U *sendbuf)
{
    INT8U ret,tmp[2];
    
    if(blockaddr>sds.block_num)
        return SD_ERR_OVER_CARDRANGE ;
    /* 操作超出卡容量范围 operate over the card range */
    
    if(SD_ChkCardWP()==1)
        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 */
    /* 读Card Status寄存器, 检查写入是否成功 */
    if(ret==SD_NO_ERR)
    {
        /* 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 */
    }
    return ret ;/* 返回写入结果 return the result of writing */
}

/*******************************************************************************
** 函数名称: INT8U SD_WriteMultiBlock()				
** 功能描述: 向SD卡中写入多个块						
** 输   入: INT32U blockaddr: 块地址				
	     INT32U blocknum : 块数量					
	     INT8U *sendbuf  : 发送缓冲区每块512字节    	
** 输   出: 0:   正确    >0:   错误码		  		
*******************************************************************************/
#if SD_WriteMultiBlock_EN 
INT8U SD_WriteMultiBlock(INT32U blockaddr,INT32U blocknum,INT8U *sendbuf)
{
    INT32U i ;

⌨️ 快捷键说明

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