ds1302时钟数码管显示时分秒
单片机原理课程设计课题名称:基于DS1302的数码管显示数字钟专业班级:电子信息工程学生学号:0414070126 学生姓名:张向阳指导教师:张云马崇霄设计时间:2010年6月21日--2010年6月25日目录摘要...................................................................................1 设计任务和要求.....................................................................2 方案论证...........................................................................3 系统硬件设计.......................................................................3.1 系统总原理图 ...............................................................3.2 元器件清单.................................................................................... ..................................................3.3 PCB板图.................................................................................... ...................................................3.4 Proteus仿真图..............................................................3.5 分电路图及原理说明.........................................................3.5.1 主控部分(单片机MCS-51).................................................................... ..........3.5.2 计时部分(实时时钟芯片DS1302)..................................................................3.5.3 显示部分(共阳极数码管)....................................................................... .........3.5.4 调时部分(按键)....................................................................... .........................4 系统软件设计.......................................................................4.1 程序流程图..................................................................4.2 程序源代码...................................................................5 心得体会...........................................................................6 参考文献...........................................................................7 结束语.............................................................................基于DS1302的数码管显示数字钟设计摘要本次课程设计的是使用专门的时钟芯片DS1302在数码管上显示的数字电子钟,并能通过按键对其进行调时和校准。
DS1302是一种高性能、低功耗、带RAM的实时时钟芯片,它能够对时,分,秒进行精确计时,它与单片机的接口使用同步串行通信,仅用3条线与之相连接,就可以实现MCS-51单片机对其进行读写操作,把读出的时间数据送到数码管上显示。
程序运行时,数码管将从当前时间开始显示,通过调节K1键和K2键可以分别对小时和分钟进行调整,调整后,时钟以新的时间为起点继续刷新显示。
关键字:MCS-51单片机、DS1302,数码管,按键,动态扫描,调时,校准;1设计任务和要求1. 应用MCS-51单片机设计单片机实现数字钟(LED显示小时:分:秒)电路;2. 选用八位LED数码显示,实时显示时、分、秒,采用按键式实现时钟对表和快慢调整;3. 硬件设计部分,根据设计的任务选定合适的单片机,根据控制对象设计接口电路。
设计的单元电路必须有工作原理,器件的作用,分析和计算过程;4. 软件设计部分,根据电路工作过程,画出软件流程图,根据流程图编写相应的程序,进行调试并打印程序清单;5.原理图设计部分,根据所确定的设计电路,利用Protel工具软件绘制电路原理图、PCB板图、提供元器件清单。
2方案论证实现数字电子钟的设计有以下两种基本方案,现就两种基本方案的优劣进行具体论证,从而说明选择方案二的理由。
方案一:直接用单片机的内部定时器来实现时间。
该方案以MCS-51单片机为主控芯片,以MCS-51的内部定时器产生的1s中断作为时钟的驱动,然后再通过8个74LS245缓冲器驱动8个独立的数码管来组成数字钟电路。
该电路由于数码管和缓冲器的数目较多,所以在连线方面比较复杂,而且用到的分压电阻也比较多。
但是此方案最大的缺点在于单片机89C51产生的1s 中断存在误差,如果工作时间长的话,数字时钟显示的时间将会出现严重的偏差,不够精确。
方案二:使用串行接口时钟芯片DS1302设计时钟电路。
该设计方案以MCS-51单片机为主控芯片,以串行时钟芯片DS1302为核心计时芯片,然后再通过一个74LS245缓冲器驱动两组数码管组(每个数码管组由四个数码管连在一起组成)组成数字时钟电路。
更重要的是,DS1302时钟芯片的加入大大提高了数字钟时间的准确性,而且该电路在断电后不丢失时间和数据信息时也使得该方案的研究与提升更具有开发的意义。
3 系统硬件设计 3.1系统总原理图EA/VP 31X119X218RESET 9INT012INT113T014T115P101P112P123P134P145P156P167P178P0039P0138P0237P0336P0435P0534P0633P0732P2021P2122P2223P2324P2425P2526P2627P2728RXD10V C C40U1a b f c g de a11b 7c 4d 2e 1f 10g 5d p3dp129a b f c g de dpa b f c g de dpa b f c g de dp86DS1数码管*4a b f c g de a11b 7c 4d 2e 1f 10g 5d p3dp129a b f c g de dpab fc g de dpa b f c g de dp86DS2数码管*4Y1CR YSTALC222PF C122PF 121312&U2A 74S15G 19DIR 1A12B118A23B217A34B316A45B415A56B514A67B613A78B712A89B811U374LS245+5VA B C D E F G HAB C D E F GHA B C E F G H D 1234567812345678K1K2K3X12X23VC C11GND 4RST 5IO 6SCLK 7VC C28U4DS1302(8)Y2CR YSTAL +5V C4104+5V+5V 123456789RP1RES-8图1 数字钟总原理图3.2 元件清单元件序号型号或主要参数数量封装元件序号型号或主要参数数量封装R1100Ω 1 AXIAL0.3 U1AT89C51 1 DIP40 R21kΩ 1 AXIAL0.3 U274S15 1 DIP14 RP1 1KΩ 1 SIP9 U4DS1302 1 DIP8 C1 22pF 3 RAD2.54 U374LS245 1 DIP20 C4 104uF 1 RAD2.54 Y1 CRYSTAL 1 STAL3 DS SM41C564 2 数码管*4 Y2 CRYSTAL 1 STAL2K 按键 4 按键4.5*6.53.3PCB板图图2 总电路PCD板图3.4Proteus仿真图图3 proteus仿真图3.5分电路图及原理说明本次设计的硬件电路由主控部分(单片机MCS-51)、计时部分(实时时钟芯片DS1302)、显示部分(数码管)、调时部分(按键)4个部分组成。
各部分之间相互协作,构成一个统一的有机整体,实现数字时钟的计时功能。
现就各部分的硬件电路设计作出如下论述:3.5.1 主控部分(单片机MCS-51)MCS-51单片机作为主控芯片,控制整个电路的运行。
其外围电路主要有两部分:复位电路和晶体振荡器。
复位电路的功能是:系统上电时提供复位信号,直至系统电源稳定后,撤消复位信号。
为可靠起见,电源稳定后还要经一定的延时才撤销复位信号,以防电源开关或电源插头分-合过程中引起的抖动而影响复位。
该设计采用含有二极管的复位电路,复位电路可以有效的解决电源毛刺和电源缓慢下降(电池电压不足)等引起的问题,在电源电压瞬间下降时可以使电容迅速放电,一定宽度的电源毛刺也可令系统可靠复位。
晶体振荡电路:MCS-51单片机中有一个用于构成内部振荡器的高增益反相放大器,引脚XTAL1和XTAL2分别为该反向放大器的输入端和输出端。
这个反向放大器与作为反馈元件的片外石英晶体或陶瓷谐振器一起构成自激振荡器。
外接石英晶体(或陶瓷谐振器)及电容C1、C2接在放大器的反馈回路中构成并联振荡电路。
对外接电容C1、C2虽然没有十分严格的要求,但电容容量的大小会轻微影响振荡频率的高低、振荡器工作的稳定性、起振的难易程度及温度稳定性。
基于DS1302的电子时钟设计
基于DS1302的电子时钟设计2012~ 2013 学年第二学期《单片机》课程设计报告题目:基于DS1302的电子时钟设计专业:电气工程系自动化班级: 10自动化(2)班姓名:费孝斌洪建勇刘云飞桑乐陆欢欢魏笑指导教师:林开司电气工程系2013年5月12日任务书摘要电子时钟主要是利用电子技术将时钟电子化、数字化,拥有时钟精确、体积小、界面友好、可扩展性能强等特点,被广泛应用于生活和工作当中。
另外,在生活和工农业生产中,也常常需要温度,这就需要电子时钟具有多功能性。
本设计主要为实现一款可正常显示时钟/日历、带有定时闹铃的多功能电子时钟。
本文对当前电子钟开发手段进行了比较和分析,最终确定了采用单片机技术实现多功能电子时钟。
本设计应用AT89C52芯片作为核心,6位LED数码管显示,使用DS1302实时时钟日历芯片完成时钟/日历的基本功能。
这种实现方法的优点是电路简单,性能可靠,实时性好,时间精确,操作简单,编程容易。
该电子时钟可以应用于一般的生活和工作中,也可通过改装,提高性能,增加新功能,从而给人们的生活和工作带来更多的方便。
关键词:电子时钟;多功能;AT89C52;时钟日历芯片目录摘要一、引言 (4)二、基于单片机的电子时钟硬件选择分析 (5)2.1主要IC芯片选择 (5)2.1.1微处理器选择 (5)2.1.2 DS1302简介 (6)2.1.3 DS1302引脚说明 (7)2.2电子时钟硬件电路设计 (8)2.2.1时钟电路设计 (9)2.2.2整点报时功能 (10)三、protel软件画原理图 (11)3.1系统工作流程图 (12)3.2原理图 (13)四、proteus软件仿真及调试 (14)4.1电路板的仿真 (15)4.2软件调试 (16)五、源程序 (17)六、参考文献 (18)引言时间是人类生活必不可少的重要元素,如果没有时间的概念,社会将不会有所发展和进步。
从古代的水漏、十二天干地支,到后来的机械钟表以及当今的石英钟,都充分显现出了时间的重要,同时也代表着科技的进步。
DS1302时钟 秒表
;******************************************************************; 1 2 3 A ;修改时间时,A键为当前修改时间加一,B键为减一,C不保存退出,D保存并退出; 4 5 6 B INT0 ;INT0键,进入和退出秒表; 7 8 9 C INT1 ;显示时间时,INT1键,进入修改时间程序;秒表时,INT1键为计数清零; E 0 F D T0 ;显示时间时,T0键为切换日历和时钟,秒表时,T0为开始结束计时;*******************************************************************;修改时间时E键左移F键右移;******************************************************************* LED EQU P0 ;显示接口KEY EQU P1 ;键盘接口DUAN EQU P2 ;LED段控制ZCLK BIT P1.6 ;时钟线引脚ZIO BIT P3.5 ;数据线引脚ZRST BIT P1.7 ;复位线引脚ZINT0 BIT P3.2 ;外部中断0引脚ZINT1 BIT P3.3 ;外部中断1引脚ZT0 BIT P3.4 ;T0引脚ZT1 BIT P3.5 ;T1引脚XSW EQU 7FH ;显示首地址SECOND EQU 30H ;秒地址XGDDZ EQU 7EH ;修改段地址XGSJDZ EQU 7DH ;修改时间地址SMBZ EQU 70H ;键盘扫描标志位XGWBZ EQU 71H ;修改位标志MBBZ EQU 72H ;秒表标志SS EQU 70H ;闪烁缓存地址T0JC EQU 74H ;T0计数次数XSW1 EQU 75H ;显示辅助;********************************ORG 00H ;程序入口LJMP STARTORG 03H ;外部中断0程序入口LJMP AINT0ORG 0BH ;定时器T0程序入口LJMP AT0ORG 13H ;外部中断1程序入口LJMP AINT1ORG 1BH ;定时器T1程序入口LJMP AT1;********************************ORG 30HSTART:CLR SMBZ ;清扫描标志,为0表示当前不进行键盘扫描,为1表示扫描。
单片机时钟芯片DS1302在LCD1602上显示年月日时分秒
单片机设计实验内容摘要:单片机实验是通过Proteus仿真并且与Keil相结合使用控制单片机使其在仿真中完成一系列所设计的程序。
我们这个小组所做的实验是仿真一个数字时钟,通过DS1302这个芯片从计算机上读取时间信息,再由51单片机对数据进行处理、分配,将其输出在LCD1602上,实现简单的数字时钟的功能。
设计内容及要求:(1)根据设计课题的技术指标和给定条件,在教师指导下,能够独立而正确地进行方案论证和设计计算,要求概念清楚、方案合理、方法正确、步骤完整;(2)要求学生掌握单片机的设计内容、方法和步骤;(3)要求会查阅有关参考资料和手册等;(4)要求学会选择有关元件和参数;(5)要求学会绘制有关电路图和设计流程图;(6)要求学会编写设计说明书。
系统框图:硬件选择:1、AT89C51AT89C51是一种带4K字节FLASH存储器(FPEROM—Flash Programmable and Erasable Read Only Memory)的低电压、高性能CMOS 8位微处理器,俗称单片机。
AT89C2051是一种带2K字节闪存可编程可擦除只读存储器的单片机。
单片机的可擦除只读存储器可以反复擦除1000次。
该器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。
由于将多功能8位CPU和闪烁存储器组合在单个芯片中,ATMEL的AT89C51是一种高效微控制器,AT89C2051是它的一种精简版本。
AT89C51单片机为很多嵌入式控制系统提供了一种灵活性高且价廉的方案。
AT89C51外形及引脚排列主要特性:·与MCS-51 兼容·4K字节可编程FLASH存储器·寿命:1000写/擦循环·数据保留时间:10年·全静态工作:0Hz-24MHz·三级程序存储器锁定·128×8位内部RAM·32可编程I/O线·两个16位定时器/计数器·5个中断源·可编程串行通道·低功耗的闲置和掉电模式·片内振荡器和时钟电路特性概述:AT89C51 提供以下标准功能:4k 字节Flash 闪速存储器,128字节内部RAM,32 个I/O 口线,两个16位定时/计数器,一个5向量两级中断结构,一个全双工串行通信口,片内振荡器及时钟电路。
ds1302实时时钟程序说明
DS1302实时时钟在数码管上进行实时显示的程序
#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit rst=P2^4;
sbit io=P2^0;
}
write_ds1302(0x8e,0x80); //进行写保护
}
void read_rtc()
{
uchar i;
for(i=0;i<7;i++)
{
time_data[i]=read_ds1302(read_add[i]);
}
}
void time_pros()
{
disp[0]=time_data[6]%16;//将BCD码(这里与十六进制没有区别)进行十位个位的分离
{
j=time_data[i]/10;//十位5
time_data[i]%=10;//各位8
time_data[i]=time_data[i]+j*16;
}
write_ds1302(0x8e,0x00);//去除写保护
for(i=0;i<7;i++)
{
write_ds1302(write_add[i],time_data[i]);
disp[1]=time_data[6]/16;
disp[2]=17;
disp[3]=time_data[5]%16;
disp[4]=time_data[5]/16;
disp[5]=17;
课程设计——DS1302数码管显示数字钟的设计1
××大学××学院××系课程设计报告××大学××学院××系××课程设计DS1302数码管显示数字钟的设计学生姓名学号所在系专业名称班级指导教师成绩××大学××学院二〇一二年六月摘要:本课程设计要求基于STC89C52单片机实现用8位数码管进行时钟显示。
采用STC89C52单片机和DS1302实时时钟芯片,使用5V电源供电。
时钟可以通过按键切换,数码管显示时、分、秒以及年、月、日,并且可以实现时钟的校准功能。
包括时钟芯片驱动程序,数码管显示及驱动程序。
关键字:单片机,DS1302,时钟电路,数码管显示Abstract: This course is designed 8 digital tube clock display requirements based STC89C52 microcontroller. Using STC89C52 microcontroller and DS1302 real time clock chip, using a 5V power supply. Design of the clock by means of the key switches, digital tube display hours, minutes, seconds, and the year, month, day, and can achieve clock calibration function. Including the driver of the clock chip, digital display and driver.Key words: single chip macrocomputer;DS1302;clock circuit;digital tube display目录1. 总体设计方案 (1)1.1 电子钟功能介绍1.1.1 基本功能介绍 (1)1.1.2 扩展功能介绍 (1)1.2 总体设计方案 (1)1.2.1 计时方案 (1)1.2.2 按键方案 (1)1.2.3 显示方案 (2)2. 单元模块设计 (2)2.1 硬件总电路设计 (2)2.2 显示模块电路设计 (2)2.3 按键调时电路设计 (3)2.4 时钟芯片通信电路 (3)3. 软件模块设计 (4)3.1 主程序设计 (4)3.2 时钟芯片 (5)3.2.1 DS1302内部结构 (5)3.2.2 DS1302的读时序 (6)3.2.3 DS1302的写时序 (6)3.3 键盘调时 (7)4. 设计总结 (8)5. 参考文献 (8)6. 附录 (9)前言数字钟是采用数字电路实现对时、分、秒及数字显示的计时装置,广泛用于个人家庭、车站、办公室等公共场所,成为人们日常生活中的必需品。
ds1302实时时钟程序
/* 时间:4月19日功能:使用ds1302实时时钟芯片,用共阴数码管显示时,分,秒*/#include<reg51.h>#include<intrins.h>#define uint unsigned int#define uchar unsigned charsbit io=P3^4;sbit cs=P3^5;sbit clk=P3^6;uchar code table1[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x80};uchar code table2[]={ //译码器与单片机的接线引脚P2.4 P2.3 P2.20xe3,0xe7,0xeb,0xef,0xf3,0xf7,0xfb,0xff};uchar time[7]={14,2,3,25,23,59,50}; //初始化实时时钟时间uchar register_wr[7]={0x8c,0x8a,0x88,0x86,0x84,0x82,0x80};uchar register_re[7]={0x8d,0x8b,0x89,0x87,0x85,0x83,0x81}; uchar temp1[7];uchar shi,ge;void delay_ms(uchar t);void delay(); //大约10usvoid spi_writebyte(uchar dat);uchar spi_readbyte();void ds1302_spiwrite(uchar add,uchar dat);uchar ds1302_spiread(uchar add);void ds1302_init();void ds1302_run(); //ds1302全运行过程void display(); //共阴数码管显示过程void main(){ds1302_init();while(1){ds1302_run();display();}}void delay_ms(uchar t){uchar x,y;for(x=t;x>0;x--)for(y=110;y>0;y--);}void ds1302_run(){ //ds1302全运行过程uchar i;for(i=0;i<7;i++){ds1302_spiwrite(0x8e,0x80);//写保护,不让写temp1[i]=ds1302_spiread(register_re[i]); //将十六进制数转换成相同数字的十进制shi=temp1[i]/16;ge=temp1[i]%16;time[i]=shi*10+ge;}}void display(){P0=table1[time[4]/10]; P2=table2[0];delay_ms(1);P0=table1[time[4]%10]; P2=table2[1];delay_ms(1);P0=table1[16];P2=table2[2];delay_ms(1);P0=table1[time[5]/10]; P2=table2[3];delay_ms(1);P0=table1[time[5]%10]; P2=table2[4];delay_ms(1);P0=table1[16];P2=table2[5];delay_ms(1);P0=table1[time[6]/10];P2=table2[6];delay_ms(1);P0=table1[time[6]%10];P2=table2[7];delay_ms(1);}void ds1302_init(){uchar i;ds1302_spiwrite(0x8e,0x00); //wp是写允许位。
DS1302显示时钟程序
#include<reg52.h>#include<intrins.h>#define uint unsigned int#define uchar unsigned charsbit k1=P1^0; //开关的位置sbit k2=P1^1;sbit k3=P1^2;sbit k4=P1^3;sbit clk=P3^6; //时钟线sbit en=P3^5; //使能端sbit io=P3^4; //DS1302的IO口sbit lcden=P2^7; //液晶使能端sbit lcdrd=P2^6; //数据命令端sbit lcdwr=P2^5; //读写选择端sbit beep=P2^4; //蜂鸣器位置bit flag; //按键标志位uchar code t[]="LCD LOCK"; //第一行显示字符uchar code b[]="****"; //第二行显示字符uchar c[8] ={0x00}; //定义显示缓冲区uchar d[7] ={0,0,0x12,0,0,0,0}; //DS1302时间缓冲区,存放秒、分、时、日、月、uchar e[2]={0}; //用来存放分钟小时的中间值void delay(uint x) //延时函数{ uint i,j;for(i=0;i<x;i++)for(j=0;j<115;j++); //延时X*MS}void write_com(uchar com) //命令函数{ lcdrd=0; //选择命令端P0=com; //要写的命令送到P0口delay(5);lcden=1; //开启使能端delay(5);lcden=0; //关闭使能端}void write_data(uchar dat) //数据函数{ lcdrd=1; //数据选择端P0=dat;delay(5);lcden=1; //开使能delay(5);lcden=0;}bit busy() //忙碌检查函数{ bit result;lcdrd=0;lcdwr=1;lcden=1;_nop_(); //延时几微秒_nop_();_nop_();_nop_();result=(bit)(P0&0x80);lcden=0;return result;}void lcdclr() //LCD清屏函数{ write_com(0x01); //清零显示,数据指针清零delay(5);}void init() //初始化函数{ delay(15);write_com(0x38); //16*2显示,5*7点阵,8位数据delay(15);write_com(0x38);write_com(0x06); //写一个字符地址指针加1 delay(5);write_com(0x0c); //设置显示,不显示光标delay(5);write_com(0x01); //显示清零,数据指针清零}void write_byte(uchar date) //写一个字节函数{ uchar i;for(i=0;i<8;i++){ clk=0; //低电平改变数据if(date&0x01)io=1;elseio=0;clk=1; //高电平写入1302_nop_();date=date>>1;}}uchar read_byte() //读一个字节函数{uchar i,temp=0;io=1;for(i=0;i<7;i++){clk=0;if(io==1)temp=temp|0x80;elsetemp=temp&0x7f;clk=1; //产生下跳沿temp=temp>>1;}return temp;}void write1302(uchar com,uchar dat) //写1302函数在某个地址写数据{ clk=0;en=1;write_byte(com);write_byte(dat);clk=0;en=0;}uchar read1302(uchar add) //读1302函数,从地址读数据{ uchar d;clk=0;en=1;write_byte(add); //先写地址d=read_byte(); //后读数据clk=0;en=0;return d;}void set1302(uchar add,uchar *p,uchar n) //时间初始化{ write1302(0x80,0x00); //写控制,允许写操作for(;n>0;n--){ write1302(add,*p);p++;add=add+2;}write1302(0x8e,0x80); //写保护,不允许写操作}void get1302(uchar add,uchar *p,uchar n) //读取当前数据{ for(;n>0;n--){ *p=read1302(add);p++;add=add+2;}}void init1302() //初始化1302函数{ en=0;clk=0;write1302(0x80,0x00); //写秒寄存器write1302(0x90,0xab); //写充电器write1302(0x8e,0x80); //写保护,禁止写}void BEEP() //蜂鸣器函数{ beep=0; //响蜂鸣器delay(100); //响0.1sbeep=1;delay(100);}void lcdcon(uchar m1,m2,m3) //将数据转化成适合LCD显示的数据{ c[0]=m1/10+0x30; //小时十位数据c[1]=m1%10+0x30; //小时个位数据c[2]=m2/10+0x30; //分钟十位数据c[3]=m2%10+0x30; //分钟个位数据c[4]=m3/10+0x30; //秒十位c[5]=m3%10+0x30; //秒个位}void lcddis() //LCD显示函数{ write_com(0x44|0x80); //第二行第四列write_data(c[0]); //小时十位write_data(c[1]); //小时个位write_data(':'); //显示:write_data(c[2]); //显示分钟十位write_data(c[3]); //显示分钟个位write_data(':');write_data(c[4]); //显示秒十位write_data(c[5]); //显示秒个位}void keyscan() //按键函数{ uchar fen,shi; //定义两个16位分钟和小时write1302(0x8e,0x00); //1302写保护,允许写write1302(0x80,0x80); //时钟停止运行if(k2==0) //按键2被按下{ d elay(10); //去抖动if(k2==0) //确认被按下{ while(!k2); //等待按键释放BEEP(); //蜂鸣器函数d[2]=d[2]+1; //小时加1if(d[2]==24) //满24清零d[2]=0;shi=d[2]/10*16+d[2]%10; //将小时转化成16进制write1302(0x84,shi); //调整后写入1302}}if(k3==0) //按键3被按下{ delay(10); //抖动if(k3==0) //确认被按下{ while(!k3); //等待按键放开BEEP(); //蜂鸣器函数d[1]=d[1]+1; //分钟加1if(d[1]==60) //满60清零d[1]=0;fen=d[1]/10*16+d[1]%10; //将分钟转化为16进制write1302(0x82,fen); //调整后,写入1302}}if(k4==0) //按键4被按下{ d elay(10); //去抖动if(k4==0) //确认被按下{ while(!k4); //等待按键释放BEEP(); //蜂鸣器函数write1302(0x80,0x00); //调整后,启动时钟运行write1302(0x8e,0x80); //写保护,禁止写flag=0; //按键1标志位清零}}}void gettime() //读取当前时间,转化为10进制{ uchar miao,fen,shi;write1302(0x8e,0x00); //控制命令,0表示允许写write1302(0x90,0xab); //电流控制miao=read1302(0x81); //读取秒fen=read1302(0x83); //读取分shi=read1302(0x85); //读取小时d[0]=miao/16*10+miao%16; //转化为10进制d[1]=fen/16*10+fen%16; //转化为10进制d[2]=shi/16*10+shi%16; //转换为10进制}void main() //主函数{ uchar i;P0=0xff;P2=0xff;init1302(); //1302初始化函数lcdclr(); //1302清屏函数write_com(0x00|0x80); //第一行第0列i=0;while(t[i]!=0){ write_data(t[i]); //第一个字符显示i++;}write_com(0x40|0x80); //第二行显示第0列i=0;while(b[i]!=0);{ write_data(b[i]);i++;}init1302();while(1){ gettime();if(k1==0) //按键1按下{ delay(10); //去抖动if(k1==0) //确认按下{ while(!k1); //等待按键释放BEEP(); //蜂鸣器函数flag=1; //按键1标志位置位,进行时钟调整}}if(flag==1) //如为1,则进行调整keyscan();lcdcon(d[2],d[1],d[0]); //将1302的数据送到函数转换lcddis(); //调整LCD显示,显示小时,分钟,秒}}。
利用单片机及DS1302制作电子时钟
单片机原理及应用——基于Proteus仿真设计报告课程名:利用单片机及DS1302制作电子时钟专业:班级:学号:姓名:设计时间:一、简介这是一种“基于单片机和DS1302的电子时钟”(简称“电子时钟”)。
单片机为控制核心,DS1302为应用广泛且走时准确的时钟芯片。
二、功能与操作1.功能(1)时钟功能:动态显示时、分、秒。
(2)调时功能:可依据标准时钟调校时间。
(3)因DS1302接有辅助纽扣电池,即使电源断电也能准确计时数年。
2.操作(1)上电后时钟开始计时并显示。
(2)调时。
按下“调时”按键,则进入调校时间状态,可依次调校时、分、秒。
三、技术要点1.时钟芯片DS1302的应用(1)DS1302的简介DS1302 是美国DALLAS公司推出的一种高性能、低功耗、带RAM 的实时时钟电路,它可以对年、月、日、周日、时、分、秒进行计时,具有闰年补偿功能,工作电压为2.5V~5.5V。
采用三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号或RAM数据。
DS1302内部有一个31×8的用于临时性存放数据的RAM寄存器。
DS1302是DS1202的升级产品,与DS1202兼容,但增加了主电源/后备电源双电源引脚,同时提供了对后备电源进行涓细电流充电的能力。
(2)DS1302的电路图2.应用中的几个小问题(1)子程序必须满足三线通信的时序要求。
单片机晶振频率不同,相应的子程序中的延时也要调整。
否则,运行结果可能出现错误。
(2)注意LED数码管动态扫描显示程序的设计及单片机晶振频率的选择。
否则,会因LED数码管数量多而导致显示闪烁或不正确。
所以在程序设计中,应使动态扫描频率大于视觉暂留频率,要考虑避免出现串显现象。
四、元件清单五、原理图六、程序SCLK EQU P3.2IO EQU P3.3RST EQU P3.4JIA1 EQU P3.6 ;"加一"口TSH EQU P3.7 ;"调时间"口HOUR DATA 62HMINTUE DATA 61HSECOND DATA 60HDS1302_ADDR DATA 32HDS1302_DATA DATA 31HORG 0HMOV SP,#70HLCALL DELY1MOV DS1302_ADDR,#8EH ;允许写1302MOV DS1302_DATA,#00HLCALL WRITEMOV DS1302_ADDR,#81H ;从1302读秒LCALL READANL A,#7FH ;启动1302振荡器MOV DS1302_ADDR,#80HMOV DS1302_DATA,ALCALL WRITEMOV 20H,#0 ;调整时标识单元MOV 21H,#0FH ;调整时工作单元MAIN1: JB TSH,MAIN2F ;按调时键往下执行MOV DS1302_ADDR,#81H ;从1302读秒LCALL READORL A,#80H ;停1302振荡器MOV DS1302_ADDR,#81HMOV DS1302_DATA,ALCALL WRITESSS: LCALL DISP ;显示JNB TSH,SSS ;等待调键盘弹起MOV 20H,#8 ;设置调"时"标志SSS3: JNB TSH,FFF ;按调时键转调"分"LCALL DISP ;显示JB JIA1,SSS3 ;按"加一"键往下执行SSS2: LCALL DISP ;显示JNB JIA1,SSS2 ;等待"加一"键弹起MOV R7,HOURMOV HOUR,ACJNE A,#24H,SSS1 ;不等于24时转MOV HOUR,#0 ;等于24时归零SSS1: MOV DS1302_ADDR,#84H ;将"时"写入1302 MOV DS1302_DATA,HOURLCALL WRITEMOV R0,HOUR ;"时"分离LCALL DIVIDEMOV 44H,R1MOV 45H,R2SJMP SSSMAIN2F: LJMP MAIN2FFF: NOP ;调"分"LCALL DISP ;显示JNB TSH,FFF ;等待调时键弹起MOV 20H,#4 ;置调"分"标志FFF3: JNB TSH,MMM ;安调时键转调"秒"LCALL DISP ;显示JB JIA1,FFF3 ;若按"加一"键往下执行FFF2: LCALL DISP ;显示JNB JIA1,FFF2 ;等待"加一"键弹起MOV R7,MINTUELCALL JIAYI ;"分"加一MOV MINTUE,ACJNE A,#60H,FFF1 ;不等于60转MOV MINTUE,#0 ;等于60则归零FFF1: MOV DS1302_ADDR,#82H ;将"分"写入1302 MOV DS1302_DATA,MINTUELCALL WRITEMOV R0,MINTUELCALL DIVIDE ;"分"分离MOV 42H,R1MOV 43H,R2SJMP FFF3MMM: LCALL DISP ;显示JNB TSH,MMM ;若按调时键则转调"秒"MOV 20H,#2 ;置调"秒"标志MMM3: JNB TSH,MAIN3 ;按调时键退出调时LCALL DISP ;显示JB JIA1,MMM3 ;按"加一"键往下执行MMM2: LCALL DISP ;显示JNB JIA1,MMM2 ;等待"加一"键弹起MOV R7,SECONDMOV SECOND,ACJNE A,#60H,MMM1 ;不等于60转MOV SECOND,#0MMM1: ORL SECOND,#80HMOV DS1302_ADDR,#80H ;写"秒"MOV DS1302_DATA,SECONDLCALL WRITEANL SECOND,#7FHMOV R0,SECONDLCALL DIVIDE ;"秒"分离MOV 40H,R1MOV 41H,R2SJMP MMM3MAIN3: LCALL DISP ;显示JNB TSH,MAIN3 ;等待调时键弹起MOV 20H,#0MOV 21H,#0FHMOV DS1302_ADDR,#81H ;读"秒"LCALL READANL A,#7FH ;启动1302振荡器MOV DS1302_ADDR,#80HMOV DS1302_DATA,ALCALL WRITELJMP MAIN1MAIN2: MOV P1,#0 ;读时分秒并显示MOV DS1302_ADDR,#85H ;读"时"LCALL READMOV HOUR,DS1302_DATAMOV DS1302_ADDR,#83H ;读"分"LCALL READMOV MINTUE,DS1302_DATAMOV DS1302_ADDR,#81H ;读"秒"LCALL READMOV SECOND,DS1302_DATAMOV R0,HOUR ;"时"分离LCALL DIVIDEMOV 44H,R1MOV 45H,R2MOV R0,MINTUE ;"分"分离LCALL DIVIDEMOV 42H,R1MOV 43H,R2MOV R0,SECOND ;"秒"分离LCALL DIVIDEMOV 40H,R1MOV 41H,R2LCALL DISPLJMP MAIN1DISP: NOPMOV P1,40H ;显示"秒"低位JNB 01H,MIAOLMOV A,21HRL AMOV 21H,ACJNE A,#78H,MIAO1MIAO1: JC MIAOLCLR P2.4CLR P2.5SJMP FENMIAOL: SETB P2.5LCALL DELY1CLR P2.5LCALL DELY2MOV P1,41H ;显示"秒"高位SETB P2.4LCALL DELY1CLR P2.4LCALL DELY2FEN: MOV P1,42H ;显示"分"低位JNB 02H,FENLMOV A,21HRL AMOV 21H,ACJNE A,#78H,FEN1FEN1: JC FENLCLR P2.2CLR P2.3SJMP SHIFENL: SETB P2.3LCALL DELY1CLR P2.3LCALL DELY2MOV P1,43H ;显示"分"高位SETB P2.2LCALL DELY1CLR P2.2LCALL DELY2SHI: MOV P1,44H ;显示"时"地位JNB 03H,SHILMOV A,21HRL AMOV 21H,ACJNE A,#78H,SHI1SHI1: JC SHILSJMP SHI2SHIL: SETB P2.1LCALL DELY1CLR P2.1LCALL DELY2MOV P1,45H ;显示"时"高位SETB P2.0LCALL DELY1CLR P2.0LCALL DELY2SJMP SFMSHI2: CLR P2.0CLR P2.1SFM: RETDELY1: MOV R7,#5 ;晶振12MHz,延时2.58ms DELY11: MOV R6,#0DJNZ R6,$DJNZ R7,DELY11RETDELY2: MOV R7,#1 ;晶振12MHz,延时0.52ms DELY21: MOV R6,#0DJNZ R6,$DJNZ R7,DELY21RETDELY3: MOV R7,#40 ;晶振12MHz,延时8x2.58ms DELY31: MOV R6,#0DJNZ R6,$DJNZ R7,DELY31RETJIAYI: MOV A,R7ADD A,#1DA ARETDIVIDE: MOV A,R0 ;分离子程序ANL A,#0FHMOV R1,AMOV A,R0SWAP AANL A,#0FHMOV R2,ARET;以下为DS1302在单片机晶振频率为4MHz时的串行通信子程序WRITE: CLR SCLK ;1302写子程序SETB RSTMOV A,DS1302_ADDRMOV R4,#8WRITE1: RRC ACLR SCLKMOV IO,CSETB SCLKDJNZ R4,WRITE1CLR SCLKMOV A,DS1302_DATAMOV R4,#8WRITE2: RRC ACLR SCLKMOV IO,CSETB SCLKDJNZ R4,WRITE2CLR RSTRETREAD: CLR SCLK ;1302读子程序SETB RSTMOV A,DS1302_ADDRMOV R4,#8READ1: RRC ANOPMOV IO,CSETB SCLKCLR SCLKDJNZ R4,READ1MOV R4,#8READ2: CLR SCLKMOV C,IORRC ASETB SCLKDJNZ R4,READ2MOV DS1302_DATA,ACLR RSTRETEND七、总结通过这次设计与仿真,让我对PROTEUS仿真有了一定的了解,其中也碰见了许多不会用的,后来经过网上查阅懂得了怎么使用,如,画总线工具在什么地方,怎么使用这个东西来画总线,怎么画网络标号。
基于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时钟显示代码可以显示年月日时分秒和星期#include#include#include#define uchar unsigned char#define uint unsigned intsbit SDA=P3^7; // DS1302数据线sbit CLK=P3^6; //DS1302时钟线sbit RST=P3^5; //DS1302复位线sbit RS=P2^0;sbit RW=P2^1;sbit EN=P2^2;sbit K1=P3^1; // 选择sbit K2=P3^2; // 加sbit K3=P3^3; // 减sbit K4=P3^4; // 确定//void Display_LCD_String(uchar p,uchar *s);uchar tCount=0;//一年中每个月的天数,2月的天数由年份决定uchar MonthsDays[]={0,31,0,31,30,31,30,31,31,30,31,30,31};uchar*WEEK[]={"SUN","MON","TUS","WEN","THU","FRI","SAT"};//周日,周一到周六uchar LCD_DSY_BUFFER1[]={"Date 00-00-00 "}; //LCD显示缓冲uchar LCD_DSY_BUFFER2[]={" 00:00:00 "};uchar DateTime[7]; //所读取的日期时间char Adjust_Index=-1; //当前调节的时间:秒,分,时,日,uchar Change_Flag[]="-MHDM-Y";//uchar Read_LCD_State();//void LCD_Busy_Wait();//void Write_LCD_Data(uchar dat);//void Write_LCD_Command(uchar cmd); //void Init_LCD();//void Set_LCD_POS(uchar p);void DelayMS(uint x){uchar i;while(x--) for(i=0;i<120;i++);}uchar Read_LCD_State() //忙检查{uchar state;RS=0;RW=1;EN=1;DelayMS(1);state=P0;EN=0;DelayMS(1);return state;}void LCD_Busy_Wait() //等待{while((Read_LCD_State()&0x08)==0x80); DelayMS(5);}void Write_LCD_Data(uchar dat) //写数据{LCD_Busy_Wait();RS=1;RW=0;//EN=0;P0=dat;EN=1;DelayMS(1);EN=0;}void Write_LCD_Command(uchar cmd)//写命令{LCD_Busy_Wait();RS=0;RW=0;//EN=0;P0=cmd;EN=1;DelayMS(1);EN=0;}void Init_LCD() //LCD初始化{Write_LCD_Command(0x38); DelayMS(1);Write_LCD_Command(0x01); DelayMS(1);Write_LCD_Command(0x06); DelayMS(1);Write_LCD_Command(0x0C); DelayMS(1); // Display_LCD_String(0x00,"zzuli");// DelayMS(1000);// Display_LCD_String(0x40,"LCD CLOCK");// DelayMS(2000);}void Set_LCD_POS(uchar p) //写命令,设定{Write_LCD_Command(p|0x80);}void Display_LCD_String(uchar p,uchar *s) //显示{uchar i;Set_LCD_POS(p);for(i=0;i<16;i++){Write_LCD_Data(s[i]);DelayMS(1);}}void DS1302_Write_Byte(uchar x) //向DS1302写入一字节{ uchar i;for(i=0;i<8;i++){SDA=x&1;CLK=1;CLK=0;x>>=1;}}uchar DS1302_Read_Byte() //从DS1302读取一字节{uchar i,b,t;for(i=0;i<8;i++){b>>=1;t=SDA;b|=t<<7;CLK=1;CLK=0;}return b/16*10+b%16;}uchar Read_Data(uchar addr) //从DS1302指定位置数据{uchar dat;RST=0;CLK=0;RST=1;DS1302_Write_Byte(addr);dat=DS1302_Read_Byte();CLK=1;RST=0;return dat;}void Write_DS1302(uchar addr,uchar dat) //向DS1302某地址写入数据{CLK=0;RST=1;DS1302_Write_Byte(addr);DS1302_Write_Byte(dat);CLK=0;RST=0;}void SET_DS1302() //设置时间{uchar i;Write_DS1302(0x8e,0x00);for(i=0;i<7;i++){Write_DS1302(0x80+2*i,(DateTime[i]/10<<4|(DateTime[i]%1 0))); }Write_DS1302(0x8e,0x80);}void GetTime() //读取当前时期时间{uchar i;for(i=0;i<7;i++){DateTime[i]=Read_Data(0x81+2*i);}}void Format_DateTime(uchar d,uchar *a) //时间和日期转换成数字字符{a[0]=d/10+'0';a[1]=d%10+'0';}uchar isLeapYear(uint y) //判断是否为闰年{return (y%4==0&&y%100!=0)||(y%400==0);}void RefreshWeekDay() //星期转换{uint i,d,w=5;for(i=2000;i<2000+DateTime[6];i++){d=isLeapYear(i) ? 366 : 365;w=(w+d)%7;}d=0;for(i=1;id+=DateTime[3];DateTime[5]=(w+d)%7+1;}void DateTime_Adjust(char x) //年月日时分秒++/-- {switch (Adjust_Index){case 6: //年if(x== 1&&DateTime[5]<99) DateTime[6]++;if(x==-1&&DateTime[6]>0) DateTime[6]--; MonthsDays[2]=isLeapYear(2000+DateTime[6])? 29:28; if(DateTime[3]>MonthsDays[DateTime[4]]) DateTime[3]=MonthsDays[DateTime[4]]; RefreshWeekDay();break;case 4: //月if(x== 1&&DateTime[4]<12) DateTime[4]++;if(x==-1&&DateTime[4]>1) DateTime[4]--; MonthsDays[2]=isLeapYear(2000+DateTime[6])? 29:28; if(DateTime[3]>MonthsDays[DateTime[4]]) DateTime[3]=MonthsDays[DateTime[4]]; RefreshWeekDay();break;case 3: //日MonthsDays[2]=isLeapYear(2000+DateTime[6])? 29:28; if(x== 1&&DateTime[3]<="" p="">if(x==-1&&DateTime[3]>0) DateTime[3]--;RefreshWeekDay();break;case 2: //时if(x== 1&&DateTime[2]<23) DateTime[2]++;if(x==-1&&DateTime[2]>0) DateTime[2]--;break;case 1: //秒if(x== 1&&DateTime[1]<59) DateTime[1]++;if(x==-1&&DateTime[1]>0) DateTime[1]--;break;}}void T0_INT() interrupt 1 //定时器每秒刷新LCD显示{TH0=-50000/256;TL0=-50000%256;if(++tCount!=2) return;tCount=0;Format_DateTime(DateTime[6],LCD_DSY_BUFFER1+5); Format_DateTime(DateTime[4],LCD_DSY_BUFFER1+8); Format_DateTime(DateTime[3],LCD_DSY_BUFFER1+11); strcpy(LCD_DSY_BUFFER1+13,WEEK[DateTime[5]-1]); Format_DateTime(DateTime[2],LCD_DSY_BUFFER2+5); Format_DateTime(DateTime[1],LCD_DSY_BUFFER2+8); Format_DateTime(DateTime[0],LCD_DSY_BUFFER2+11); Display_LCD_String(0x00,LCD_DSY_BUFFER1); Display_LCD_String(0x40,LCD_DSY_BUFFER2);}void EX_INT0() interrupt 0 //键盘中断{if(K1==0) //选择调整对象:年,月,日,时,分,秒{ while(K1==0);if(Adjust_Index==-1||Adjust_Index==1) Adjust_Index=7; Adjust_Index--;if(Adjust_Index==5) Adjust_Index=4;LCD_DSY_BUFFER2[13]='[';LCD_DSY_BUFFER2[14]=Change_Flag[Adjust_Index]; LCD_DSY_BUFFER2[15]=']';}elseif(K2==0) // 加{while (K2==0); DateTime_Adjust(1);}elseif(K3==0) // 减{while (K3==0); DateTime_Adjust(-1);}elseif(K4==0) // 确定{while(K4==0);SET_DS1302(); //调整后的时间写入DS1302LCD_DSY_BUFFER2[13]=' ';LCD_DSY_BUFFER2[14]=' ';LCD_DSY_BUFFER2[15]=' ';Adjust_Index=-1;}}void main() //主程序{Init_LCD(); //LCD初始化IE=0x83; // 允许INT0,T0中断IP=0x01;IT0=0x01;TMOD=0x01;TH0=-50000/256;TL0=-50000%256;TR0=1;while(1){if(Adjust_Index==-1) GetTime(); }}。
