1、51单片机DS1302时钟1602显示可调时钟基于proteus的51单片机仿真实例八十一、实时时钟芯片DS1302应用实例1、DS1302引脚排列:如下图引脚说明:1)Vcc1:后备电源,VCC2:主电源。在主电源关闭的情况下,也能保持时钟的连续运行。DS1302由Vcc1或Vcc2两者中的较大者供电。当Vcc2大于Vcc10.2V时,Vcc2给DS1302供电。当Vcc2小于Vcc1时,DS1302由Vcc1供电。2)X1、X2:振荡源,外接32.768kHz晶振。3)RST:复位/片选线,通过把RST输入驱动置高电平来启动所有的数据传送。RST输入有两种功能:首先,RST接通控制逻辑,允
2、许地址/命令序列送入移位寄存器;其次,RST提供终止单字节或多字节数据的传送手段。当RST为高电平时,所有的数据传送被初始化,允许对DS1302进行操作。如果在传送过程中RST置为低电平,则会终止此次数据传送,I/O引脚变为高阻态。上电运行时,在Vcc2.0V之前,RST必须保持低电平。只有在SCLK为低电平时,才能将RST置为高电平。4)I/O为串行数据输入输出端(双向)。5)SCLK为时钟输入端。2、DS1302的控制字节 DS1302 的控制字如下图所示。控制字节的最高有效位(位7必须是逻辑1,如果它为0,则不能把数据写入DS1302中,位6如果为0,则表示存取日历时钟数据,为1表示存取
3、RAM数据。位5至位1指示操作单元的地址。最低有效位(位0如为0表示要进行写操作,为1表示进行读操作,控制字节总是从最低位开始输出。3、数据输入输出(I/O 在控制指令字输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302,数据输入从低位即位0开始。同样,在紧跟8位的控制指令字后的下一个SCLK脉冲的下降沿读出DS1302的数据,读出数据时从低位0位到高位7。 DS1302的寄存器 DS1302有12个寄存器,其中有7个寄存器与日历、时钟相关,存放的数据位为BCD码形式,其日历、时间寄存器及其控制字见数据手册。此外,DS1302 还有年份寄存器、控制寄存器、充电寄存器、时钟突发寄存器及
4、与RAM相关的寄存器等。时钟突发寄存器可一次性顺序读写除充电寄存器外的所有寄存器内容。 DS1302与RAM相关的寄存器分为两类:一类是单个RAM单元,共31个,每个单元组态为一个8位的字节,其命令控制字为C0HFDH,其中奇数为读操作,偶数为写操作;另一类为突发方式下的RAM寄存器,此方式下可一次性读写所有的RAM的31个字节,命令控制字为FEH(写、FFH(读。 下面是其C程序独家转售):#include#include#define uchar unsigned char #define uint unsigned int#define LCDIO P2sbit rs=P30。 sbit
5、 rd=P31。sbit lcden=P32。sbit acc0=ACC0。 /移位时的第0位sbit acc7=ACC7。 /移位时用的第7位uchar second,minute,hour,day,month,year,week,count=0。 uchar ReadValue,num,time。 uchar code table= 2018-11-29 MON。uchar code table1= 15:45:00 。uchar code table2= THUFRISATSUNMONTUEWES。sbit DATA=P01。 sbit RST=P02。 sbit SCLK=P00。 s
6、bit menu=P35。 /菜单sbit add=P36。 /加一sbit dec=P37。 /减一void delay(uint z uint x,y。 for(x=z。x0。x- for(y=110。y0。y-。void delay1(uint z for(。z0。z-。void write_com(uchar com rs=0。 rd=0。 lcden=0。 P2=com。 delay(5。 lcden=1。 delay(5。 lcden=0。 void write_date(uchar date rs=1。 rd=0。 lcden=0。 P2=date。 delay(5。 lcden
7、=1。 delay(5。 lcden=0。 void init( uchar num。 lcden=0。 write_com(0x38。 write_com(0x0c。 write_com(0x06。 write_com(0x01。 write_com(0x80。 delay(5。 write_com(0x80。 for(num=0。num write_date(tablenum。 delay(5。 write_com(0x80+0x40。 for(num=0。num write_date(table1num。 delay(5。 void Write1302(uchar dat uchar i
8、。 SCLK=0。 /拉低SCLK,为脉冲上升沿写入数据做好准备 delay1(2。 /稍微等待,使硬件做好准备 for(i=0。i /连续写8个二进制位数据 DATA=dat&0x01。 /取出dat的第0位数据写入1302 delay(2。 /稍微等待,使硬件做好准备 SCLK=1。 /上升沿写入数据 delay1(2。 /稍微等待,使硬件做好准备 SCLK=0。 /重新拉低SCLK,形成脉冲 dat=1。 /将dat的各数据位右移1位,准备写入下一个数据位 void WriteSet1302(uchar Cmd,uchar dat RST=0。 /禁止数据传递 SCLK=0。 /确保写数
9、居前SCLK被拉低 RST=1。 /启动数据传输 delay1(2。 /稍微等待,使硬件做好准备 Write1302(Cmd。 /写入命令字 Write1302(dat。 /写数据 SCLK=1。 /将时钟电平置于已知状态 RST=0。 /禁止数据传递 uchar Read1302(void uchar i,dat。 delay(2。 /稍微等待,使硬件做好准备 for(i=0。i /连续读8个二进制位数据 dat=1。 /将dat的各数据位右移1位,因为先读出的是字节的最低位 if(DATA=1 /如果读出的数据是1 dat|=0x80。 /将1取出,写在dat的最高位 SCLK=1。 /将
10、SCLK置于高电平,为下降沿读出 delay1(2。 /稍微等待 SCLK=0。 /拉低SCLK,形成脉冲下降沿 delay1(2。 /稍微等待 return dat。 /将读出的数据返回 uchar ReadSet1302(uchar Cmd uchar dat。 RST=0。 /拉低RST SCLK=0。 /确保写数居前SCLK被拉低 RST=1。 /启动数据传输 Write1302(Cmd。 /写入命令字 dat=Read1302(。 /读出数据 SCLK=1。 /将时钟电平置于已知状态 RST=0。 /禁止数据传递 return dat。 /将读出的数据返回void Init_DS13
11、02(void WriteSet1302(0x8E,0x00。 /根据写状态寄存器命令字,写入不保护指令 WriteSet1302(0x80,(0/10。 /根据写秒寄存器命令字,写入秒的初始值 WriteSet1302(0x82,(45/10。 /根据写分寄存器命令字,写入分的初始值 WriteSet1302(0x84,(15/10。 /根据写小时寄存器命令字,写入小时的初始值 WriteSet1302(0x86,(29/10。 /根据写日寄存器命令字,写入日的初始值 WriteSet1302(0x88,(11/10。 /根据写月寄存器命令字,写入月的初始值 WriteSet1302(0x8
12、c,(10/10。 /nian WriteSet1302(0x8a,(4/10。void DisplaySecond(uchar x uchar i,j。 i=x/10。 j=x%10。 write_com(0xc8。 write_date(0x30+i。 write_date(0x30+j。 void DisplayMinute(uchar x uchar i,j。 i=x/10。 j=x%10。 write_com(0xc5。 write_date(0x30+i。 write_date(0x30+j。 void DisplayHour(uchar x uchar i,j。 i=x/10。
13、j=x%10。 write_com(0xc2。 write_date(0x30+i。 write_date(0x30+j。 void DisplayDay(uchar x uchar i,j。 i=x/10。 j=x%10。 write_com(0x89。 write_date(0x30+i。 write_date(0x30+j。 void DisplayMonth(uchar x uchar i,j。 i=x/10。 j=x%10。 write_com(0x86。 write_date(0x30+i。 write_date(0x30+j。 void DisplayYear(uchar x u
14、char i,j。 i=x/10。 j=x%10。 write_com(0x83。 write_date(0x30+i。 write_date(0x30+j。 void DisplayWeek(uchar x uchar i。 x=x*3。 write_com(0x8c。 for(i=0。i write_date(table2x。 x+。 void read_date(void ReadValue = ReadSet1302(0x81。 second=(ReadValue&0x704*10 + (ReadValue&0x0F。 ReadValue = ReadSet1302(0x83。 min
15、ute=(ReadValue&0x704*10 + (ReadValue&0x0F。 ReadValue = ReadSet1302(0x85。 hour=(ReadValue&0x704*10 + (ReadValue&0x0F。 ReadValue = ReadSet1302(0x87。 day=(ReadValue&0x704*10 + (ReadValue&0x0F。 ReadValue = ReadSet1302(0x89。 month=(ReadValue&0x704*10 + (ReadValue&0x0F。 ReadValue = ReadSet1302(0x8d。 year=
16、(ReadValue&0x704*10 + (ReadValue&0x0F。 ReadValue=ReadSet1302(0x8b。 /读星期 week=ReadValue&0x07。 DisplaySecond(second。 DisplayMinute(minute。 DisplayHour(hour。 DisplayDay(day。 DisplayMonth(month。 DisplayYear(year。 DisplayWeek(week。 void turn_val(char newval,uchar flag,uchar newaddr,uchar s1num newval=Rea
17、dSet1302(newaddr。 /读取当前时间 newval=(newval&0x704*10+(newval&0x0f。 /将bcd码转换成十进制 if(flag /判断是加一还是减一 newval+。 switch(s1num case 1: if(newval99 newval=0。 DisplayYear(newval。 break。 case 2: if(newval12 newval=1。 DisplayMonth(newval。 break。 case 3: if(newval31 newval=1。 DisplayDay(newval。 break。 case 4: if(
18、newval6 newval=0。 DisplayWeek(newval。 break。 case 5: if(newval23 newval=0。 DisplayHour(newval。 break。 case 6: if(newval59 newval=0。 DisplayMinute(newval。 break。 case 7: if(newval59 newval=0。 DisplaySecond(newval。 break。 default:break。 else newval-。 switch(s1num case 1: if(newval=0 newval=99。 Display
19、Year(newval。 break。 case 2: if(newval=0 newval=12。 DisplayMonth(newval。 break。 case 3: if(newval=0 newval=31。 DisplayDay(newval。 break。 case 4: if(newval newval=6。 DisplayWeek(newval。 break。 case 5: if(newval newval=23。 DisplayHour(newval。 break。 case 6: if(newval newval=59。 DisplayMinute(newval。 br
20、eak。 case 7: if(newval newval=59。 DisplaySecond(newval。 break。 default:break。 WriteSet1302(newaddr-1,(newval/10|(newval%10。 /将新数据写入寄存器 /键盘扫描程序/*void key_scan(void uchar miao,s1num=0。 if(menu=0 delay(5。 if(menu=0 while(!menu。 s1num+。 while(1 if(menu=0 delay(5。 if(menu=0 while(!menu。 s1num+。 rd=0。 mia
21、o=ReadSet1302(0x81。 second=miao。 WriteSet1302(0x80,miao|0x80。 write_com(0x0f。/光标闪射 if(s1num=1 year=ReadSet1302(0x8d。 write_com(0x80+4。 /年光标 if(add=0 delay(3。 if(add=0 while(!add。 turn_val(year,1,0x8d,1。 if(dec=0 delay(3。 if(dec=0 while(!dec。 turn_val(year,0,0x8d,1。 if(s1num=2 month=ReadSet1302(0x89。
22、 write_com(0x80+7。 /月光标 if(add=0 delay(3。 if(add=0 while(!add。 turn_val(month,1,0x89,2。 if(dec=0 delay(3。 if(dec=0 while(!dec。 turn_val(month,0,0x89,2。 if(s1num=3 day=ReadSet1302(0x87。 write_com(0x80+10。/日光标 if(add=0 delay(3。 if(add=0 while(!add。 turn_val(day,1,0x87,3。 if(dec=0 delay(3。 if(dec=0 whi
23、le(!dec。 turn_val(day,0,0x87,3。 /写入日寄存器 if(s1num=4 week=ReadSet1302(0x8b。 write_com(0x80+14。 /星期光标 if(add=0 delay(3。 if(add=0 while(!add。 turn_val(week,1,0x8b,4。 if(dec=0 delay(3。 if(dec=0 while(!dec。 turn_val(week,0,0x8b,4。 if(s1num=5 hour=ReadSet1302(0x85。 write_com(0x80+0x40+3。 /时光标 if(add=0 dela
24、y(3。 if(add=0 while(!add。 turn_val(hour,1,0x85,5。 if(dec=0 delay(3。 if(dec=0 while(!dec。 turn_val(hour,0,0x85,5。 if(s1num=6/调时间分 minute=ReadSet1302(0x83。 write_com(0x80+0x40+6。 if(add=0 delay(5。 if(add=0 while(!add。 turn_val(minute,1,0x83,6。 /写入分寄存器 if(dec=0 delay(3。 if(dec=0 while(!dec。 turn_val(minute,0,0x83,6。 /写入分寄存器 if(s1num=7/调时间秒 second=ReadSet1302(0x81。 write_com(0x80+0x40+9。/秒光标 if(add=0 delay(3。 if(add=0 while(!add。 if(second=0x60 second=0x00。 turn_val(second,1,0x81,7。 if(dec=0 delay(3。 if(dec=0 while(!dec。 turn_val(second,0,0x81
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1