基于DS1302的数码管时钟电路设计源程序

合集下载

DS1302时钟程序

DS1302时钟程序
#define ds1302_hr_add 0x84 //时
#define ds1302_charge_add 0x8e //控制数据地址
unsigned char sec,min,hr;
sbit DS1302_CLK=P1^5; //实时时钟时钟线引脚
sbit DS1302_IO=P1^6; //实时时钟数据线引脚
case 1:P2_1=0;P0=led_code[led_reg[1]]; break;
case 2:P2_2=0;P0=led_code[led_reg[2]]; break;
case 3:P2_3=0;P0=led_code[led_reg[3]]; break;
case 4:P2_4=0;P0=led_code[led_reg[4]]; break;
else temp&=0x7F;
DS1302_CLK=1;
DS1302_CLK=0;
}
DS1302_CLK=1;
DS1302_RST=0; //停止DS1302总线
return temp;
}
void T_display() //时钟显示
DS1302_CLK=1;
DS1302_CLK=0;
addr=addr>>1;
}
for(i=0;i<8;i++) //输出数据:temp
{
temp=temp>>1;
if(DS1302_IO)temp|=0x80;
}
}
void main() //主程序
{
ds1302_init();
delay(5);

DS1302时钟芯片 C语言程序设计

DS1302时钟芯片 C语言程序设计

unsigned char i,tmp; time_buf[1]=ds1302_read_byte(ds1302_year_add); //年 time_buf[2]=ds1302_read_byte(ds1302_month_add); //月 time_buf[3]=ds1302_read_byte(ds1302_date_add); //日 time_buf[4]=ds1302_read_byte(ds1302_hr_add); //时 time_buf[5]=ds1302_read_byte(ds1302_min_add); //分 time_buf[6]=(ds1302_read_byte(ds1302_sec_add))&0x7F;//秒 time_buf[7]=ds1302_read_byte(ds1302_day_add); //周 for(i=0;i<8;i++){ //BCD处理 tmp=time_buf[i]/16; time_buf1[i]=time_buf[i]%16; time_buf1[i]=time_buf1[i]+tmp*10; } } /*DS302初始化函数*/ void ds1302_init(void) { RST_CLR; /*RST脚置低*/ SCK_CLR; /*SCK脚置低*/ }
} else { temp &= 0x7F; } SCK_SET; SCK_CLR; } RST_CLR; /*停止DS1302总线*/ return temp; } /*向DS302写入时钟数据*/ void ds1302_write_time(void) { unsigned char i,tmp; for(i=0;i<8;i++){ //BCD处理 tmp=time_buf1[i]/10; time_buf[i]=time_buf1[i]%10; time_buf[i]=time_buf[i]+tmp*16; } ds1302_write_byte(ds1302_control_add,0x00); //关闭写保护 ds1302_write_byte(ds1302_sec_add,0x80); //暂停 ds1302_write_byte(ds1302_charger_add,0xa9); //涓流充电 ds1302_write_byte(ds1302_year_add,time_buf[1]); //年 ds1302_write_byte(ds1302_month_add,time_buf[2]); //月 ds1302_write_byte(ds1302_date_add,time_buf[3]); //日 ds1302_write_byte(ds1302_day_add,time_buf[7]); //周 ds1302_write_byte(ds1302_hr_add,time_buf[4]); //时 ds1302_write_byte(ds1302_min_add,time_buf[5]); //分 ds1302_write_byte(ds1302_sec_add,time_buf[6]); //秒 ds1302_write_byte(ds1302_day_add,time_buf[7]); //周 ds1302_write_byte(ds1302_control_add,0x80); //打开写保护 } /*从DS302读出时钟数据*/ void ds1302_read_time(void) {

课程设计(论文)-基于DS1302的电子时钟设计

课程设计(论文)-基于DS1302的电子时钟设计

目录摘要: (1)1 引言: (2)1.1 功能电子时钟研究的背景和意义 (2)1.2 电子时钟的功能 (2)2 基于单片机的电子时钟硬件选择分析 (2)2.1 微处理器选择 (2)2. 2 DS1302简介 (4)2. 3 DS1302引脚说明 (4)3 电子时钟硬件电路设计 (5)3.1 时钟电路设计 (6)3.2 显示器的选择 (6)3.3 按键调时电路 (6)4 proteus软件仿真及调试 (7)4.1 系统工作流程图 (8)4.2 电路板的仿真 (8)4.3 软件调试 (8)5 源程序 (9)总结 (16)参考文献 (17)附录 (18)基于DS1302的电子时钟设计摘要:电子时钟主要是利用电子技术将时钟电子化、数字化,拥有时钟精确、体积小、界面友好、可扩展性能强等特点,被广泛应用于生活和工作当中。

另外,在生活和工农业生产中,也常常需要温度,这就需要电子时钟具有多功能性。

本文对当前电子钟开发手段进行了比较和分析,最终确定了采用单片机技术实现多功能电子时钟。

本设计应用AT89C52芯片作为核心,LCD1602显示,使用DS1302实时时钟日历芯片完成时钟/日历的基本功能。

这种实现方法的优点是电路简单,性能可靠,实时性好,时间精确,操作简单,编程容易。

关键词:电子时钟;多功能;A T89C52;时钟日历芯1 引言:时间是人类生活必不可少的重要元素,如果没有时间的概念,社会将不会有所发展和进步。

从古代的水漏、十二天干地支,到后来的机械钟表以及当今的石英钟,都充分显现出了时间的重要,同时也代表着科技的进步。

致力于计时器的研究和充分发挥时钟的作用,将有着重要的意义。

1.1 功能电子时钟研究的背景和意义20世纪末,电子技术获得了飞速的发展。

在其推动下,现代电子产品几乎渗透到了社会的各个领域,有力的推动和提高了社会生产力的发展与信息化程度,同时也使现代电子产品性能进一步提升,产品更新换代的节奏也越来越快。

实时时钟芯片DS1302 C51源程序

实时时钟芯片DS1302 C51源程序
函数名:RTInputByte()
功能:实时时钟写入一字节
说明:往DS1302写入1Byte数据(内部函数)
入口参数:d写入的数据
返回值:无
***********************************************************************/
void RTInputByte(uchar d)
函数名:W1302()
功能:往DS1302写入数据
说明:先写地址,后写命令/数据(内部函数)
调用:RTInputByte() , RTOutputByte()
入口参数:ucAddr: DS1302地址, ucData:要写的数据
返回值:无
***********************************************************************/
允许写保护:W1302(0X8E,0X80)读月:R1302(0X89)
慢充电控制:W1302(0X90,0XAA)写秒(起振):W1302(0X80,0X00)
写秒(停振):W1302(0X80,0X80)
函数名:R1302()
功能:读取DS1302某地址的数据
说明:先写地址,后读命令/数据(内部函数)
调用:RTInputByte() , RTOutputByte()
入口参数:ucAddr: DS1302地址
返回值:ucData :读取的数据
***********************************************************************/
返回值:无
***********************************************************************/

DS1302三键4位1.5寸数码管时钟

DS1302三键4位1.5寸数码管时钟

说明:最初跑得不太准,把1302的电容换成7p以后,精度非常好,具体没有查误差,反正好几个月与家里的石英钟很对时。

5v供电,亮度不高,室内用正好。

本人程序基本抄袭的,其中秒是用定时器模拟闪动,各位老师多多指教,原来是显示带拐角的7,让我改了,第一位为零时也改作不显示了,请各位大大批评指正!随便挣俩钱儿(感谢江顺万老师的细心批评指正,由于自己不够严谨导致一点错误,已经在原文改过,深表歉意!)先上电路图:再上个实物图:分解图:最后上c程序,不用下载,照顾没米的大大,欢迎批评,砸点儿币过来。

三鞠躬!/**********************************DS1302 四位数码管***********************************/#include <reg52.h>#define uchar unsigned char#define uint unsigned int#define D P2 //段选#define D P0 //位选sbit IO=P1^1; //数据口sbit SCLK=P1^2; //控制数据时钟sbit RST=P1^0; //使能端、复位端/************按键引脚定义***********/sbit s1=P1^5; //按键加sbit s2=P1^3; //按键减sbit s3=P1^4; //按键选择sbit led=P1^7; //闪烁的小数点uchar s, knum=0,snum,fnum;标志。

/***********写时分秒地址************/#define write_shi 0x84#define write_fen 0x82#define write_miao 0x80/***********读时分秒地址************/#define read_shi 0x85#define read_fen 0x83#define read_miao 0x81bit miao_flag;char miao_num;char Dmiao;char shi,fen,miao; //读出数据存储变量uchar d[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xd8,0x80,0x90}; //不带小数点,共阳uchar dd[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10}; //带小数点,共阳void delay(uint z) //延时函数,z的取值为这个函数的延时ms数,如 delay(200);大约延时200ms.{ //delay(500);大约延时500ms.uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void t0_init() //定时50ms一个中断{TMOD=0X01;TH0=(65536-50000)/256;TL0=(65536-50000)%256;EA=1;ET0=1;TR0=1;}uchar read_1302(uchar add) //读函数{uchar i,date;RST=0; //禁止读写数据for(i=0;i<8;i++){RST=1;SCLK=0;IO=add&0x01;add>>=1;SCLK=1;}for(i=0;i<8;i++){if(IO)date=date|0x80;elsedate=date|0x00;SCLK=1;date>>=1;SCLK=0;}RST=0;date=date/16*10+date%16;//进制转换16转10进制IO=0; //数据读完后,IO口必须为0,不然小时一直显示85 return date;}void write_1302(uchar add,uchar dat) //写函数{uchar i;RST=0; //禁止读写数据SCLK=0;for(i=0;i<8;i++) //写地址{RST=1; //允许读写数据SCLK=0;IO=add&0x01;add>>=1;SCLK=1;}for(i=0;i<8;i++) //写数据{RST=1; //允许读写数据SCLK=0;IO=dat&0x01;dat>>=1;SCLK=1;}RST=0;}void init_1302() //初始化函数设置时间{flag=read_1302(0x81);if(flag&0x80)write_1302(0x8e,0x00); //保护取消,可以进行读写操作write_1302(write_miao,0x56);write_1302(write_fen,0x49);write_1302(write_shi,0x14);write_1302(0x90,0xa5);write_1302(0x8e,0x80); //保护启动,不能进行读写操作}void display(uchar shi,uchar fen) //显示函数{if(knum==0){snum=30;fnum=30;}if(knum==1){fnum++;snum=30;}if(knum==2){snum++;fnum=30;}if(snum>=30){W=0xF7; //位选s=d[shi/10];//段码先给s,判断其值是否为0,if(s==0xc0){W=0xff;D=0xff;}D=s;//s不为零则给D,让其显示delay(5);D=0Xff; //消隐if(miao_flag) //小数点闪烁 {miao_flag=0;W=0xFb;D=dd[shi%10];delay(5);D=0Xff; //消隐}else{W=0xFb;D=d[shi%10];delay(5);D=0Xff;}if(snum==60)snum=0;}if(fnum>=30){W=0xFd;D=d[fen/10];delay(5);D=0Xff; //消隐W=0xFe;D=d[fen%10];delay(5);D=0Xff; //消隐if(fnum==60)fnum=0;}}void read_sf(){miao=read_1302(read_miao); /*if(miao!=Dmiao){Dmiao=miao;TR0=1;miao_flag=1;} */fen=read_1302(read_fen);shi=read_1302(read_shi);display(shi,fen);}void keyscan() //按键扫描函数{if(s3==0) //选择按键按下{delay(10);if(s3==0){while(!s3)display(shi,fen); //加上这句,按键按下就不会闪knum++;if(knum==1) //分闪烁{write_1302(0x8e,0x00); //保护取消write_1302(write_miao,0x80);}if(knum==3) //时钟启动{knum=0;write_1302(write_miao,0x00);write_1302(0x8e,0x80); //保护启动}}}if(knum==1) //分钟调节{if(s1==0) //加{delay(10);if(s1==0){while(!s1)display(shi,fen); //加上这句,按键按下就不会闪fen++;if(fen==60)fen=0;write_1302(write_fen,fen/10*16+fen%10); //写入1302 // read_sf(); //读出时间,然后显示}}if(s2==0){delay(10);if(s2==0){while(!s2)display(shi,fen); //加上这句,按键按下就不会闪 fen--;if(fen==-1)fen=59;write_1302(write_fen,fen/10*16+fen%10);read_sf();}}}if(knum==2){if(s1==0){delay(10);if(s1==0){while(!s1)display(shi,fen); //加上这句,按键按下就不会闪 shi++;if(shi==24)shi=0;write_1302(write_shi,shi/10*16+shi%10);read_sf();}}if(s2==0){delay(10);if(s2==0){while(!s2)display(shi,fen); //加上这句,按键按下就不会闪 shi--;if(shi==-1)shi=23;write_1302(write_shi,shi/10*16+shi%10);read_sf();}}}}void main(){init_1302();t0_init();while(1){ if(miao_num<10)led=0;if(miao_num>=10)led=1;read_sf();keyscan();}}void t0_timer() interrupt 1 {TMOD=0X01;TH0=(65536-50000)/256; TL0=(65536-50000)%256; miao_num++;if(miao_num>=20){miao_num=0;miao_flag=1;}}。

DS1302时钟程序(完整版),液晶显示

DS1302时钟程序(完整版),液晶显示

#include<reg52.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intuchar table0[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39}; //液晶显示数字0——9代码sbit SCLK=P1^0;sbit DATA=P1^1;sbit CE=P1^2;sbit RS=P2^0;sbit RW=P2^1;sbit EN=P2^2;sbit FB=P0^7;sbit start=P1^4;sbit stop=P1^5;uchar i;/*******************延时n微秒函数*****************/void delaynus(uchar n) //n us延时函数{// uchar i;for(i=n;i>0;i--);}/*******************写数据函数*****************/void write1302(uchar add,uchar dat){CE=0;SCLK=0;CE=1;for(i=0;i<8;i++) //写入地址{DATA=add&0x01;SCLK=1;SCLK=0;add>>=1;}for(i=0;i<8;i++) //写入数据{DATA=dat&0x01;SCLK=1;SCLK=0;dat>>=1;}SCLK=1;CE=0;}/*******************读数据函数*****************/uchar read1302(uchar add){uchar dat;CE=0;SCLK=0;CE=1;for(i=8;i>0;i--) //写入地址{DATA=add&0x01;SCLK=1;SCLK=0;add>>=1;}for(i=8;i>0;i--) //读出数据/********************为神马???**************************/{dat>>=1;if(DATA==1)dat=dat|0x80;SCLK=1;SCLK=0;}SCLK=1;CE=0;return dat;}/*******************DS1302初始化函数*****************/void init1302(){uchar flag;flag=read1302(0x81);if(flag&0x80){write1302(0x8e,0x00);write1302(0x80,0x00);write1302(0x82,(((1/10)<<4)|(1%10)));write1302(0x84,(((20/10)<<4)|(20%10)));write1302(0x86,(((19/10)<<4)|(19%10)));write1302(0x88,(((7/10)<<4)|(7%10)));write1302(0x8a,((2/10)<<4)|(2%10));write1302(0x8c,(((11/10)<<4)|(11%10)));write1302(0x90,0xa5); //充电。

基于ds1302的51单片机简易实时时钟-1602显示-源程序

基于ds1302的51单片机简易实时时钟-1602显示-源程序

==================主程序================= #include <reg51.h>。

#include "ds1302.h"#include "LCD1602.h"void change();uchar times[9];uchar date[9];main(){LCD_init();//LCD初始化init_1302(time_1302);gotoxy(1,1);LCD_display("Time:");gotoxy(1,2);LCD_display("Date:");times[8]='\0';//date[8]='\0';while(1){get_1302(time_1302);change();gotoxy(7,1);LCD_display(times);gotoxy(7,2);LCD_display(date);}}/*=========================== 转换子程序===========================*/void change(){// 时间的转换times[0]=time_1302[2]/10+'0';times[1]=time_1302[2]%10+'0';times[2]=':';times[3]=time_1302[1]/10+'0';times[4]=time_1302[1]%10+'0';times[5]=':';times[6]=time_1302[0]/10+'0';times[7]=time_1302[0]%10+'0';// 日期的转换date[0]=time_1302[6]/10+'0';date[1]=time_1302[6]%10+'0';date[2]='-';date[3]=time_1302[4]/10+'0';date[4]=time_1302[4]%10+'0';date[5]='-';date[6]=time_1302[3]/10+'0';date[7]=time_1302[3]%10+'0';}======================================================DS1302驱动程序=============#define uchar unsigned charuchar time_1302[7]={0x00,0x00,0x00,0x03,0x07,0x03,0x08};//设置时间初始值数组// 秒分时号月份星期年sbit T_IO=P1^0; //与硬件相关的连线clk为DS1302的时钟信号线sbit T_CLK=P1^1; //DAT为DS1302的I/O数据线sbit T_RST=P1^2; //RST为DS1302的RST信号线uchar bdata datbyte;sbit datbyte0=datbyte^0;sbit datbyte7=datbyte^7;void get_1302(uchar time[]);void write_ds1302(uchar dat);uchar r_1302(uchar add);void w_1302(uchar add,uchar dat);uchar read_ds1302(void);void init_1302(uchar *time);/*==========================================D S 1 3 0 2 初始化===========================================*/void init_1302(uchar *time){uchar i, add;//uchar time_bcd[7];add=0x80;//0写入,1读出w_1302(0x8e,0x00);for(i=0;i<7;i++){w_1302(add,*time);add+=2;time++;}w_1302(0x8e,0x80);}//===========================// 读取当前时间//===========================void get_1302(uchar time[]){uchar i;uchar add=0x81;w_1302(0x8e,0x00);for(i=0;i<7;i++){time[i]=r_1302(add);add+=2;}w_1302(0x8e,0x80);}/*================================= DS1302写入一个字节(上升沿有效)=================================*/void write_ds1302(uchar dat){uchar i;datbyte=dat;for(i=0;i<8;i++){T_IO=datbyte0;T_CLK=1;T_CLK=0;datbyte=datbyte>>1;}}/*======================================= DS1302读取一个字节(下降沿有效)=======================================*/uchar read_ds1302(void){uchar i;for(i=0;i<8;i++){datbyte=datbyte>>1;datbyte7=T_IO;T_CLK=1;T_CLK=0;}return(datbyte);}/*========================================= 指定位置读取数据=========================================*/uchar r_1302(uchar add){uchar temp,dat1,dat2;T_RST=0;T_CLK=0;T_RST=1;write_ds1302(add);temp=read_ds1302();T_CLK=1;T_RST=0;dat1=temp/16;dat2=temp%16;temp=dat1*10+dat2;return(temp);}/*========================================== 指定位置写入数据==========================================*/void w_1302(uchar add,uchar dat){T_RST=0;T_CLK=0;T_RST=1;write_ds1302(add);write_ds1302(dat/10<<4|dat%10);T_CLK=1;T_RST=0;}=========================================== =============LCD1602驱动程序================#define LCD_DB P0//定义LCD的数据端口sbit LCD_RS=P2^0;sbit LCD_RW=P2^1;sbit LCD_E=P2^2;#define uchar unsigned char#define uint unsigned int//===========延时子函数======================== void delay_lcd(uint x){uint i,j;for(i=x;i>0;i--)for(j=0;j<2;j++);}//==================写指令函数================= void LCD_write_command(uchar command){LCD_DB=command;LCD_RS=0;//指令LCD_RW=0;//写入LCD_E=1;LCD_E=0;delay_lcd(1);//等待执行完毕。

ds1302源代码

ds1302源代码

#include <REGX51.H>#include<stdio.h>#include<absacc.h>#define uchar unsigned char#define uint unsigned intsbit P15=P1^5;sbit P16=P1^6;unsigned int i;//uchar seg[10]={0xc0,0xf9,0xa4,0xb0, // 0, 1, 2, 3 共阳数码管段码// 0x99,0x92,0x82,0xf8,0x80,0x90, 0xff}uchar seg[]={0x3f,0x06,0x5b,0x4f,0x66, //共阴数码管段码0x6d,0x7d,0x07,0x7f,0x6f};ucharsec,sec_1,sec_2,min,min_1,min_2,shi,shi_1,shi_2,ri,ri_1,ri_2,yue,yue_1,yue_2,year,year_1,year_2 ,flag;sbit T_CLK= P1^2; /*实时时钟时钟线引脚*/sbit T_IO = P1^3; /*实时时钟数据线引脚*/sbit T_RST= P1^4; /*实时时钟复位线引脚*/void delay(uint i) //延时函数{ uint j;while(i--)for(j=100;j>0;j--);}uchar read_1302(uchar address) //读地址一个字节的数据{uchar i,dat;T_CLK=0;T_RST=0;T_RST=1;for(i=0;i<8;i++){T_IO=address&0x01;T_CLK=0;T_CLK=1;address>>=1;}for (i=8;i>0;i--) //循环8次读取数据{if (T_IO==1){dat= dat|0x80;}T_CLK=1;T_CLK=0;dat= dat>>1 ;}return dat;}//}void write_1302(uchar address,uchar dd) //写一个字节格式是:地址,数据{T_CLK=0;T_RST=0;T_RST=1;for(i=0;i<8;i++){T_IO=address&0x01;T_CLK=0;T_CLK=1;address>>=1;}for(i=0;i<8;i++){T_IO=dd&0x01;T_CLK=0;dd>>=1;}T_RST=0;T_RST=1;}void set_1302() //设置时间{write_1302(0x8e,0x00); // 2009-10-09 mon:5 am;08:14:00 write_1302(0x80,0x20);write_1302(0x82,0x59);write_1302(0x84,0x23);write_1302(0x86,0x09);write_1302(0x88,0x10);write_1302(0x8a,0x05);write_1302(0x8c,0x09);write_1302(0x8e,0x80);}/*void key() //调节时间函数{if(P15==0){delay(50);flag=flag+1;}if(flag==3)flag=0;switch(flag){case 1:if(P16==0)write_1302(0x80,0x00);break;case 2:if(P16==0){uchar dd,zz;delay(200);dd=read_1302(0x83);if(dd&0x0f>=10){dd=dd&0xf0;dd+=16;}if(zz>=60)zz=0;write_1302(0x82,zz);} break;default:break;}}*/void covent_1302() //数据处理转换{sec=read_1302(0x81); //读秒寄存器min=read_1302(0x83); //读分寄存器shi=read_1302(0x85); //读时寄存器ri=read_1302(0x87); //读日寄存器yue=read_1302(0x89); //读月寄存器year=read_1302(0x8d); //读年寄存器sec_1=sec%16;sec_2=(sec&0x70)/16;min_1=min%16;min_2=(min&0x70)/16;shi_1=shi%16;shi_2=(shi&0x30)/16;ri_1=ri%16;ri_2=ri/16;yue_1=yue%16;yue_2=yue/16;year_1=year%16;year_2=year/16;}void disp() //显示函数{P3=seg[sec_1];/* if(flag==1){ if(i>20)P2=0xfe;elseP2=0xff;}else */P2=0xfe;delay(1);P3=0x00;P2=0xff;P3=seg[sec_2];/* if(flag==1){ if(i>20)P2=0xfd;elseP2=0xff;}else */P2=0xfd;delay(1);P3=0x00;P2=0xff;P3=0x40;P2=0xfb;delay(1);P3=0x00;P2=0xff;P3=seg[min_1];/* if(flag==2){ if(i>20)P2=0xf7;elseP2=0xff;}else*/ P2=0xf7;delay(1);P3=0x00;P2=0xff;P3=seg[min_2];/* if(flag==2){ if(i>20)P2=0xef;elseP2=0xff;}else*/ P2=0xef;delay(1);P3=0x00;P2=0xff;P3=0x40;P2=0xdf;delay(1);P3=0x00;P2=0xff;P3=seg[shi_1];P2=0xbf;delay(1);P3=0x00;P2=0xff;P3=seg[shi_2];P2=0x7f;delay(1);P3=0x00;P2=0xff;/* P3=seg[year_1];P2=0xbf;delay(1);P3=0x00;P2=0xff;P3=seg[year_2];P2=0x7f;delay(1);P3=0x00;P2=0xff;covent();*/P3=seg[ri_1];P0=0xef;delay(1);P3=0x00;P0=0xff;P3=seg[ri_2];P0=0xdf;delay(1);P3=0x00;P0=0xff;covent();P3=seg[yue_1];P0=0xbf;delay(1);P3=0x00;P0=0xff;P3=seg[yue_2];P0=0x7f;delay(1);P3=0x00;P0=0xff;covent();i++;if(i>50)i=0;}void main() //主函数{ // flag=0;set_1302();while(1){disp();// key();}}}。

基于DS1302的数码管时钟电路设计

基于DS1302的数码管时钟电路设计

单片机与可编程器件LED数码管时钟电路采用24h计时方式,时、分、秒用六位数码管显示,其中小时、分、秒之间用小数点分开。

 该电路采用AT89C52单片机和DS1302实时时钟芯片,使用5V电源进行供电,使用两个按键进行调时,调整过程中被调节的分钟或时钟将进入闪亮状态,看上去非常直观,另外,本设计还具有快速调时功能,当按键一直被按下时,便进入快速调时状态。

由于本时钟电路的计时是由芯片DS1302来完成的,计时准确 ,单片机通过串行通信来控制DS1302工作,同时进行键盘和显示的控制。

DS1302芯片介绍1.DS1302的功能及其结构DS1302芯片是美国DALLAS公司推出的低功耗实时时钟芯片,它采用串行通信方式,只需3条线便可以和单片机通信,并且其片内均含RAM,可增加系统的RAM,DS1302的时钟校准比较容易,若采用专用的晶体振荡器,几乎无须调整即可以达到国家要求的时钟误差标准。

DS1302有两个电源输入端,其中的一个用来做备用电源,这样避免了由于突然停电而造成时钟停止,因此它非常适合于长时间无人职守的监测控制系统或需经常记录某些具有特殊意义的数据及对应时间的场合。

DS1302提供秒、分、时、日、星期、月、年的信息,每月的天数和闰年的天数可自动调整,并可通过AM/PM 指示决定采用24 或12 小时格式。

DS1302串行时钟芯片主要由移位寄存器、控制逻辑、振荡器、实时时钟及31B的RAM组成。

在数据传送前,必须把RST置为高电平,且把提供地址和命令信息的8位装入到移位寄存器。

在进行单字节传送或多字节传送时,开始的8位命令字节用于指定40B(前31B RAM和9B时钟寄存器)中哪个将被访问。

在开始的8个时钟周期把命令装入移位寄存器之后,另外的时钟在读操作时输出数据,在写操作时输入数据。

DS1302的封装引脚示意图和内部结构图分别见图1和图2。

其中,X1、X2接32.768kHz 晶振,GND为地,复位线驱动至高电平,启动所有的数据传送。

基于DS1302的数字时钟设计

基于DS1302的数字时钟设计

一、设计目的 (1)二、设计思路 (1)三、设计过程 (1)五、主要元器件与设备 (10)六、课程设计体会 (10)七、参考文献 (10)一、设计目的1、掌握电子时钟的基本工作方式。

2、进一步熟悉DS1302芯片的特性。

3、通过使用各基本指令,进一步熟练掌握单片机的编程和程序调试。

二、设计思路利用AT89C52的特点及DS1302的特点,设计一种基于DS1302单片机控制,再利用数码管静态显示的可调可定时数字钟。

本系统硬件利用AT89S52作为CPU 进行总体控制,通过DS1302时钟芯片获取准确详细的时间(年、月、日、周、日、时、分、秒准确时间),对时钟信号进行控制,同时利用数码管对时间进行准确显示年、月、日、周、日、时、分、秒。

三、设计过程3.1系统设计结构图图1系统设计结构图根据系统设计的要求和设计思路,确定该系统的系统设计结构图。

如图1所示。

硬件电路主要由MCU微处理控制器单元、DS1302时钟电路、储存器、复位电路、晶振电路、数码管显示模块构成。

3.2 MCU微控制器电路AT89S52作为系统的核心控制元件,只有它能正常工作后才能使其它的元件进入正常工作状态。

因此,下面对AT89S52进行必要的说明,AT89S52的管脚如图3所示。

图3 AT89S52的管脚1)VCC:40脚,供电电压,一般接+5V电压。

2)GND:20脚,接工作地。

