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

📄 sd-51.c

📁 51控制SD卡
💻 C
📖 第 1 页 / 共 2 页
字号:
		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 + -