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