3)P0口:1~8脚,P0口是一个8位漏极开路的双向I/O口。

作为输出口,每位能驱动8个TTL逻辑电平。

对P0端口写“1”时,引脚用作高阻抗输入。

当访问外部程序和数据存储器时,P0口也被作为低8位地址/数据复用。

在这种模式下,P0具有内部上电阻。

但是P0口在程序校验作为输出指令字节时,需要外部加上拉电阻,一般上拉电阻选4.7K~10K为宜。

本设计中用5.1K的排阻对P0口进行上拉电平。

4)P1口:32~39脚,P1口是一个内部具有上拉电阻的8位双向I/O口,P1口缓冲器能接收输出4个TTL门电流。

DS1302时钟芯片C51源代码源程序

DS1302时钟芯片C51源代码源程序

DS1302时钟芯片C51源代码源程序DS1302--- 51C语言代码,头文件与对应C代码已分离开,直接可用(自己写,绝对可用。

)其中星期几能直接由日期按公式推算出来,time.week=(time.year/100)/4-2*(time.year/100)+(time.year%100)+(time.year%100)/4+26*(tim e.month+1)/10 +time.day-1;(详情请搜:蔡乐公式)///////////////////////////////////////////////////////////////DS1302头文件:#ifndef _ds1302_h_#define _ds1302_h_#define uchar unsigned char#define uint unsigned int#define ulong unsigned long#define u32 unsigned long intsbit sdinn = P2^6;sbit sclkk = P2^5;sbit cee = P2^7;#define second_w 0x80#define second_r 0x81#define minute_w 0x82#define minute_r 0x83#define hour_w 0x84#define hour_r 0x85#define day_w 0x86#define day_r 0x87#define month_w 0x88#define month_r 0x89#define year_w 0x8c#define year_r 0x8d#define week_w 0x8a#define week_r 0x8b#define protect_w 0xc0#define protect_r 0xc1#define clock_base_w 0xc2#define clock_base_r 0xc3#define clock_state_w 0xcc#define clock_state_r 0xcd#define D_protect 0x77typedef struct{uint year;uint month;uint day;uint hour;uint minute;uint second;uint week;} Time_info;void DS1302_Writebyte(uchar dat);void time_write2DS1302(Time_info Time);void time_read_from_DS1302(Time_info *Time);uchar DS1302_Readbyte();void DS1302Write(uchar cmd, uchar dat);uchar DS1302Read(uchar cmd);void Init_DS1302(void);void display_date(unsigned char X,unsigned char Y,Time_info Read_T); void writeDate2DS1302(Time_info Time);void time_HMS2DS1302(Time_info Time);void Alarm_respond();void sendtime2computer();#endif///////////////////////////////////////////////////////////DS1302-C代码:#include "option.h"xdata uchar trans_buf;extern xdata uchar Date_Index;extern xdata uchar Time_Index;extern xdata uchar Write_date_buff[15];extern xdata uchar Alarm_buff[7];extern xdata uchar Alarm_arrive;extern xdata uchar arriveminute;extern xdata uchar Alarm_state;extern xdata Time_info Read_Time;xdata uchar tiao_buff[30];xdata uint hour,minute,second;xdata uchar old_second=250;void delay(unsigned long int i){while(i--);}void time_write2DS1302(Time_info Time)DS1302Write(0x8e,0x00);//写保护关trans_buf = ((Time.year%100/10)<<4)+((Time.year%10)&0X0F); // 写入年DS1302Write(year_w, trans_buf);trans_buf = (((Time.month%100/10)<<4)&0x10) + ((Time.month%10)&0X0F); //写入月DS1302Write(month_w, trans_buf);trans_buf = (((Time.day%100/10)<<4)&0x30) + ((Time.day%10)&0X0F);//写入日DS1302Write(day_w, trans_buf);trans_buf = (((Time.hour%100/10)<<4)&0x30)+((Time.hour%10)&0X0F);//写入时DS1302Write(hour_w, trans_buf);trans_buf = (((Time.minute%100/10)<<4)&0x70) + ((Time.minute%10)&0X0F); //写入分DS1302Write(minute_w, trans_buf);trans_buf = (((Time.second%100/10)<<4)&0x70) + ((Time.second%10)&0X0F); //写入秒DS1302Write(second_w, trans_buf);trans_buf = Time.week%7; //写入星期DS1302Write(week_w, trans_buf);DS1302Write(0x8e,0x80); //开写保护}void writeDate2DS1302(Time_info Time){DS1302Write(0x8e,0x00);//写保护关trans_buf = ((Time.year%100/10)<<4)+((Time.year%10)&0X0F); // 写入年DS1302Write(year_w, trans_buf);trans_buf = (((Time.month%100/10)<<4)&0x10) +((Time.month%10)&0X0F); //写入月DS1302Write(month_w, trans_buf);trans_buf = (((Time.day%100/10)<<4)&0x30) + ((Time.day%10)&0X0F);//写入日DS1302Write(day_w, trans_buf);Time.week = (int)(Time.year/100)/4-(int)2*(Time.year/100)+(int)(Time.year%100)+(int)(Time.year%100)/4+(int)26*(Time.mo nth+1)/10+(int)Time.day-1;// printf("--week:%5d--",Time.week);Time.week %= 7;if(Time.week == 0) Time.week = 7;trans_buf = Time.week; //写入星期DS1302Write(week_w, trans_buf);DS1302Write(0x8e,0x80); //开写保护}void time_HMS2DS1302(Time_info Time){DS1302Write(0x8e,0x00);//写保护关trans_buf = (((Time.hour%100/10)<<4)&0x30)+((Time.hour%10)&0X0F);//写入时DS1302Write(hour_w, trans_buf);trans_buf = (((Time.minute%100/10)<<4)&0x70) + ((Time.minute%10)&0X0F); //写入分DS1302Write(minute_w, trans_buf);trans_buf = (((Time.second%100/10)<<4)&0x70) + ((Time.second%10)&0X0F); //写入秒DS1302Write(second_w, trans_buf);DS1302Write(0x8e,0x80); //开写保护}void time_read_from_DS1302(Time_info *Time){Time->year = DS1302Read(year_r);Time->month = DS1302Read(month_r);Time->day = DS1302Read(day_r);Time->hour = DS1302Read(hour_r);Time->minute = DS1302Read(minute_r);Time->second = DS1302Read(second_r);Time->week = DS1302Read(week_r);Time->year = 2000+((Time->year>>4)*10)+(Time->year&0x0f);Time->month = ((Time->month>>4)*10) + (Time->month&0x0f);Time->day = (Time->day>>4)*10 + (Time->day&0x0f);Time->hour = (Time->hour>>4)*10 + (Time->hour&0x0f);Time->minute = ((Time->minute>>4)*10) + (Time->minute&0x0f);Time->second = (Time->second>>4)*10 + (Time->second&0x0f); }void DS1302_Writebyte(uchar dat){uchar i;sclkk = 0;delay(300);for(i = 0; i < 8; i++){sdinn = dat & 0x01;delay(90);sclkk = 1;delay(180);sclkk = 0;dat >>= 1;}}uchar DS1302_Readbyte(){uchar i, dat = 0;delay(90);for(i = 0; i < 8; i++){dat >>=1;if(sdinn)dat |= 0x80;sclkk = 1;delay(60);sclkk = 0;delay(60);}sdinn = 0;return dat;}void DS1302Write(uchar cmd, uchar dat) {cee = 0;sclkk = 0;cee = 1;DS1302_Writebyte(cmd);DS1302_Writebyte(dat);sclkk = 1;cee = 0;}uchar DS1302Read(uchar cmd) {uchar dat = 0;cee = 0;sclkk = 0;cee = 1;DS1302_Writebyte(cmd);dat = DS1302_Readbyte();sclkk = 1;cee = 0;return dat;}void Init_DS1302(void){Time_info time;uchar init_state;DS1302Write(0x8e,0x00);//写保护关init_state = DS1302Read(protect_r); DS1302Write(0x8e,0x80); //开写保护if(init_state != D_protect){time.year = 2014;time.month = 12;time.day = 5;time.hour = 18;time.minute = 57;time.second = 50; //日期换算为星期[c/4]-2c+y+[y/4]+[26(m+1)/10]+d-1time.week = (time.year/100)/4-2*(time.year/100)+(time.year %100)+(time.year%100)/4+26*(time.month+1)/10+time.da y-1;time.week %= 7;if(time.week == 0) time.week = 7;time_write2DS1302(time);DS1302Write(0x8e,0x00);//写保护关DS1302Write(protect_w,D_protect); //初始化一次标示DS1302Write(0x8e,0x80); //开写保护}DS1302Write(0x8e,0x00);//写保护关Alarm_buff[0] = DS1302Read(clock_base_r+0);Alarm_buff[1] = DS1302Read(clock_base_r+2);Alarm_buff[2] = DS1302Read(clock_base_r+4);Alarm_buff[3] = DS1302Read(clock_base_r+6);Alarm_buff[4] = DS1302Read(clock_base_r+8);Alarm_buff[5] = DS1302Read(clock_base_r+10);Alarm_state = DS1302Read(clock_state_r);DS1302Write(0x8e,0x80); //开写保护}void display_date(unsigned char X,unsigned char Y,Time_info Read_T) {xdata char dis_info[12];sprintf(dis_info, "%04d/%02d/%02d", (int)Read_T.year, (int) Read_T.month, (int)Read_T.day);LCD_write_english_string(X,Y,dis_info);sprintf(dis_info, "%02d/%02d/%02d", (int)Read_T.hour, (int) Read_T.minute, (int)Read_T.second);LCD_write_english_string(X+6,Y+1,dis_info);sprintf(dis_info, "Week:%d", (int)Read_T.week);LCD_write_english_string(X+12,Y+2,dis_info);}void Alarm_respond(){hour = (uint)Alarm_buff[0]*10+Alarm_buff[1];minute = (uint)Alarm_buff[2]*10+Alarm_buff[3];second = (uint)Alarm_buff[4]*10+Alarm_buff[5];if(Alarm_state==1){time_read_from_DS1302(&Read_Time);if((old_second < Read_Time.second)||(Read_Time.second==0)){if(arriveminute!=Read_Time.minute) Alarm_arrive = 0;if((Read_Time.hour == hour)&&(Read_Time.minute== minute)&&(Read_Time.second == second)){Alarm_arrive = 1;arriveminute = Read_Time.minute;}}old_second = Read_Time.second;}}void sendtime2computer(){time_read_from_DS1302(&Read_Time);printf("time%04d/%02d/%02d/%02d:%02d:%02d", Read_Time.year, Read_Time.month, Read_Time.day, Read_Time.hour, Read_Time.minute,Read_Time.second);printf("%d--\n",Read_Time.week);}。

