具体原理参考博客:这位老哥写得非常详细:一看就会!DS1302实时时钟原理和程序_seaeress的博客-CSDN博客_ds1302时钟芯片工作原理
本次我用这个DS1302在数码管上显示时钟的时 分 秒,配合按键串口打印年周月日时分秒已经温度(按键6打印时间,按键4配合按键5打印温度,更多详细见代码)。
注意DS1302读和写的数据都是BCD码,一个字节高四位表示10位,低四位的数值即为剩余的数值。
比如 0x15 BCD码为 0001 0101 =1*10+5;
转换函数如下:
u8 DatToBcd(u8 dat)//数据转BCD码
{
u8 dat1,dat2;
dat1 = dat / 10;
dat2 = dat % 10;
dat2 = dat2 + dat1 * 16;
return dat2;
}
u8 BcdToDat(u8 dat)//BCD码转数据
{
u8 dat1,dat2;
dat1 = (dat >>4)*10;
dat2 = (dat&0x0f) % 16;
dat2 = dat2 + dat1;
return dat2;
}
读取时间函数:
void Read_Time(){ MyDst[0]=BcdToDat(Read_Ds1302_Byte(0x8d));//年 MyDst[1]=BcdToDat(Read_Ds1302_Byte(0x8b));//周 MyDst[2]=BcdToDat(Read_Ds1302_Byte(0x89));//月 MyDst[3]=BcdToDat(Read_Ds1302_Byte(0x87));//日 MyDst[4]=BcdToDat(Read_Ds1302_Byte(0x85));//时 MyDst[5]=BcdToDat(Read_Ds1302_Byte(0x83));//分 MyDst[6]=BcdToDat(Read_Ds1302_Byte(0x81));//秒 }
main.c如下
#include "sys.h"
u8 s=0;
u8 smgtime=0;
u8 keytime=0;
u8 temp=0;
u16 time=0;
xdata u8 Tempbuf[20]={0};
void UIPlay(){
DT[0]=MyDst[4]/10;
DT[1]=MyDst[4]%10;
DT[2]=10;
DT[3]=MyDst[5]/10;
DT[4]=MyDst[5]%10;
DT[5]=10;
DT[6]=MyDst[6]/10;
DT[7]=MyDst[6]%10;
}
void main()
{
sys_init();
Timer0Init();
while(1){
if(keytime==20){
keytime=0;
key_scan();
switch(rkey){
case 4:
temp=(u8)Read_temp();
break;
case 5:
Tempbuf[0]=temp/10+0x30;
Tempbuf[1]=temp%10+0x30;
Tempbuf[2]='\r';
Tempbuf[3]='\n';
Tempbuf[4]='\0';
SendString(Tempbuf);
break;
case 6:
Tempbuf[0]=MyDst[0]/10+0x30;//年
Tempbuf[1]=MyDst[0]%10+0x30;//
Tempbuf[2]='y';
Tempbuf[3]=MyDst[1]/10+0x30;
Tempbuf[4]=MyDst[1]%10+0x30;
Tempbuf[5]='z';
Tempbuf[6]=MyDst[2]/10+48;
Tempbuf[7]=MyDst[2]%10+48;
Tempbuf[8]='m';
Tempbuf[9]=MyDst[3]/10+48;
Tempbuf[10]=MyDst[3]%10+48;
Tempbuf[11]='d';
Tempbuf[12]=MyDst[4]/10+48;
Tempbuf[13]=MyDst[4]%10+48;
Tempbuf[14]='h';
Tempbuf[15]=MyDst[5]/10+48;
Tempbuf[16]=MyDst[5]%10+48;
Tempbuf[17]='m';
Tempbuf[18]=MyDst[6]/10+48;
Tempbuf[19]=MyDst[6]%10+48;
Tempbuf[20]='s';
Tempbuf[21]='\r';
Tempbuf[22]='\n';
Tempbuf[23]='\0';
SendString(Tempbuf);
break;
case 7:
//to do
break;
default :
break;
}
rkey=0;
}
if(smgtime==50){
smgtime=0;
UIPlay();
}
if(time==1000){
time=0;
Read_Time();
}
}
}
void TIME0() interrupt 1{
smg_play(DT[s],s);
if(++s>7)s=0;
smgtime++;
keytime++;
time++;
}
串口打印
附上Demo链接
链接:https://pan.baidu.com/s/1A3Y9G-Ckk0eFJX9lXSKOlQ
提取码:yzh1