📄 sd_drive.c
字号:
/*--------------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 + -