基于DS1302的单片机数字时钟

基于DS1302的单片机数字时钟

源程序如下:#include <at89x52.h>#include <DS1302.h>//定义共阳极字型码0123456789-//unsigned char code dispcode[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf}; unsigned char code dispcode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40}; unsigned char time[]={0,0,0,0,0,0,0,0};//用来储存时间unsigned char date[]={0,0,0,0,0,0,0,0};//用来储存日期SYSTEMTIME time1; //在ds1302.h文件中已经定义了一个名字为SYSTEMTIME的结构体,在这里我们定义一个变量名//为time的SYSTEMTIME结构体void delay(unsigned char i) //延时子程序{unsigned char j;while((i--)!=0){for(j=123;j>0;j--);}}unsigned char button_time(n,x,y) //时钟调整子程序unsigned char n,x,y;{if(P1_7==0){delay(50);if(P1_7==0){n++;if(n==x)n=0;while(P1_7==0);}}if(P1_5==0){delay(50);if(P1_5==0){if(n==0)n=y;elsen--;while(P1_5==0);}return n;}unsigned char button_date(n,x,y) //日期调整子程序unsigned char n,x,y;{if(P1_7==0){delay(50);if(P1_7==0){n++;if(n==x)n=1;while(P1_7==0);}}if(P1_5==0){delay(50);if(P1_5==0){if(n==1)n=y;elsen--;while(P1_5==0);}}return n;}void display(second10,second1,minute10,minute1,hour10,hour1) //显示子程序unsigned char second10,second1,minute10,minute1,hour10,hour1;{P2=0xfe;P0=dispcode[second10];//显示秒的十位delay(1);P2=0xfd;P0=dispcode[second1]; //显示秒的个位P2=0xfb;P0=dispcode[10]; //显示"-"delay(1);P2=0xf7;P0=dispcode[minute10];//显示分的十位delay(1);P2=0xef;P0=dispcode[minute1]; //显示分的个位delay(1);P2=0xdf;P0=dispcode[10]; //显示"-"delay(1);P2=0xbf;P0=dispcode[hour10]; //显示时的十位delay(1);P2=0x7f;P0=dispcode[hour1]; //显示时的个位delay(1);}void main(){unsigned char flag;Initial_DS1302(); //初始化DS1302这个时钟芯片, while(1){DS1302_GetTime(&time1); //读取时间参数time[5]=(time1.Second)%10; //把秒的个位数据存入time[5]time[4]=(time1.Second)/10; //把秒的十位数据存入time[4]time[3]=(time1.Minute)%10; //把分的个位数据存入time[3]time[2]=(time1.Minute)/10; //把分的十位数据存入time[2]time[1]=(time1.Hour)%10; //把时的个位数据存入time[1]time[0]=(time1.Hour)/10; //把时的十位数据存入time[0] date[5]=(time1.Day)%10;date[4]=(time1.Day)/10;date[3]=(time1.Month)%10;date[2]=(time1.Month)/10;date[1]=(time1.Year)%10;date[0]=(time1.Year)/10;if(P1_4==0) //如果按下Time Start键一下,时钟开始正常显示时间,再按一下,显示日期{delay(50);if(P1_4==0){flag++;if(flag>1){flag=0;}}while(P1_4==0);}if(P1_6==0) //如果按下Time Set键一下,开始显示日期,再按一下进入日期跟时钟的调节模式{delay(50);if(P1_6==0){flag++;if(flag>7){flag=0;}}while(P1_6==0);}switch(flag){case 0:display(time[0],time[1],time[2],time[3],time[4],time[5]); //调用子函数display,把存入数组time的数据给显示出来break;case 1:display(date[0],date[1],date[2],date[3],date[4],date[5]); //调用子函数display,把存入数组date的数据给显示出来break;case 2:time1.Year=button_date(time1.Year,100,99); //调整年DS1302_SetTime(0x8c,time1.Year);display(date[0],date[1],10,10,10,10);break;case 3:time1.Month=button_date(time1.Month,13,12); //调整月DS1302_SetTime(0x88,time1.Month);display(10,10,date[2],date[3],10,10);break;case 4:time1.Day=button_date(time1.Day,32,31); //调整日DS1302_SetTime(0x86,time1.Day);display(10,10,10,10,date[4],date[5]);break;case 5:time1.Hour=button_time(time1.Hour,24,23); //调整时DS1302_SetTime(0x84,time1.Hour);display(time[0],time[1],10,10,10,10);break;case 6:time1.Minute=button_time(time1.Minute,60,59); //调整分DS1302_SetTime(0x82,time1.Minute);display(10,10,time[2],time[3],10,10);break;case 7:time1.Second=button_time(time1.Second,60,59); //调整秒DS1302_SetTime(0x80,time1.Second);display(10,10,10,10,time[4],time[5]);break;}}}头文件ds1302.h程序如下:#ifndef _REAL_TIMER_DS1302_2003_7_21_#define _REAL_TIMER_DS1302_2003_7_21_#include <at89x52.h>sbit DS1302_CLK = P1^0; //实时时钟时钟线引脚sbit DS1302_IO = P1^1; //实时时钟数据线引脚sbit DS1302_RST = P1^2; //实时时钟复位线引脚sbit ACC0 = ACC^0;sbit ACC7 = ACC^7;typedefstruct __SYSTEMTIME__{unsigned char Second;unsigned char Minute;unsigned char Hour;unsigned char Week;unsigned char Day;unsigned char Month;unsigned char Year;unsigned char DateString[9];unsigned char TimeString[9];}SYSTEMTIME; //定义的时间类型#define AM(X) X#define PM(X) (X+12) // 转成24小时制#define DS1302_SECOND 0x80 //秒寄存器#define DS1302_MINUTE 0x82 //分寄存器#define DS1302_HOUR 0x84#define DS1302_WEEK 0x8A#define DS1302_DAY 0x86#define DS1302_MONTH 0x88#define DS1302_YEAR 0x8C#define DS1302_RAM(X)(0xC0+(X)*2) //用于计算DS1302_RAM 地址的宏void DS1302InputByte(unsigned char d) //实时时钟写入一字节(内部函数) {unsigned char i;ACC = d;for(i=8; i>0; i--){DS1302_IO = ACC0; //相当于汇编中的RRCDS1302_CLK = 1;DS1302_CLK = 0; //发一个高跳变到低的脉冲ACC = ACC >> 1;}}unsigned char DS1302OutputByte(void) //实时时钟读取一字节(内部函数) {unsigned char i;for(i=8; i>0; i--){ACC = ACC >>1; //相当于汇编中的RRCACC7 = DS1302_IO;DS1302_CLK = 1;DS1302_CLK = 0; //发一个高跳变到低的脉冲}return(ACC);}void Write1302(unsigned char ucAddr, unsigned char ucDa) //ucAddr: DS1302地址, ucData: 要写的数据{DS1302_RST = 0;DS1302_CLK = 0;DS1302_RST = 1;DS1302InputByte(ucAddr); // 地址,命令DS1302InputByte(ucDa); // 写1Byte数据DS1302_CLK = 1;DS1302_RST = 0; //RST 0->1->0,CLK 0->1}unsigned char Read1302(unsigned char ucAddr) //读取DS1302某地址的数据{unsigned char ucData;DS1302_RST = 0;DS1302_CLK = 0;DS1302_RST = 1; //enableDS1302InputByte(ucAddr|0x01); // 地址,命令ucData = DS1302OutputByte(); // 读1Byte数据DS1302_CLK = 1; //RST 0->1->0,CLK 0->1DS1302_RST = 0;return(ucData);}void DS1302_SetProtect(bit flag) //是否写保护{if(flag)Write1302(0x8E,0x10); //WP=1,不能写入elseWrite1302(0x8E,0x00);//WP=0,可以写入}void DS1302_SetTime(unsigned char Address, unsigned char Value) // 设置时间函数{DS1302_SetProtect(0);Write1302(Address, ((Value/10)<<4 | (Value%10))); //高4位为十位,低4位为个位}void DS1302_GetTime(SYSTEMTIME *Time){unsigned char ReadValue;ReadValue = Read1302(DS1302_SECOND);Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);//转换成10进制的秒ReadValue = Read1302(DS1302_MINUTE);Time->Minute = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue = Read1302(DS1302_HOUR);Time->Hour = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue = Read1302(DS1302_DAY);Time->Day = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue = Read1302(DS1302_WEEK);Time->Week = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue = Read1302(DS1302_MONTH);Time->Month = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue = Read1302(DS1302_YEAR);Time->Year = ((ReadValue&0xf0)>>4)*10 + (ReadValue&0x0F);}/*voidDateToStr(SYSTEMTIME *Time){Time->DateString[0] = Time->Year/10 + '0'; //数字类型转化为字符类型Time->DateString[1] = Time->Year%10 + '0';Time->DateString[2] = '-';Time->DateString[3] = Time->Month/10 + '0';Time->DateString[4] = Time->Month%10 + '0';Time->DateString[5] = '-';Time->DateString[6] = Time->Day/10 + '0';Time->DateString[7] = Time->Day%10 + '0';Time->DateString[8] = '\0';}voidTimeToStr(SYSTEMTIME *Time){Time->TimeString[0] = Time->Hour/10 + '0'; //数字类型转化为字符类型Time->TimeString[1] = Time->Hour%10 + '0';Time->TimeString[2] = ':';Time->TimeString[3] = Time->Minute/10 + '0';Time->TimeString[4] = Time->Minute%10 + '0';Time->TimeString[5] = ':';Time->TimeString[6] = Time->Second/10 + '0';Time->TimeString[7] = Time->Second%10 + '0';Time->DateString[8] = '\0';}*/void Initial_DS1302(void){unsigned char Second=Read1302(DS1302_SECOND);if(Second&0x80) //如果第七为1(表明没有启动), 则启动时钟DS1302_SetTime(DS1302_SECOND,0);}/****************************************************************************** **void BurstWrite1302(unsigned char *pWClock) //往DS1302写入时钟数据(多字节方式) {unsigned char i;Write1302(0x8e,0x00); // 控制命令,WP=0,写操作?DS1302_RST = 0;DS1302_CLK = 0;DS1302_RST = 1;DS1302InputByte(0xbe); // 0xbe:时钟多字节写命令for (i = 8; i>0; i--) //8Byte = 7Byte 时钟数据+ 1Byte 控制{DS1302InputByte(*pWClock); // 写1Byte数据pWClock++;}DS1302_CLK = 1;DS1302_RST = 0;}void BurstRead1302(unsigned char *pRClock) //读取DS1302时钟数据(时钟多字节方式) {unsigned char i;DS1302_RST = 0;DS1302_CLK = 0;DS1302_RST = 1;DS1302InputByte(0xbf); // 0xbf:时钟多字节读命令for (i=8; i>0; i--){*pRClock = DS1302OutputByte(); // 读1Byte数据pRClock++;}DS1302_CLK = 1;DS1302_RST = 0;}void DS1302_TimeStop(bit flag) // 是否将时钟停止{unsigned char Data;Data=Read1302(DS1302_SECOND);DS1302_SetProtect(0);if(flag)Write1302(DS1302_SECOND, Data|0x80);//停止elseWrite1302(DS1302_SECOND, Data&0x7F);不停止}******************************************************************************* */#endif。

