(7) DS1302 リアルタイムクロック

DS1302 は、米国 DALLAS 社が発売した、トリクル電流充電機能を備えた低電力リアルタイム クロック チップです。年、月、日、週、時、分、秒の計時が可能で、うるう年補正など多彩な機能を搭載

RTC (リアルタイム クロック): リアルタイム クロックは、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 を使用するには、左側の 2 つに黄色のジャンパー キャップを忘れずに挿入してください。

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 つの 2 進数を使用して 1 つの 10 進数を表現します。

  • 例: 0001 0011 は 13 を意味し、1000 0101 は 85 を意味し、0001 1010 は不正です。上位 8 ビットと下位 8 ビットはそれぞれ 10 進法の 10 と 1 を表します。
  • 16 進数: 0x13 は 13 を意味し、0x85 は 85 を意味し、0x1A は不正です

BCD コードを 10 進数に変換: DEC=BCD / 16 * 10 + BCD % 16; (2 桁の BCD)

10 進数から 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