(7)DS1302实时时钟

DS1302是由美国DALLAS公司推出的具有涓细电流充电能力的低功耗实时时钟芯片。它可以对年、月、日、周、时、分、秒进行计时,且具有闰年补偿等多种功能

RTC(Real Time Clock):实时时钟,是一种集成电路,通常称为时钟芯片,如DS1302、DS3231、DS12C887

请添加图片描述

请添加图片描述

请添加图片描述

请添加图片描述

sbit DS1302_SCLK = P3^6; // 时钟
sbit DS1302_IO = P3^4; // 输入输出
sbit DS1302_CE = P3^5; // 使能开关

void DS1302_Init(){
    
    
	DS1302_CE = 0;
	DS1302_SCLK = 0;
}

/**
	* @brief 单字节写入
	* @param 
	* @retval 
	*/
void DS1302_WriteByte(unsigned char command, Data){
    
    
	unsigned char i;
	DS1302_CE = 1; // 开启使能开关
	
	for(i = 0;i < 8;i++){
    
    
		
		DS1302_IO = command & (0x01 << i); // 取出命令字第i位
		DS1302_SCLK = 1; // 写入一位命令字
		DS1302_SCLK = 0; // 恢复
	}
	
	for(i = 0;i < 8;i++){
    
    
		DS1302_IO = Data & (0x01 << i); // 取出数据第i位
		DS1302_SCLK = 1; // 写入一位数据
		DS1302_SCLK = 0; // 恢复
	}
	
	DS1302_CE = 0; // 关闭
}

/**
	* @brief 单字节读取
	* @param 
	* @retval 
	*/
unsigned char DS1302_ReadByte(unsigned char command){
    
    
	unsigned char i, Data = 0x00;
    command |= 0x01; // 保证是读操作,这样可以直接传入define的值
    
	DS1302_CE = 1;
	
	for(i = 0;i < 8;i++){
    
    
		
		DS1302_IO = command & (0x01 << i); // 取出命令字第i位
		DS1302_SCLK = 0; // 
		DS1302_SCLK = 1; // 
		
	}
	
	for(i = 0;i < 8;i++){
    
    
		DS1302_SCLK = 1;
		DS1302_SCLK = 0; // 读取到IO
		
		if(DS1302_IO){
    
    
			Data |= (0x01 << i); // 若IO非0,将Data的i位置1
		} 
	}
	
	DS1302_CE = 0;
	DS1302_IO = 0; // IO清零
	return Data;
}

请添加图片描述

请添加图片描述

注意,记得把黄色跳帽插到左边两个上,才能使用LCD

void main(){
    
    
	unsigned char Sec = 0x00;
	LCD_Init();
	DS1302_Init();
	DS1302_WriteByte(0x8e,0x00); // 在写寄存器之前必须先将写保护位给清零
	DS1302_WriteByte(0x80, 0x00); // 写入00秒
	
	while(1){
    
    
		Sec = DS1302_ReadByte(0x81);
		LCD_ShowNum(1, 1, Sec, 2);
		Delay(50);
	}
}

在DS1302中并不是以二进制来表示时间的,而是以BCD码表示:

BCD码(Binary Coded Decimal‎),用4位二进制数来表示1位十进制数

  • 例:0001 0011表示13,1000 0101表示85,0001 1010不合法,高8位和低8位分别表示十进制的十位和个位
  • 在十六进制中的体现:0x13表示13,0x85表示85,0x1A不合法

BCD码转十进制:DEC=BCD / 16 * 10 + BCD % 16; (2位BCD)

十进制转BCD码:BCD = DEC / 10 * 16 + DEC % 10; (2位BCD)

//寄存器写入地址/指令定义
#define DS1302_SECOND		0x80
#define DS1302_MINUTE		0x82
#define DS1302_HOUR			0x84
#define DS1302_DATE			0x86
#define DS1302_MONTH		0x88
#define DS1302_DAY			0x8A
#define DS1302_YEAR			0x8C
#define DS1302_WP			0x8E
/**
	* @brief 将time数组里的时间写入时钟
	* @param 
	* @retval 
	*/
void DS1302_SetTime(){
    
    
	DS1302_WriteByte(DS1302_WP, 0x00); // 关闭写保护
	
	DS1302_WriteByte(DS1302_YEAR, time[0]/10*16 + time[0]%10); // 十进制转BCD后写入
	DS1302_WriteByte(DS1302_MONTH, time[1]/10*16 + time[1]%10);
	DS1302_WriteByte(DS1302_DATE, time[2]/10*16 + time[2]%10);
	DS1302_WriteByte(DS1302_HOUR, time[3]/10*16 + time[3]%10);
	DS1302_WriteByte(DS1302_MINUTE, time[4]/10*16 + time[4]%10);
	DS1302_WriteByte(DS1302_SECOND, time[5]/10*16 + time[5]%10);
	DS1302_WriteByte(DS1302_DAY, time[6]/10*16 + time[6]%10);
	
	DS1302_WriteByte(DS1302_WP, 0x80);
}

/**
	* @brief 读出时钟的时间
	* @param 
	* @retval 
	*/
void DS1302_ReadTime(){
    
    
	unsigned char Temp;
	Temp=DS1302_ReadByte(DS1302_YEAR);
	time[0]=Temp/16*10+Temp%16;//BCD码转十进制后读取
	Temp=DS1302_ReadByte(DS1302_MONTH);
	time[1]=Temp/16*10+Temp%16;
	Temp=DS1302_ReadByte(DS1302_DATE);
	time[2]=Temp/16*10+Temp%16;
	Temp=DS1302_ReadByte(DS1302_HOUR);
	time[3]=Temp/16*10+Temp%16;
	Temp=DS1302_ReadByte(DS1302_MINUTE);
	time[4]=Temp/16*10+Temp%16;
	Temp=DS1302_ReadByte(DS1302_SECOND);
	time[5]=Temp/16*10+Temp%16;
	Temp=DS1302_ReadByte(DS1302_DAY);
	time[6]=Temp/16*10+Temp%16;
}

猜你喜欢

转载自blog.csdn.net/Falling_Asteroid/article/details/130736964