当前位置:文档之家› 基于单片机的时钟设计

基于单片机的时钟设计

随着现代生活的推进,电子时钟在人们的生活中已经普及,本课题的主要内容就是结合单片机的强大功能,在一块普通的电子时钟集成多种功能,方便人们的日常生活,该功能是通过单片机、8 段数码管以及一些简单辅助电路实现的。

由于之前没有独立做过单片机实现多功能电子时钟方面的内容,所以在做设计时总会遇见很多问题,本次设计是在结合老师的指导及同学的帮助下完成的,并通过在网上所查的大量资料及单片机设计中常见的电路而构思出来的。

单片计算机即单片微型计算机。

由RAM ,ROM,CPU 构成,定时,计数和多种接口于一体的微控制器。

它体积小,成本低,功能强,广泛应用于智能产业和工业自动化上。

51 系列单片机是各单片机中最为典型和最有代表性的一种。

这次课程设计通过对它的学习,应用,从而达到学习、设计、开发软、硬的能力。

本设计主要设计了一个基于AT89C51单片机的电子时钟。

并在数码管上显示相应的时间。

并通过一个控制键用来实现时间的调节和是否进入省电模式的转换。

该方法仿真效果真实、准确,节省了硬件资源。

1.主要功能用4位LED显示时、分、秒值,以24小时计时方式工作,可用开关调整时间值和闹铃时间。

2.硬件设计如下图所示,本次设计时钟电路,使用AT89C51单片机芯片控制电路,单片机控制电路简单且省去了很多复杂的线路,使得电路简明易懂,使用键盘键上的按键来调整时钟的时、分、秒,用一蜂鸣器来进行定时提醒,同时使用C语言程序来控制整个时钟显示,使得编程变得更容易,这样通过四个模块:键盘、芯片、蜂鸣器、显示屏即可满足设计要求。

单片机电路如下:3.软件设计:(一)主要功能及原理数字式电子钟用集成电路计时时,译码代替机械式传动,用LED 显示器代替指针显示进而显示时间,减小了计时误差,这种表具有时、分、秒显示时间的功能,还可以进行时和分的校对,片选的灵活性好。

该电子时钟由AT89C51、四段数码管等构成,采用晶振电路作为驱动电路, 由延时程序和循环程序产生的一秒定时,达到时分秒的计时,六十秒为一分钟,六十分钟为一小时,满二十四小时为一天。

而电路中唯一的一个控制键却拥有多种不同的功能,按下又松开,可以实现屏蔽数码管显示的功能,达到省电的目的;直接按下,则可以通过按键实现分钟的累加,每按一次分钟加一;而另一个键按下,则可实现小时的调节,同样每按一次小时加一。

(二)通过对多种单片机性能的分析,最终认为AT89C51是最理想的电子时钟开发芯片。

AT89C51是一种带4K字节闪烁可编程可擦除只读存储器的低电压,高性能CMOS8位微处理器,单片机的外部扩展能力很强。

在内部的各种功能部件不能满足应用的需求时, 均可在外部进行扩展,与许多通用的微机接口芯片兼容,给应用系统设计带来了很大的方便。

(三)数码管显示工作原理数码管是一种把多个LED 显示段集成在一起的显示设备。

有两种类型,一种是共阳型,一种是共阴型.共阳型就是把多个LED显示段的阳极接在一起,又称为公共端。

共阴型就是把多个LED显示段的阴极接在一起,即为公共商。

阳极即为二极管的正极, 又称为正极,阴极即为二极管的负极,又称为负极.通常的数码管又分为8 段,即8 个LED 显示段,这是为工程应用方便如设计的,分别为A,B,C,D,E,F,G,DP,其中DP是小数点位段。

而多位数码管,除某一位的公共端会连接在一起,不同位的数码管的相同端也会连接在一起。

即所有的A 段都会连在一起,其它的段也是如此,这是实际最常用的用法。

数码管显示方法可分为静态显示和动态显示两种。

静态显示就是数码管的8 段输入及其公共端电平一直有效.动态显示的原理是,各个数码管的相同段连接在一起,共同占用8 位段引管线;每位数码管的阳极连在一起组成公共端。

2个1个28 个3个1个利用人眼的视觉暂留性,依次给出各个数码管公共端加有效信号,在此同时给出该数码管加有效的数据信号,当全段扫描速度大于视觉暂留速度时,显示就会清晰显示出来。

(四)键盘电路设计该设计只用了4个键,实现的功能却是比较完善,减少了硬件资源的损耗。

首先按下S3进入时间调整状态,S1为小时时间加一,S2为分钟时间加一,再按S3进入正常走时状态;按下S4进入闹钟调整时间状态,S1为小时时间加一,S2为分钟时间加一,再按S4进入正常走时,到时间达到闹钟调整时间蜂鸣器发出响声。

