?? 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 + -