DS1302数码管电子闹钟程序

DS1302数码管电子闹钟程序
buzzer=1;
}
void keyscan()//按键扫描程序
{
uchar temp;
if(key1==0) //功能键
{
if(key1==0)
{
while(!key1);
key1n=key1n++;
if(key1n==5)
key1n=1;
switch(key1n)
{
case 1://didi();
{
P2=0x7f;
P0=tab[miaog];
delay(5);
P2=0xbf;
P0=tab[miaos];
delay(5);
P2=0xdf;
P0=0xc0;
delay(5);
P2=0xef;
P0=tab[feng];
delay(5);
P2=0xf7;
P0=tab[fens];
delay(5);
P2=0xfb;
void delay(uint xms)
{
uint x,y;
for(x=xms;x>0;x--)
for(y=110;y>0;y--);
}
void init()//初始化
{
//RST=0;
//SCLK=0;
//write_1302(0x80,0x00);//写控制字,允许写
//write_1302(0x90,0x00);//禁止涡流充电
if(clock1[1]>59)clock1[1]=0;
}
}
}
if(keyn==3) //秒修改
{
if(key3==0) //减键
{
//delay(3);

ds1302电路+程序

ds1302电路+程序
**函数名称:Write_Ds1302( uchar address,uchar dat )
**函数功能:写入DS1302
********************************************************************************
*/
void Write_Ds1302( uchar address,uchar dat )
*【Q Q】:348439350
*【声明】:此程序仅用于学习与参考,引用请注明版权和作者信息!
*【函数功能】:DS1302串行数码管显示时钟
*【接线说明】:时钟模块与单片机连接:SCLK- P3.6 I/O-P3.4 RST-P3.5 VCC-VCC GND-GND
串行数码管模块与单片机连接:DIO-P2.2 SCK-P2.4 RCK-P2.3 VCC-VCC GND-GND
void delay(uint z);
/*变量定义-----------------------------------------------*/
sbit SCK=P3^6;//时钟
sbit SDA=P3^4;//数据
sbit RST=P3^5;// DS1302复位
unsigned char m;
#define uchar unsigned char
#define uint unsigned int
/*函数申明-----------------------------------------------*/
void Set_RTC(void);
void Read_RTC(void);
uchar Read_Ds1302 ( uchar address );

基于ds1302数字时钟电路的设计

基于ds1302数字时钟电路的设计

1 引言从古代的滴漏更鼓到近代的机械钟,从电子表到目前的数字时钟,为了准确的测量和记录时间,人们一直在努力改进着计时工具。

钟表的数字化,大力推动了计时的精确性和可靠性。

在单片机构成的装置中,实时时钟是必不可少的部件。

目前常用的实时时钟,很多采用单片机的中断服务来实现,这种方式一方面需要采用计数器,占用硬件资源,另一方面需要设置中断、查询等,同样耗费单片机的资源,而且某些测控系统可能不允许;有的则使用并行接口的时钟芯片,如MC146818、DS12887等,它们虽然能满足单片机系统对实时时钟的要求,但是这些芯片与单片机接口复杂,占用地址、数据总线多,芯片体积大,占用空间多,给其它设计带来诸多不便。

本设计选取串行接口时钟芯片DS1302与单片机同步通信构成数字时钟电路。

其简单的三线接口能为单片机节省大量资源,DS1302的后背电源及对后背电源进行涓细电流充电的能力保证电路断电后仍能保存时间和数据信息等。

这些优点解决了目前常用的实时时钟所无法解决的问题。

该时钟电路强大的功能和优越的性能,在很多领域的应用中,尤其是某些自动化控制、长时间无人看守的测控系统等对时钟精确性和可靠性有较高要求的场合,具有很高的使用价值。

1.1 多功能数字钟的起源1350年6月6日意大利人乔万尼•德•党笛制造了世界上第一台结构简单的机械打点多功能数字钟。

1657年,荷兰人惠更斯首先把重力摆引入机械钟,从而创立了摆钟。

到了20世纪,随着电子工业的迅速发展,电池驱动钟、交流电钟、电机械表、指针式石英电子钟表、数字显示式石英钟表相继问世,多功能数字钟的日差已小于0.5秒。

特别是原子钟的出现,它是原子的振动来控制,是目前世界上最精确的钟,即使经过100万年,其偏差也不会超过1秒钟。

多功能数字钟最早起源于欧洲中世纪的教堂,是完全机械式结构,动力使用重锤,打点钟声完全使用人工撞击铸钟,因此当时一个多功能数字钟工程在建筑和机械结构方面是相当复杂的。

时钟芯片DS1302数码管程序

时钟芯片DS1302数码管程序
void write(uchar address,uchar number)
{
uchar i;
dsclk=0;//清零时钟总线
dsdata=0;//清零数据总线
dsret=0;//片选端无效
dsret=1;//逻辑控制有效,可对1302操作
for(i=16;i>0;i++)
dsclk=1;
}
dsclk=1;//上升沿动作
dsret=0;//片选无效,不可进行操作
}
/*********** 时间显示函数**************/
void show(
{
uchar i;
for(i=0;i<8;i++) // 数码管有8位,因此需要循环8次
{
uchar code tab[8]={0xf7,0xfb,0Xfd,0Xfe,0x7f,0xbf,0xdf,0xef};//数码管显示位选端
uchar buf[8];//申请数据暂存空间
/********** 延时函数************/
void delay(uchar i)
{
while(--i);
address=address>>1;
if(dsdata)
address=address|0x80;
dsclk=1;//上升沿动作
dsclk=1;//等待
}
dsclk=1;//时钟置高
dsret=0;//片选无效
return (address);
}
/*********** 写 ***************/

基于DS1302的时钟程序

基于DS1302的时钟程序

/************************************//*DS1302测试程序*//*目标器件:A T89S51 *//*晶振:11.0592MHZ *//*编译环境:Keil 7.50A *//************************************//*********************************包含头文件********************************/#include "reg51.h"#include <intrins.h>/*********************************端口定义**********************************/ sbit DS1302_CLK = P1^0;sbit DS1302_IO = P1^1;sbit DS1302_RST = P1^2;/*******************************共阳LED段码表*******************************/ unsigned char code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};/******************************定义全局变量*********************************/ unsigned char second,minute,hour,week,day,month,year; //秒、分、时、星期、日、月、年unsigned char time[]={0x06,0x03,0x14,0x03,0x12,0x30,0x00}; //初始时间数组/**************************************************************************** 函数功能:数码管扫描延时子程序入口参数:出口参数:****************************************************************************/ void delay1(void){int k;for(k=0;k<400;k++);}/**************************************************************************** 函数功能:数码管显示子程序入口参数:k出口参数:****************************************************************************/ void display(void){P2=0xfe;P0=tab[hour/16];delay1();P2=0xfd;P0=tab[hour%16];delay1();P2=0xfb;P0=0xbf; //显示"-"delay1();P2=0xf7;P0=tab[minute/16];delay1();P2=0xef;P0=tab[minute%16];delay1();P2=0xdf;P0=0xbf; //显示"-"delay1();P2=0xbf;P0=tab[second/16];delay1();P2=0x7f;P0=tab[second%16];delay1();}/***************************************************************************** 函数功能:向DS1302送一字节数据子程序入口参数:出口参数:*****************************************************************************/ void InputByte(unsigned char byte1){char i;for(i=8;i>0;i--){DS1302_IO=(bit)(byte1&0x01);DS1302_CLK=1;_nop_();DS1302_CLK=0;byte1>>=1;}return;}/***************************************************************************** 函数功能:读DS1302一个字节子程序入口参数:出口参数:*****************************************************************************/ unsigned char outputbyte(void){unsigned char i;unsigned ucdat=0;for(i=8;i>0;i--){DS1302_IO=1;ucdat>>=1;if(DS1302_IO)ucdat|=0x80;DS1302_CLK=1;_nop_();DS1302_CLK=0;}return(ucdat);}/***************************************************************************** 函数功能:向DS1302某地址写一字节数据子程序入口参数:addr,TDat出口参数:*****************************************************************************/ void write_ds1302(unsigned char addr,unsigned char TDat){DS1302_RST=0;_nop_();DS1302_CLK=0;_nop_();DS1302_RST=1;InputByte(addr);_nop_();InputByte(TDat);DS1302_CLK=1;_nop_();DS1302_RST=0;}/***************************************************************************** 函数功能:读DS1302地址子程序入口参数:add出口参数:timedata*****************************************************************************/ unsigned char read_ds1302(unsigned char addr){unsigned char timedata;DS1302_RST=0;_nop_();DS1302_CLK=0;_nop_();DS1302_RST=1;InputByte(addr);timedata=OutputByte();DS1302_CLK=1;_nop_();DS1302_RST=0;return(timedata);}/***************************************************************************** 函数功能:初始化DS1302子程序入口参数:time[](全局变量)出口参数:*****************************************************************************/ void initial_ds1302(){write_ds1302(0x8e,0x00); //写保护寄存器,在对时钟或RAM写前WP一定要为0write_ds1302(0x8c,time[0]); //年write_ds1302(0x88,time[1]); //月write_ds1302(0x86,time[2]); //日write_ds1302(0x8A,time[3]); //星期write_ds1302(0x84,time[4]); //时write_ds1302(0x82,time[5]); //分write_ds1302(0x80,time[6]); //秒write_ds1302(0x8e,0x80); //写保护寄存器}/***************************************************************************** 函数功能:读DS1302时间子程序入口参数:出口参数:全局变量(second,minute,hour,week,day,month,year)*****************************************************************************/ void read_time(){second=read_ds1302(0x81); //秒寄存器minute=read_ds1302(0x83); //分hour=read_ds1302(0x85); //时week=read_ds1302(0x8B); //星期day=read_ds1302(0x87); //日month=read_ds1302(0x89); //月year=read_ds1302(0x8d); //年}/***************************************************************************** 函数功能:主程序入口参数:出口参数:*****************************************************************************/ void main(void){initial_ds1302(); //初始化DS1302while(1){read_time(); //读取时间display(); //显示时间}}。

DS1302程序代码

DS1302程序代码

DS1302程序代码#include <reg51.h>#include <string.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intsbit SDA=P1^0; //DS1302数据线sbit CLK=P1^1; //DS1302时钟线sbit RST=P1^2; // DS1302 复位线char Adjust_Index=-1; //当前调节的时间对象:秒,分,时,日,月,年(0,1,2,3,4,6)uchar MonthsDays[]={0,31,0,31,30,31,30,31,31,30,31,30,31}; // 一年中每个月的天数,二月的天数由年份决定uchar DateTime[7];//所读取的日期时间//函数声明void Write_Byte_TO_DS1302(uchar X); // 向DS1302写入一个字节uchar Read_Byte_FROM_DS1302(); //从DS1302中读取一个字节uchar Read_Data_FROM_DS1302(uchar addr); //从DS1302指定位置读取数据, 读数据void Write_Data_TO_DS1302(uchar addr,uchar dat); // 向DS1302指定位置写入数据, 写数据void SET_DS1302(); // 设置时间void GetTime(); // 读取当前时间uchar Is_Leapyear(uint year);// 判断是否为闰年//*--------写字节函数,向DS1302写入一个字节--------*//void Write_Byte_TO_DS1302(uchar X) // 向DS1302写入一个字节{uchar i;for(i=0;i<8;i++){SDA=X&1;CLK=1;CLK=0;X>>=1;}}//*--------读字节函数,从DS1302读取一个字节--------*//uchar Read_Byte_FROM_DS1302() //从DS1302中读取一个字节{uchar i,byte,t;for(i=0;i<8;i++){byte>>=1;t=SDA;byte|=t<<7;CLK=1;CLK=0;}//BCD码转换return byte/16*10+byte%16;}//-------------------------------------------------------------//从DS1302指定位置读取数据 , 读数据//---------------------------------------------------------------uchar Read_Data_FROM_DS1302(uchar addr) //从DS1302指定位置读取数据 , 读数据{uchar dat;RST=0;CLK=0;RST=1;Write_Byte_TO_DS1302(addr); //向DS1302写入一个地址dat=Read_Byte_FROM_DS1302(); //在上面写入的地址中读取数据CLK=1;RST=0;return dat;}//-------------------------------------------------------------//向DS1302指定位置写入数据, 写数据//---------------------------------------------------------------void Write_Data_TO_DS1302(uchar addr,uchar dat) // 向DS1302指定位置写入数据, 写数据{CLK=0;RST=1;Write_Byte_TO_DS1302(addr);Write_Byte_TO_DS1302(dat);CLK=1;RST=0;}//-----------------------------------------------------------// 设置时间//---------------------------------------------------------void SET_DS1302() // 设置时间{uchar i;Write_Data_TO_DS1302(0x8E,0x00); //写控制字,取消写保护// 分,时,日,月,年依次写入for(i=1;i<7;i++){// 分的起始地址是10000010(0x82),后面依次是时,日,月,周,年,写入地址每次递增2Write_Data_TO_DS1302(0x80+2*i,(DateTime[i]/10<<4)|(DateTime[i]%10));}Write_Data_TO_DS1302(0x8E,0x80); //写控制字,加写保护}//--------------------------------------------------------// 读取当前时间//-------------------------------------------------------void GetTime() // 读取当前时间{uchar i;for(i=0;i<7;i++){DateTime[i]=Read_Data_FROM_DS1302(0x81+2*i);}}//-------------------------------------------------------------------// 判断是否为闰年//-------------------------------------------------------------------uchar Is_Leapyear(uint year){return (year%4==0&&year%100!=0)||(year%400==0) ;}//------------------------------------------------------------------// 求自2000.1.1开始的任何一天是星期几?//----------------------------------------------------------------------void Refresh_Week_Day(){uint i,d,w=5; //已知1999年12.31是星期五for(i=2000;i<2000+DateTime[6];i++){d=Is_Leapyear(i)?366:365;w=(w+d)%7;}d=0;for (i=1;i<DateTime[4];i++){d+=MonthsDays[i];}d+=DateTime[3];//保存星期,0-6表示星期日,星期一至星期六,为了与DS1302的星期格式匹配,返回值需要加1DateTime[5]=(w+d)%7+1;}//-------------------------------------------------//年,月,日和时,分++/--//----------------------------------------------------void Datetime_Adjust(char X){switch(Adjust_Index){case 6: //年调整,00-99if(X==1&&DateTime[6]<99){DateTime[6]++;}if(X==-1&&DateTime[6]>0){DateTime[6]--;}//获取2月天数MonthsDays[2]=Is_Leapyear(2000+DateTime[6])?29:28;//如果年份变化后当前月份的天数大于上限则设为上限if(DateTime[3]>MonthsDays[DateTime[4]]){DateTime[3]=MonthsDays[DateTime[4]];}Refresh_Week_Day(); //刷新星期break;case 4: //月调整01-12if(X==1&&DateTime[4]<12){DateTime[4]++;}if(X==-1&&DateTime[4]>1){DateTime[4]--;}//获取2月天数MonthsDays[2]=Is_Leapyear(2000+DateTime[6])?29:28;//如果年份变化后当前月份的天数大于上限则设为上限if(DateTime[3]>MonthsDays[DateTime[4]]){DateTime[3]=MonthsDays[DateTime[4]];}Refresh_Week_Day(); //刷新星期break;case 3: // 日调整00-28或00-29或00-30或00-31//调节之前首先根据当前年份得出该年中2月的天数MonthsDays[2]=Is_Leapyear(2000+DateTime[6])?29:28;//根据当前月份决定调节日期的上限if(X==1&&DateTime[3]<MonthsDays[DateTime[4]]){DateTime[3]++;}if(X==-1&&DateTime[3]>0){DateTime[3]--;}Refresh_Week_Day(); //刷新星期break;case 2: // 时调整if(X==1&&DateTime[2]<23){DateTime[2]++;}if(X==-1&&DateTime[4]>0){DateTime[2]--;}break;case 1: // 分调整if(X==1&&DateTime[1]<59){DateTime[1]++;}if(X==-1&&DateTime[4]>0){DateTime[1]--;}break;case 0: // 秒调整if(X==1&&DateTime[1]<59){DateTime[0]++;}if(X==-1&&DateTime[4]>0){DateTime[0]--;}break;}}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

基于DS1302的数码管时钟电路设计源程序时钟电路设计的程序清单:;* 基于DS1302的时钟电路设计*;****************************************T_CLK EQU P3.3 ; 时钟线引脚T_IO EQU P3.4 ; 数据线引脚T_RST EQU P3.2 ; 复位线引脚SECOND EQU 30H ;秒数据存储单元CMIN EQU 31H ;分数据CHR EQU 32H ;小时数据CDA TE EQU 33H ;日数据CMONTH EQU 34H ;月数据CDAY EQU 35H ;星期数据CYEAR EQU 36H ;年数据低2位ORG 0000H ;程序执行开始地址LJMP START ;跳至START执行ORG 0003H ;外中断0中断入口地址RETI ;中断返回(不开中断)ORG 000BH ;定时器T0中断入口地址RETI ;中断返回(不开中断)ORG 0013H ;外中断1中断入口地址RETI ;中断返回(不开中断)ORG 001BH ;定时器T1中断入口地址LJMP INTT1 ;进入定时器中断程序ORG 0023H ;串行口中断入口地址RETI ;中断返回(不开中断)ORG 002BH ;定时器T2中断入口地址RETI ;中断返回(不开中断)ORG 0100H;****************************************; 主程序*;**************************************** START: MOV TL1,#0B0H ;初始化定时器T1MOV TH1,#3CHCLR 13H ;分钟、小时闪动标志位初始化CLR 14HSTART1: LCALL set1302 ;调用DS1302初始化之程序NOPSTART2: LCALL DELAY ;调用显示子程序JNB P3.5,KEY ;判断是否有键按下,若有,则调用键盘程序LCALL get1302 ;调用DS1302读时间程序JNB P3.5,KEY ;再次判断是否有键按下,若有,则调用键盘程序AJMP START2;****************************************; 键盘程序*;****************************************KEY: MOV R6,#07H ;MOV 22H,#00H ;标志位置零LCALL DELAY ;显示并延时,判断是否为抖动抖动JNB P3.5 ,KEY1 ;的确有键按下,进入时间调整程序AJMP START2 ;否则跳出调时程序KEY1: LCALL DELAY ;调显示JNB P3.5 ,KEY1 ;等待键释放SETB TR1 ;定时器开始计时,开放中断SETB ET1SETB EACHMIN: LCALL DELAY ;分钟调整入口JNB P3.5,CHHR ;JNB P3.6 ,ADDMIN ;AJMP CHMINADDMIN: LCALL DELAYJB P3.6,CHMIN ;INC CMIN ;SETB 10H ;CLR 11H ;TIAOMIN: PUSH A ;分钟加1调整,并保护现场MOV A,CMINANL A,#0FHCLR CCJNE A,#0AH ,PPAANL CMIN,#0F0HMOV A,CMINADD A,#10HMOV CMIN,ACJNE A,#60H,PPAANL CMIN,#00HPPA: POP A ;恢复现场LCALL DELAY ;显示LCALL DELAYLCALL DELAYLCALL DELAYJB P3.6, CHMIN ;若键释放,则返回到分钟调整入口程序LCALL DELAY ;显示并延时LCALL DELAYLCALL DELAYLCALL DELAYLCALL DELAYJNB P3.6,ADD2 ;若键一直按下,则进入快速调分状态AJMP CHMIN ;否则进入分钟调整入口程序ADD2: PUSH A ;快速调分程序MOV A,CMINADD A,#01HMOV CMIN,APOP AAJMP TIAOMINCHHR: LCALL DELAY ;等待键释放JNB P3.5, CHHRCLR 10HSETB 11HCHHR1: LCALL DELAY ;小时调整程序入口JNB P3.5,OUT ;JNB P3.6 ,ADDHAJMP CHHR1ADDH: LCALL DELAY ;延时去抖动JB P3.6,CHHR1INC CHRTIAOSHI: PUSH A ;小时加1调整程序MOV A,CHRCJNE A,#24H,HH0ANL CHR,#00HAJMP OUT11HH0: ANL A,#0FHCLR CCJNE A,#0AH,OUT11ANL CHR,#0F0HMOV A,CHRADD A,#10HMOV CHR,AOUT11: POP A ;显示并延时LCALL DELAYLCALL DELAYLCALL DELAYLCALL DELAYJB P3.6 ,CHHR1 ;判断键释放,则返回到小时调整入口程序LCALL DELAY ;否则显示并延时LCALL DELAYLCALL DELAYLCALL DELAYLCALL DELAYJNB P3.6 ,ADDH2 ;若键一直按下,则进入快速调时状态AJMP CHHR1 ;否则进入小时调整入口程序ADDH2: PUSH A ;快速调时程序MOV A ,CHRADD A,#01HMOV CHR,APOP AAJMP TIAOSHIOUT: LCALL DELAY ;调时结束,置零标志位,关定时器JNB P3.5,OUTCLR 13HCLR 14HCLR TR1CLR ET1CLR EALJMP START ; 返回set1302: CLR T_RST ;DS1302初始化之程序,将分钟,小时等数据送入到DS1302中CLR T_CLKSETB T_RSTMOV B,#8EH ;控制寄存器LCALL RTInputByteMOV B,#00H ;写操作前WP置零LCALL RTInputByteSETB T_CLKCLR T_RST MOV R0,#SecondMOV R7,#7 ;秒、分、时、日、月、星期、年共7个数据MOV R1,#80H ;秒写地址set13021: CLR T_RSTCLR T_CLKSETB T_RSTMOV B,R1 ;写秒、分、时、日、月、星期、年地址LCALL RTInputByteMOV A,@R0 ;写秒数据MOV B,ALCALL RTinputByteINC R0INC R1INC R1SETB T_CLKCLR T_RSTDJNZ R7,Set13021CLR T_RSTCLR T_CLKSETB T_RSTMOV B,#8EH ;控制寄存器LCALL RTInputByteMOV B,#80H ;控制WP为1,进入写保护状态LCALL RTInputByteSETB T_CLKCLR T_RSTRET;;;;get1302: MOV R0,#Second ;DS1302读时间程序MOV R7,#7MOV R1,#81H ;秒地址get13021: CLR T_RSTCLR T_CLKSETB T_RSTMOV B,R1 ;秒、分、时、日、月、星期、年地址LCALL RTInpuTByteLCALL RT0utputByteMOV @R0,A ;INC R0INC R1INC R1SETB T_CLKCLR T_RSTDJNZ R7,Get13021RET;;;写1302 1 B 子程序RTInputByte: MOV R4,#8Inbit1: MOV A,BRRC AMOV B,AMOV T_IO,CSETB T_CLKCLR T_CLKDJNZ R4,Inbit1RET;;读1302 1B子程序RT0utputByte: MOV R4,#8Outbit1: MOV C,T_IORRC ASETB T_CLKCLR T_CLKDJNZ R4,Outbit1RET;****************************************; 显示程序*;**************************************** DELAY: MOV R5 ,#0FFH ;显示程序DEL: MOV R3,SecondACALL CHAG ;调用字符转换程序,使压缩BCD变为非压缩BCD码MOV P2,#00HMOV P1,R2SETB P2.0 ;秒显示NOPCLR P2.0MOV P1,R3SETB P2.1NOPCLR P2.1MOV R3,CMINACALL CHAGMOV P2,#00HMOV P1,R2CLR P1.7JB 13H , MINOFF ;分钟闪动调时标志SETB P2.2 ;分显示NOPCLR P2.2MOV P1,R3SETB P2.3NOPCLR P2.3AJMP MINOUTMINOFF: CLR P2.2CLR P2.3MINOUT: MOV R3, CHRACALL CHAGMOV P2,#00HMOV P1,R2CLR P1.7JB 14H , HROFF ;小时闪动调时标志SETB P2.4 ;小时显示NOP CLR P2.4MOV P1,R3SETB P2.5NOPAJMP HOUTHROFF: CLR P2.4CLR P2.5HOUT: DJNZ R5 ,DELRETCHAG: PUSH A;字符转换程序,使压缩BCD变为非压缩BCD码MOV P2,#00H ;把转换后BCD码的低字节放到R2中,MOV A,R3 ;高字节放到R3中,数据R3传入ANL A,#00FHMOV R2,AMOV A,R3SWAP AANL A,#00FHMOV R3,AMOV DPTR,#TABMOV A,R2MOVC A,@A+DPTRMOV R2,AMOV A,R3MOVC A,@A+DPTRMOV R3,APOP ARETTAB: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H;****************************************; T1中断服务程序,用于闪动调时程序*;****************************************INTT1: PUSH ACC ;中断现场保护PUSH PSW ;MOV TL1,#0B0H ;装定时器T1定时初值MOV TH1, #3CHDJNZ R6,INTT1OUT ;0.3秒未到退出中断(50MS中断6次)MOV R6,#07H ;重装0.3秒定时用初值SETB 12H ;0.3秒定时到对闪烁标志取反JB 12H,FLASH1 ;02H位为1时显示单元"熄灭"CLR 13HCLR 14HINTT1OUT: POP PSW ;恢复现场POP ACC ;RETI ;中断退出FLASH1: JB 11H,FLASH2 ;01H位为1时,转小时熄灭控制CPL 13HAJMP INTT1OUT ;转中断退出FLASH2: CLR 13HCPL 14HAJMP INTT1OUT ;转中断退出。

相关文档
最新文档