主程序流程图4.源程序代码#include<reg51.h> // 包含51单片机寄存器定义的头文件unsigned char code Tab[ ]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //数字0~9的段码unsigned char int_time ; //中断次数计数变量unsigned char second; //秒计数变量unsigned char minute,minute1; //分钟计数变量unsigned char hour,hour1; //小时计数变量unsigned int count=0;sbit SOUND=P3^7;unsigned int t=0;sbit S4=P3^3;sbit S1=P3^2; //将S1位定义为P3.2sbit S2=P3^1; //将S2位定义为P3.1sbit S3=P3^0; //将S3位定义为P3.0sbit P0_7=P0^7;/****************************************************************** 函数功能:数码管扫描延时********************************************************************/ void delay(void){unsigned char j;for(j=0;j<200;j++);}/******************************************************************函数功能:键盘扫描延时********************************************************************/ void delay60ms(void){unsigned char i,j;for(i=0;i<200;i++)for(j=0;j<100;j++);}/****************************************************************** 函数功能:显示秒入口参数:s********************************************************************/ void DisplaySecond(unsigned char s){if(int_time<=10){P0_7=0;P2=0x40;}delay();P2=0x00;}/****************************************************************** 函数功能:显示分钟入口参数:m********************************************************************/ void DisplayMinute(unsigned char m){P2=0x20; // P2.5引脚输出高电平P0=Tab[m/10]; //显示十位delay();P2=0x10; // P2.4引脚输出高电平P0=Tab[m%10]; //显示个位delay();P2=0x00; //关闭所有数码管}/****************************************************************** 函数功能:显示小时的子程序入口参数:h********************************************************************/ void DisplayHour(unsigned char h){P2=0x80; //P2.7引脚输出高电平P0=Tab[h/10]; //显示十位delay();P2=0x40; //P2.6引脚输出高电平P0=Tab[h%10]; //显示个位delay();P2=0x00; //关闭所有数码管}/****************************************************************** 函数功能:键盘扫描********************************************************************/ void key_scan(void){if(S3==0) //有键按下{delay60ms(); //延时60ms再检测if(S3==0) //确实有键按下{if(S1==0) //如果是S1键按下{minute++; //分钟加1DisplayMinute(minute); } //调用分钟显示子程序if(S2==0) //如果是S2键按下{hour++; //小时加1DisplayHour(hour); } //调用小时显示子程序 }}}void key1_scan(void){if(S4==0) //有键按下{delay60ms(); //延时60ms再检测if(S4==0) //确实有键按下{if(S1==0) //如果是S1键按下{minute1++; //分钟加1if(minute1==60)minute1=0;DisplayMinute(minute1); } //调用分钟显示子程序if(S2==0) //如果是S2键按下{hour1++; //小时加1if(hour1==24)hour1=0;DisplayHour(hour1); } //调用小时显示子程序}}}void clock(void){for(count=0;count<=5;count++){SOUND=~SOUND;delay60ms();}count=0;SOUND=0;}/****************************************************************** 函数功能:主函数********************************************************************/void main(){TMOD=0x01; //使用定时器T0EA=1;ET0=1; //允许T0中断TH0=(65536-46083)/256; //定时器高八位赋初值TL0=(65536-46083)%256; //定时器低八位赋初值TR0=1; //启动定时器T0TR1=0;minute1=1;hour1=1;int_time=0; //中断计数变量初始化minute=0; //分钟计数变量初始化hour=0; //小时计数变量初始化P3=0x7f;SOUND=0;S4=1,S1=1,S2=1,S3=1; //将S1,S2,S3置高电平“1”if(S3==0)key_scan();if(S4==0)key1_scan();while(1){if(S4==0){DisplayMinute(minute1); //调用分钟显示子程序DisplayHour(hour1); //调用小时显示子程序}else{DisplaySecond(second); //调用秒钟显示子程序 DisplayMinute(minute); //调用分钟显示子程序DisplayHour(hour); //调用小时显示子程序}if(minute==minute1&&hour==hour1)clock();}}/****************************************************************** 函数功能:定时器T0的中断服务子程序********************************************************************/ void interserve(void ) interrupt 1 using 1 //using Time0{TR0=0; //关闭定时器T0int_time++; //中断次数加1if(int_time==20) //如果中断次数满20{int_time=0; //中断计数变量清0second++; //秒计数变量加1}if(second==60) //如果秒计满60{second=0; //如果秒计满60,将秒计数变量清0minute++; //分钟计数变量加1}if(minute==60) //如果分钟计满60{minute=0; //如果分钟计满60,将分钟计数变量清0hour++; //小时计数变量加1}if(hour==24) //如果小时计满24{hour=0; //如果小时计满24,将小时计数变量清0 }key_scan();key1_scan();TH0=(65536-46083)/256; //定时器T0高四位赋值TL0=(65536-46083)%256; //定时器T0低四位赋值 TR0=1; //启动定时器T0}5.系统调试在硬件设计时,我们使单片机P0端口接4位共阳极LED数码显示器。

相关主题