?? sd-51.c
字號:
SD_UN(); //釋放SD卡
SD_QReadByte(); //最后8個CLOCK
return SD_ERR_CMD_ERASEBLOCK_A; //發送設置擦除起始地址指令錯誤
}
SD_UN(); //釋放SD卡
SD_QReadByte(); //卡響應與下一指令時鐘間隔
SD_EN(); //SD卡使能
i=0; //初始化變量
do
{
ret=SD_SendCmd(CMD33,AdB0,AdB1,AdB2,AdB3,CMD33_R); //發送設置塊擦除終止地址
i++; //變量+1
}while((ret!=0x00)&&(i<10)); //設置循環條件
if(i>=10)
{
SD_UN(); //釋放SD卡
SD_QReadByte(); //最后8個CLOCK
return SD_ERR_CMD_ERASEBLOCK_B; //發送設置擦除起始地址指令錯誤
}
SD_UN(); //釋放SD卡
SD_QReadByte(); //卡響應與下一指令時鐘間隔
SD_EN(); //SD卡使能
SD_QWriteByte(CMD38); //寫指令
SD_QWriteByte(0xFF); //帶入參數
SD_QWriteByte(0xFF); //帶入參數
SD_QWriteByte(0xFF); //帶入參數
SD_QWriteByte(0xFF); //帶入參數
SD_QWriteByte(0x95); //發送統一CRC碼
e=0; //
while(ret=SD_QReadByte()) //設置循環條件
{
e++; //變量+1
if((ret==0xFF)&&(e<0xFFFFFFFE))
{
SD_UN(); //釋放SD卡
SD_QReadByte(); //發送時鐘
return SD_ERR_NO; //返回無錯誤
}
if(e>=0xFFFFFFFE)
{
SD_UN(); //釋放SD卡
SD_QReadByte(); //發送時鐘
return SD_ERR_ERASEBLOCKS; //發送擦除多塊指令錯誤
}
}
}
/*=========================================================
函數名:SD_ReadBlock()
功能:SD卡塊讀函數
入口參數:塊讀地址(4)
出口參數:操作返回信號(1)
=========================================================*/
Uchar SD_ReadBlock(Ulong Addrs)
{
Uchar ret,Ad0,Ad1,Ad2,Ad3; //臨時變量
Uint i; //臨時變量
Ad0=((Addrs&0xFF000000)>>24); //
Ad1=((Addrs&0x00FF0000)>>16); //
Ad2=((Addrs&0x0000FF00)>>8); //
Ad3=(Addrs&0x000000FF); //
SD_UN(); //SD卡禁止
for(i=0;i<100;i++)
{
SD_QReadByte(); //填充時鐘
}
SD_EN(); //SD卡使能
for(i=0;i<100;i++)
{
SD_QReadByte(); //送空時鐘
}
i=0; //初始化變量
do
{
ret=SD_SendCmd(CMD17,Ad0,Ad1,Ad2,Ad3,CMD17_R); //發送塊讀指令
i++; //變量+1
}while((ret!=0x00)&&(i<10)); //設置循環條件
if(i>=10)
{
for(i=0;i<100;i++)
{
SD_QReadByte(); //送空時鐘
}
SD_UN(); //釋放SD卡
for(i=0;i<100;i++)
{
SD_QReadByte(); //送空時鐘
}
return SD_ERR_CMD_READBLOCK; //返回塊讀錯誤
}
i=0; //初始化寄存器
do
{
ret=SD_QReadByte(); //讀起始字節0xEF
i++; //時間限制
}while((ret!=0xFE)&&(i<10)); //設置循環條件
if(i>=10)
{
for(i=0;i<100;i++)
{
SD_QReadByte(); //送空時鐘
}
SD_UN(); //釋放SD卡
for(i=0;i<100;i++)
{
SD_QReadByte(); //送空時鐘
}
return SD_ERR_DATA_READBLOCK; //返回塊讀錯誤
}
for(i=0;i<514;i++)
{
D[i]=SD_QReadByte(); //讀取SD卡指定地址數據
}
SD_UN(); //釋放SD卡
return SD_ERR_NO; //否則返回無錯誤
}
/*=========================================================
函數名:SD_WritBlock()
功能:SD卡塊寫函數
入口參數:
出口參數:
=========================================================*/
Uchar SD_WriteBlock(Ulong Addrs)
{
Uchar ret,Ad0,Ad1,Ad2,Ad3; //臨時變量
Uint i; //臨時變量
Ad0=((Addrs&0xFF000000)>>24); //
Ad1=((Addrs&0x00FF0000)>>16); //
Ad2=((Addrs&0x0000FF00)>>8); //
Ad3=(Addrs&0x000000FF); //
SD_UN(); //SD卡禁止
for(i=0;i<100;i++)
{
SD_WriteByte(0xFF);
}
SD_EN(); //SD卡使能
for(i=0;i<100;i++)
{
SD_ReadByte();
}
i=0; //初始化變量
do
{
ret=SD_SendCmd(CMD24,Ad0,Ad1,Ad2,Ad3,CMD24_R); //發送塊讀指令
i++; //變量+1
}while((ret!=0x00)&&(i<10)); //設置循環條件
if(i>=10)
{
for(i=0;i<100;i++)
{
SD_QReadByte(); //送空時鐘
}
SD_UN(); //釋放SD卡
for(i=0;i<100;i++)
{
SD_QReadByte(); //送空時鐘
}
return SD_ERR_CMD_WRITEBLOCK; //返回塊寫錯誤
}
for(i=0;i<8;i++)
{
SD_QWriteByte(0xFF);
}
i=0; //初始化寄存器
do
{
SD_QWriteByte(0xFF); //發送時鐘
i++; //時間限制
}while(i<10); //設置循環條件
SD_QWriteByte(0xFE); //寫入起始字節
for(i=0;i<514;i++)
{
SD_QWriteByte(D[i]); //讀取SD卡指定地址數據
}
ret=SD_QReadByte(); //忽略一個字節xxx00101b
if((ret&0x1F)!=0x05)
{
for(i=0;i<100;i++)
{
SD_QReadByte();
}
SD_UN(); //釋放SD卡
for(i=0;i<100;i++)
{
SD_QWriteByte(0xFF);
}
return SD_ERR_WAIT_WRITEBLOCK; //返回等待錯誤信號
}
i=0; //初始化變量
do
{
ret=SD_QReadByte(); //讀SD卡狀態
i++; //變量+1
}while((ret==0x00)&&(i<100)); //設置循環條件
if(i>=100)
{
for(i=0;i<100;i++)
{
SD_QReadByte(); //送空時鐘
}
SD_UN(); //釋放SD卡
for(i=0;i<100;i++)
{
SD_QReadByte(); //送空時鐘
}
return SD_ERR_DATA_WRITEBLOCK; //返回塊寫錯誤
}
for(i=0;i<100;i++)
{
SD_QReadByte(); //送空時鐘
}
SD_UN(); //釋放SD卡
for(i=0;i<100;i++)
{
SD_QWriteByte(0xFF);
}
return SD_ERR_NO; //否則返回無錯誤
}
/*=========================================================
函數名:SD_InitDate1()
功能:SD卡初始化時間表通用函數
入口參數:存放抄表數據首地址、存放時間日期數據地址、數據存放天數值
出口參數:操作信息(1個字節)
=========================================================*/
Uchar SD_InitDate1(Ulong adf,Ulong adg,Uchar j)
{
Uint i,x; //變量聲明
for(i=0;i<512;i++)
{
D[i]=0; //數組清零
}
if(j>128)
{
x=496;
}
else
{
x=512;
}
for(i=0;i<x;i+=8)
{
D[i]=j; //計算天數
j++; //天數+1
}
for(i=4;i<x;i+=8)
{
D[i]=(Uchar)((adf&0xFF000000)>>24); //賦值地址
D[i+1]=(Uchar)((adf&0x00FF0000)>>16); //賦值地址
D[i+2]=(Uchar)((adf&0x0000FF00)>>8); //賦值地址
D[i+3]=(Uchar)(adf&0x000000FF); //賦值地址
adf+=0x0003C000; //地址+1
}
i=0;
while(SD_ERR_NO!=SD_WriteBlock(adg))
{
i++; //變量+1
if(i>5)
{
LCM_ClearRegistryERR(); //清除注冊表失敗
LCM_DispDelay(); //延時1s顯示
return SD_ERR_CLEARREGISTRY; //返回注冊初始化失敗信息
}
}
return SD_ERR_NO; //返回無錯誤
}
/*=========================================================
函數名:SD_InitDate()
功能:SD卡初始化時間表函數
入口參數:無
出口參數:操作信息(1個字節)
=========================================================*/
Uchar SD_InitDate(void)
{
Uchar t; //聲明變量
t=SD_InitDate1(0x00010000,0x00003000,1); //寫入第一組時間表
if(t!=SD_ERR_NO)
{
return SD_ERR_CLEARREGISTRY; //返回錯誤信息
}
t=SD_InitDate1(0x00F10000,0x00003200,65); //寫入第二組時間表
if(t!=SD_ERR_NO)
{
return SD_ERR_CLEARREGISTRY; //返回錯誤信息
}
t=SD_InitDate1(0x01E10000,0x00003400,129); //寫入第三組時間表
if(t!=SD_ERR_NO)
{
return SD_ERR_CLEARREGISTRY; //返回錯誤信息
}
return SD_ERR_NO; //返回無錯誤
}
/*=========================================================
函數名:SD_InitRegistry()
功能:SD卡初始化注冊表函數
入口參數:無
出口參數:操作信息(1個字節)
=========================================================*/
Uchar SD_InitRegistry(void)
{
Uint p,i,j; //聲明變量
Ulong ae; //聲明變量
for(p=0;p<512;p++)
{
D[p]=0; //數組賦值
}
for(i=0;i<4;i++)
{
for(p=i;p<512;p+=64)
{
D[p]=0x55; //區域管理器空
}
}
ae=0x00002000; //變量賦值
for(i=0;i<8;i++)
{
j=0;
while(SD_ERR_NO!=SD_WriteBlock(ae)) //設置循環變量
{
j++; //變量+1
if(j>5)
{
LCM_ClearRegistryERR(); //清除注冊表失敗
LCM_DispDelay(); //延時1s顯示
return SD_ERR_CLEARREGISTRY; //返回注冊初始化失敗信息
}
}
ae+=0x00000200; //下一塊
}
i=0; //
while(SD_ERR_NO!=SD_InitDate())
{
i++;
if(i>5)
{
LCM_ClearRegistryERR(); //清除注冊表失敗
LCM_DispDelay(); //延時1s顯示
return SD_ERR_CLEARREGISTRY; //返回注冊初始化失敗信息
}
}
for(i=0;i<0x0100;i++)
{
D[i]=i; //數組賦值
}
p=0x0200; //
for(i=0;i<0x0100;i++)
{
p--; //
D[p]=i; //循環寫入
}
i=0;
while(SD_ERR_NO!=SD_WriteBlock(0x00001000)) //設置循環變量
{
i++; //變量+1
if(i>5)
{
LCM_ClearRegistryERR(); //清除注冊表失敗
LCM_DispDelay(); //延時1s顯示
return SD_ERR_CLEARREGISTRY; //返回注冊初始化失敗信息
}
}
return SD_ERR_NO; //操作正確
}
/*=========================================================
函數名:SD_CheckRegistry()
功能:SD卡注冊表檢測函數
入口參數:無
出口參數:操作信息(1個字節)
=========================================================*/
Uchar SD_CheckRegistry(void)
{
Uint i,j; //聲明變量
i=0; //變量賦值
while(SD_ERR_NO!=SD_ReadBlock(0x00001000))
{
i++; //變量+1
if(i>5)
{
LCM_SD_CheckRegistryERR(); //調顯注冊表檢測錯誤
LCM_DispDelay(); //延時1s顯示
return SD_ERR_CHECKREGISTRY; //返回注冊表檢測錯誤信息
}
}
for(i=0;i<0x0100;i++)
{
if(D[i]!=i)
{
if(SD_ERR_NO!=SD_InitRegistry())
{
return SD_ERR_INITREGISTRY; //返回初始化注冊表失敗信息
}
}
}
j=0x0100;
for(i=0x0100;i<0x0200;i++)
{
j--; //從0xFF開始遞減
if(D[i]!=j)
{
if(SD_ERR_NO!=SD_InitRegistry())
{
return SD_ERR_INITREGISTRY; //返回初始化注冊表失敗信息
}
}
}
return SD_ERR_NO; //返回操作信息
}
/*=========================================================
函數名:SD_Check()
功能:SD卡檢測函數
入口參數:無
出口參數:無
=========================================================*/
void SD_Check(void)
{
Uchar y; //聲明變量
y=0; //初始化變量
while(0x01!=SD_Rest())
{
y++; //條件+1
if(y>20) //如果在該條件下SD卡沒有完成復位
{
LCM_SDOVER(); //調顯SD卡連接失敗信息
LCM_DispDelay(); //延時1s顯示
goto sd_over; //跳轉過SD卡初始化過程
}
}
y=0; //初始化變量
while(0x00!=SD_ActInit())
{
y++; //條件+1
if(y>20) //如果在該條件下SD卡沒有完成初始化
{
LCM_SDOVER(); //調顯SD卡連接失敗信息
LCM_DispDelay(); //延時1s顯示
goto sd_over; //跳轉過SD卡初始化過程
}
}
SD_UN();
for(y=0;y<10;y++)
{
SD_QReadByte();
}
y=0; //初始化變量
while(0x00!=SD_SetBlockLen(0x00000200))
{
y++; //條件+1
if(y>20) //如果在該條件下SD卡沒有完成初始化
{
LCM_SDOVER(); //調顯SD卡連接失敗信息
LCM_DispDelay(); //延時1s顯示
goto sd_over; //跳轉過SD卡初始化過程
}
}
if(SD_ERR_NO!=SD_CheckRegistry())
{
LCM_SD_CheckRegistryERR(); //讀取檢查注冊表失敗
LCM_DispDelay(); //延時1s顯示
goto sd_over; //跳轉
}
sd_over:
_nop_(); //空操作
}
//=======================================================//
/*******************SD卡函數結束**************************/
//=======================================================//
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -