C51单片机实现电子闹钟

合集下载

基于51单片机的多功能电子钟设计

基于51单片机的多功能电子钟设计

基于51单片机的多功能电子钟设计1. 本文概述随着现代科技的发展,电子时钟已成为日常生活中不可或缺的一部分。

本文旨在介绍一种基于51单片机的多功能电子钟的设计与实现。

51单片机因其结构简单、成本低廉、易于编程等特点,在工业控制和教学实验中得到了广泛应用。

本文将重点阐述如何利用51单片机的这些特性来设计和实现一个具有基本时间显示、闹钟设定、温度显示等功能的电子钟。

本文的结构安排如下:将详细介绍51单片机的基本原理和特点,为后续的设计提供理论基础。

接着,将分析电子钟的功能需求,包括时间显示、闹钟设定、温度显示等,并基于这些需求进行系统设计。

将详细讨论电子钟的硬件设计,包括51单片机的选型、时钟电路、显示电路、温度传感器电路等。

软件设计部分将介绍如何通过编程实现电子钟的各项功能,包括时间管理、闹钟控制、温度读取等。

本文将通过实验验证所设计的电子钟的功能和性能,并对实验结果进行分析讨论。

通过本文的研究,旨在为电子钟的设计提供一种实用、经济、可靠的方法,同时也为51单片机的应用提供一个新的实践案例。

2. 51单片机概述51单片机,作为一种经典的微控制器,因其高性能、低功耗和易编程的特性而被广泛应用于工业控制、智能仪器和家用电器等领域。

它基于Intel 8051微处理器的架构,具备基本的算术逻辑单元(ALU)、程序计数器(PC)、累加器(ACC)和寄存器组等核心部件。

51单片机的核心是其8位CPU,能够处理8位数据和执行相应的指令集。

51单片机的内部结构主要包括中央处理单元(CPU)、存储器、定时器计数器、并行IO口、串行通信口等。

其存储器分为程序存储器(ROM)和数据存储器(RAM)。

程序存储器通常用于存放程序代码,而数据存储器则用于存放运行中的数据和临时变量。

51单片机还包含特殊功能寄存器(SFR),用于控制IO端口、定时器计数器和串行通信等。

51单片机的工作原理基于冯诺伊曼体系结构,即程序指令和数据存储在同一块存储器中,通过总线系统进行传输。

C51单片机实现电子闹钟

C51单片机实现电子闹钟

课程名称:单片机原理与接口技术实践设计课题:基于MCS 51单片机实现电子闹钟功能的设计学院:电子与信息工程学院专业:通信工程小组成员:电子闹钟在科学技术高度发展的今天,千家万户都少不了它,所以很多家庭个人都需要有一个电子闹钟,为人们提供报时方便,但普通电子闹钟不够方便实用。

本文给出了一种基于MCS51单片机实现电子闹钟功能的设计方法,从而给人们带来更为方便的工作与生活。

一.电子闹钟简介我们设计的电子闹钟是以MCS51单片机中的计时器作为时钟,用8位数码管显示当前时间,并且可以设置闹钟时间,并在设置的时间点发出闹铃。

简易闹钟具有以下功能:1.时钟能准确地走时,并可以通过数码管进行显示2.复位后可以进行当前时间的设置3.可以随意设置闹钟时间,闹钟会在设置时间响铃整个系统的任务要求:1)输入数字按键的功能。

保证数字的输入。

2)复位电路的功能。

所有时间回到初始化状态,用于启动设定时间参数(调时或设定闹钟时间);3)显示电路的功能。

当输入数字时显示24小时时间功能。

4)闹铃功能设置闹铃的时间后.能按设置好的时间准时闹铃。

二.系统方案的设计要求根据以上各模块并结合显示屏的功能及元器件材料的情况,决定采用AT89C51为内核显示设计方案。

先进行系统的整体规划确定整个系统的功能,然后按照每个功能的具体要求,进行各个模块的实物设计并逐个调试,待全部通过后,进行整个系统的联调,最终实现一个完整的系统。

整个系统的设计步骤如下:在单片机最小系统的基础上,完成按键电路和复位电路的设计。

完成显示电路、数字按键、单片机时钟电路。

Ⅰ硬件设计系统硬件的设计可以根据系统的各个功能,把整个系统划分成若干个模块,分别对这些模块来进行设计,然后在通过单片机程序来实现对各个硬件模块功能的调度。

本系统涉及到的硬件模块有:按键电路、数码管显示电路、单片机时钟电路、蜂鸣器电路。

各部分实现功能如下:按键电路:提供按键信号。

单片机时钟电路、复位电路:提供内部时钟。

51单片机c语言电子钟(已加入调时、闹铃、整点报时功能)

51单片机c语言电子钟(已加入调时、闹铃、整点报时功能)

51单片机c语言电子钟(已加入调时、闹铃、整点报时功能)效果图:程序如下://51单片机c语言电子钟(已加入调时、闹铃、整点报时功能)#include<reg51.h>#include<absacc.h>#define uchar unsigned char#define uint unsigned int/*七段共阴管显示定义*///此表为LED 的字模,共阴数码管0-9 -uchar code dispcode[] ={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40}; //段码控制/*定义并初始化变量*/uchar seconde=0;//秒uchar minite=0;//分uchar hour=12; //时uchar shi=0;//闹铃功能uchar fen=0;uchar bjcs;//报警次数sbit P1_0=P1^0; //second 调整定义sbit P1_1=P1^1; //minite调整定义sbit P1_2=P1^2; //hour调整定义sbit P1_5=P1^5; //整点报时sbit P1_3=P1^3; //闹铃功能,调整时间sbit P1_6=P1^6; //调整时sbit P1_7=P1^7; //调整分sbit P1_4=P1^4; //关闭闹铃/*函数声明*/void delay(uint k ); //延时子程序void time_pro( ); //时间处理子程序void display( ); //显示子程序void keyscan( ); //键盘扫描子程序/*xx子程序*/void delay (uint k){uchar j;while((k--)!=0){for(j=0;j<125;j++){;}}}/*时间处理子程序*/void time_pro(void){if(seconde==60){seconde=0;minite++;if(minite==60){minite=0;hour++;if(hour==24){hour=0;}}}}/*显示子程序*/void display(void){if(P1_3==1){P2=0XFE; P0=dispcode[seconde%10];//秒个位delay(1);P2=0XFD;P0=dispcode[seconde/10];//秒十位delay(1);P2=0XFB;P0=dispcode[10];//间隔符-delay(1);P2=0XF7;P0=dispcode[minite%10];//分个位delay(1);P2=0XEF;P0=dispcode[minite/10];//分十位delay(1);P2=0XDF;P0=dispcode[10];//间隔符-delay(1);P2=0XBF;P0=dispcode[hour%10];//时个位delay(1);P2=0X7F;P0=dispcode[hour/10];//时十位delay(1);}}/*键盘扫描子程序*/void keyscan(void){if(P1_0==0)//秒位的调整{delay (30);if(P1_0==0){seconde++;if(seconde==60){seconde=0;}}delay(250);}if(P1_1==0)//分位的调整{delay(30);if(P1_1==0){minite++;if(minite==60){minite=0;}}delay(250);}if(P1_2==0)//时位的调整{delay(30);if(P1_2==0){hour++;if(hour==24){hour=0;}}delay(250);}}/*整点报警*/void zhengdian (void){if((seconde==0)&(minite==0))//整点报时{P1_5=0;delay(1000);P1_5=1;}}/*定时闹钟*/void dingshi(void){if(P1_3==0)//按住P1_3BU不松,显示闹铃设置界面,分别按P1_6、P1_7设置闹铃时间。

51单片机电子闹钟程序(亲自编写,可用)

51单片机电子闹钟程序(亲自编写,可用)

学校电子钟,有闹钟功能,按键可调时间,可调打铃时间,打铃时间长短显示,每个模块有功能注释。

其中正常时间显示和闹钟时间显示可用一个开关来调整。

芯片选择STC89C52程序:#include<reg51.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned int//定义显示段码uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};uchar codebbtime[]={0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; uchar clock[]={0,0,0,0};uchar clock1[]={12,30,0};uchar weikong[6];uchar bbduration=4;uchar lingtime=9;//学校打铃时间组uchar shangwu1[]={8,30};uchar shangwu2[]={10,0};uchar shangwu3[]={10,20};uchar shangwu4[]={11,50};uchar xiawu1[]={13,30};uchar xiawu2[]={15,00};uchar xiawu3[]={15,15};uchar xiawu4[]={16,45};//按键定义sbit mode=P1^7;sbit sec_clr=P1^0;sbit min_set_add=P1^3;sbit min_set_sub=P1^4;sbit hour_set_add=P1^1;sbit hour_set_sub=P1^2;sbit bb_set_add=P1^5;sbit bb_set_sub=P1^6;sbit speaker=P2^6;//延时函数void delay(unsigned int t){while(t--);//时钟进位函数void clockjinwei(){clock[0]++;if(clock[0]==20){clock[1]++;clock[0]=0;if(clock[1]==60){clock[2]++;clock[1]=0;if(clock[2]==60){clock[3]++;clock[2]=0;if(clock[3]==24)clock[3]=0;}}}}//定时器0中断服务函数void timer0(void) interrupt 1 using 1 {TMOD=0x01;TH0=0x3c;TL0=0xb0;clockjinwei();}//时钟分位显示函数void fenwei(){weikong[0]=clock[3]/10;weikong[1]=clock[3]%10;weikong[2]=clock[2]/10;weikong[3]=clock[2]%10;weikong[4]=clock[1]/10;weikong[5]=clock[1]%10;}//闹钟分位显示函数void naofen(){weikong[0]=clock1[0]/10;weikong[1]=clock1[0]%10;weikong[2]=clock1[1]/10;weikong[3]=clock1[1]%10;weikong[4]=clock1[2]/10;weikong[5]=clock1[2]%10; }//闹钟定时显示函数void naozhongdisplay(){uchar z,s;uchar x=0x01;naofen();for(z=0;z<6;z++){P2=0;P0=table[weikong[z]];P2=x;x=_crol_(x,1);for(s=0;s<255;s++);}}//时钟显示函数void display(){uchar i,j;uchar x=0x01;fenwei();for(i=0;i<6;i++){P2=0;P0=table[weikong[i]];P2=x;x=_crol_(x,1);for(j=0;j<255;j++);}}//总显示函数void zhongxian(){if(mode==1)delay(100);if(mode==1)display();if(mode==0)delay(100);if(mode==0)naozhongdisplay();}//按键处理程序void key_set(){zhongxian();P1=0xff;if(min_set_add==0){delay(100);if(min_set_add==0){if(mode==1){clock[2]++;if(clock[2]==60){clock[2]=0;}while(min_set_add==0)zhongxian();}}if(mode==0){clock1[1]++;if(clock1[1]==60){clock1[1]=0;}while(min_set_add==0)zhongxian();}}//if(min_set_sub==0){delay(100);if(min_set_sub==0){if(mode==1){clock[2]--;if(clock[2]==0)clock[2]=59;}while(min_set_sub==0)zhongxian();if(mode==0){clock1[1]--;if(clock1[1]==0)clock1[1]=59;}while(min_set_sub==0)zhongxian();}}//if(hour_set_add==0){delay(100);if(hour_set_add==0){if(mode==1){clock[3]++;if(clock[3]==24){clock[3]=0;}while(hour_set_add==0)zhongxian();}if(mode==0){clock1[0]++;if(clock1[0]==24){clock1[0]=0;}while(hour_set_add==0)zhongxian();}}}//if(hour_set_sub==0){delay(100);if(hour_set_sub==0){if(mode==1){clock[3]--;if(clock[3]==0)clock[3]=23;}while(hour_set_sub==0)zhongxian();if(mode==0){clock1[0]--;if(clock1[0]==0)clock1[0]=23;}while(hour_set_sub==0)zhongxian();}}//if(sec_clr==0){delay(100);if(sec_clr==0){clock[1]=0;}while(sec_clr==0)zhongxian();}}//闹钟响铃函数void bb(){if(clock[1]<=bbduration){speaker=1;delay(100);speaker=0;}else speaker=0;}//打铃函数void daling(){if(clock[1]<=lingtime){speaker=1;delay(100);speaker=0;}else speaker=0;}//时间比较函数void bijiao(){if(clock[3]==shangwu1[0]){if(clock[2]==shangwu1[1])daling();}if(clock[3]==shangwu2[0]){if(clock[2]==shangwu2[1])daling();}if(clock[3]==shangwu3[0]){if(clock[2]==shangwu3[1])daling();}if(clock[3]==shangwu4[0]){if(clock[2]==shangwu4[1])daling();}if(clock[3]==xiawu1[0]){if(clock[2]==xiawu1[1])daling();}if(clock[3]==xiawu2[0]){if(clock[2]==xiawu2[1])daling();}if(clock[3]==xiawu3[0]){if(clock[2]==xiawu3[1])daling();}if(clock[3]==xiawu4[0]){if(clock[2]==xiawu4[1])daling();}}//闹钟比较void naobijiao(){if(clock[3]==clock1[0]){if(clock[2]==clock1[1]||clock[2]==clock1[1]+1||clock[2]==clock1[1]+2) bb();}}//响铃时长显示函数void bbtimeshow(){P3=bbtime[bbduration];if(bbduration>15)bbduration=0;}//响铃按键处理函数void bbtime_set(){bbtimeshow();if(bb_set_add==0){delay(100);if(bb_set_add==0)bbduration++;while(bb_set_add==0)bbtimeshow();}if(bb_set_sub==0){delay(100);if(bb_set_sub==0)bbduration--;while(bb_set_sub==0)bbtimeshow();}}//主程序void main(){EA=1;ET0=1;TR0=1;while(1){key_set();bijiao();bbtime_set();naobijiao();}}电路图:分四部分显示:如果在学习这个程序过程中有什么问题,可以发邮件到******************询问。

基于c51功能最全的电子钟程序(lcd1602)

基于c51功能最全的电子钟程序(lcd1602)

功能最全的电子钟【单片机】c51数字时钟(带年月日显示)摘要:本设计以单片机为核心,lcd1602显示。

采用独立键盘输入能任意修改当前时间日期和设定闹钟时间。

具有显示年月日(区分闰年和二月),闹钟报警和整点报时功能主程序:/********************************************************************************************************************************************************************************* ****************************************** lcd1602电子钟********************************************************************************************************************************** *************************************************************************************************** ********************/# include <reg52.h># include "lcd16024.h"sbit key1 = P2^0; //调整sbit key2 = P2^1; //加1sbit key3 = P2^2; //减1sbit speaker = P2^3; //蜂鸣器sbit key4 = P2^4; //闹钟设计bit cal_year = 1; //进入判断闰年标志位bit leap_year; //闰年标志位bit calculate = 0; //日加一标记bit run = 0; //闹钟标志bit beep = 0; //整点报时标志//uint8 num = 0; //调整是给的脉冲uint8 code str1[] = "D: ";uint8 code str2[] = "T: ";uint8 code str3[] = "Wek";uint8 daystr[]="2013-07-29 "; //年月日格式uint8 timestr[]="21:30:59 N"; //时分秒格式uint8 daystr1[]="2013-07-29 "; //闹钟年月日格式uint8 timestr1[]="21:30:59 N"; //闹钟时分秒格式uint8 numweek = 0; //星期加1标记char week = 1; //星期char sec = 53; //秒char min = 50; //分char hour = 23; //时uint8 day = 30; // 日uint8 month = 9; //月uint16 year = 2013; //年char week1 = 1; //闹钟星期char sec1 = 58; //闹钟秒char min1 = 50; //闹钟分char hour1 = 23; //闹钟时uint8 day1 = 30; //闹钟日uint8 month1 = 9; //闹钟月uint16 year1 = 2013; //闹钟年uint8 WeekData1; //闹钟星期标记uint8 number = 0; //定时uint8 WeekData; //星期标记uint8 speaker_num; //整点报时次数uint8 scan_key(void); //函数声名/****************************************************************************** ***************************** 更新LCD时间分离读取******************************************************************************************************************* *******/void TimeChange(){//时分秒timestr[7] = sec%10+'0';timestr[6] = sec/10+'0';timestr[4] = min%10+'0';timestr[3] = min/10+'0';timestr[1] = hour%10+'0';timestr[0] = hour/10+'0';//年月日daystr[9] = day%10+'0';daystr[8] = day/10+'0';daystr[6] = month%10+'0';daystr[5] = month/10+'0';daystr[3] = year%10+'0';daystr[2] = year/10%10+'0';daystr[1] = year/100%10+'0';daystr[0] = year/1000+'0';//星期WeekData = week+'0';}/****************************************************************************** ***************************** 闹钟更新LCD时间分离读取******************************************************************************************************************* *******/void TimeChange1(){//时分秒timestr1[7] = sec1%10+'0';timestr1[6] = sec1/10+'0';timestr1[4] = min1%10+'0';timestr1[3] = min1/10+'0';timestr1[1] = hour1%10+'0';timestr1[0] = hour1/10+'0';//年月日daystr1[9] = day1%10+'0';daystr1[8] = day1/10+'0';daystr1[6] = month1%10+'0';daystr1[5] = month1/10+'0';daystr1[3] = year1%10+'0';daystr1[2] = year1/10%10+'0';daystr1[1] = year1/100%10+'0';daystr1[0] = year1/1000+'0';//星期WeekData1 = week1+'0';}/****************************************************************************** ***************************** 初始化系统定时器0 ******************************************************************************************************************* *******/void systimer0_init(void){TMOD |=0x01;//设置为1时用或(|)TMOD &=0xfd;//设置为0时用与(&)TH0 = 0xDC; // 定时10msTL0 = 0x00;EA = 1;ET0=1;TR0=1;EX0 = 1;}/****************************************************************************** ***************************** 闹钟时间设置*************************************************************************************************************** *******/void naozhong(){uint8 number = 1;uint8 a = 0;uint8 b = 0;if(0 == key4){Delay1Ms(5);if(0 == key4){a = 1;LCD_write_command(0xc0+9);LCD_write_command(0x0f);}while(!key4);}while(a){if(0 == key4){Delay1Ms(5);if(0 == key4){a = 0;run = ~run;while(!key4);}}if(run){timestr[9] = 'Y';}else{timestr[9] = 'N';}if(0 == key1){Delay1Ms(5);if(0 == key1){b = 1;}while(!key1);}while(b){if(0 == key1){Delay1Ms(5);if(0 == key1){number++;if(4 == number)b = 0;}while(!key1);if(number == 1){LCD_write_command(0xc0+9);LCD_write_command(0x0f);}if(number == 2){LCD_write_command(0xc0+6);LCD_write_command(0x0f);}if(number == 3){LCD_write_command(0xc0+3);LCD_write_command(0x0f);}}}switch(number){case 1:if(0 == key2) //闹钟秒加1的设置{Delay1Ms(5);if(0 == key2){sec1++;if(60 == sec1){sec1 = 0;}while(!key2);timestr1[7] = sec1%10+'0';timestr1[6] = sec1/10+'0';LCD_write_char(8,1,timestr1[6]);LCD_write_char(9,1,timestr1[7]);LCD_write_command(0xc0+9);}}if(0 == key3) //闹钟秒减1的设置Delay1Ms(5);if(0 == key3){sec1--;if(sec1 < 0){sec1 = 59;}while(!key3);timestr1[7] = sec1%10+'0';timestr1[6] = sec1/10+'0';LCD_write_char(8,1,timestr1[6]);LCD_write_char(9,1,timestr1[7]);LCD_write_command(0xc0+9);}}break;case 2:if(0 == key2) //闹钟分加1的设置{Delay1Ms(5);if(0 == key2){min1++;if(60 == min1){min1 = 0;}while(!key2);timestr1[4] = min1%10+'0';timestr1[3] = min1/10+'0';;LCD_write_char(5,1,timestr1[3]);LCD_write_char(6,1,timestr1[4]);LCD_write_command(0xc0+6);}}if(0 == key3) //闹钟分减1的设置{Delay1Ms(5);if(0 == key3){min1--;if(min1 < 0){min1 = 59;}while(!key3);timestr1[4] = min1%10+'0';timestr1[3] = min1/10+'0';;LCD_write_char(5,1,timestr1[3]);LCD_write_char(6,1,timestr1[4]);LCD_write_command(0xc0+6);}}break;case 3:if(0 == key2) //闹钟时加1的设置{Delay1Ms(5);if(0 == key2){hour1++;if(24 == hour1){hour1 = 0;}while(!key2);timestr1[1] = hour1%10+'0';timestr1[0] = hour1/10+'0';LCD_write_char(2,1,timestr1[0]);LCD_write_char(3,1,timestr1[1]);LCD_write_command(0xc0+3);}}if(0 == key3) //闹钟时减1的设置{Delay1Ms(5);if(0 == key3){hour1--;if(hour1 < 0){hour1 = 23;}while(!key3);timestr1[1] = hour1%10+'0';timestr1[0] = hour1/10+'0';LCD_write_char(2,1,timestr1[0]);LCD_write_char(3,1,timestr1[1]);LCD_write_command(0xc0+3);}}break;case 4:b = 0;LCD_write_command(0x0c);break;}}}LCD_write_command(0x0c);while(!key4);}/****************************************************************************** ***************************** 判断按键进入时间调整*************************************************************************************************************** *******/uint8 scan_key(void){uint8 number = 1;uint8 a = 0;if(0 == key1){Delay1Ms(5);if(0 == key1){while(!key1);a = 1;LCD_write_command(0xc0+9);LCD_write_command(0x0f);}}while(a){if(0 == key1){Delay1Ms(5);if(0 == key1){number++;while(!key1);TR0 = 0;if(number == 2){LCD_write_command(0xc0+6);LCD_write_command(0x0f);}if(number == 3){LCD_write_command(0xc0+3);LCD_write_command(0x0f);}if(number == 4){LCD_write_command(0x80+11);LCD_write_command(0x0f);}if(number == 5){LCD_write_command(0x80+8);LCD_write_command(0x0f);}if(number == 6){LCD_write_command(0x80+5);LCD_write_command(0x0f);}if(number == 7){LCD_write_command(0xc0+14);LCD_write_command(0x0f);}if(8 == number){LCD_write_command(0x0c);a = 0;number = 0;}}}switch(number){case 1:if(0 == key2) //秒加1的设置{Delay1Ms(5);if(0 == key2){sec++;if(60 == sec){sec = 0;}timestr[7] = sec%10+'0';timestr[6] = sec/10+'0';LCD_write_char(8,1,timestr[6]);LCD_write_char(9,1,timestr[7]);LCD_write_command(0xc0+9);while(!key2);}}if(0 == key3) //秒减1的设置{Delay1Ms(5);if(0 == key3){sec--;if(sec < 0){sec = 59;}timestr[7] = sec%10+'0';timestr[6] = sec/10+'0';LCD_write_char(8,1,timestr[6]);LCD_write_char(9,1,timestr[7]);LCD_write_command(0xc0+9);while(!key3);}}break;case 2:if(0 == key2) //分加1的设置{Delay1Ms(5);if(0 == key2){min++;if(60 == min){min = 0;}timestr[4] = min%10+'0';timestr[3] = min/10+'0';;LCD_write_char(5,1,timestr[3]);LCD_write_char(6,1,timestr[4]);LCD_write_command(0xc0+6);while(!key2);}}if(0 == key3) //分减1的设置{Delay1Ms(5);if(0 == key3){min--;if(min < 0){min = 59;}timestr[4] = min%10+'0';timestr[3] = min/10+'0';LCD_write_char(5,1,timestr[3]);LCD_write_char(6,1,timestr[4]);LCD_write_command(0xc0+6);while(!key3);}}break;case 3:if(0 == key2) //时加1的设置{Delay1Ms(5);if(0 == key2){hour++;while(!key2);if(24 == hour){hour = 0;}timestr[1] = hour%10+'0';timestr[0] = hour/10+'0';LCD_write_char(2,1,timestr[0]);LCD_write_char(3,1,timestr[1]);LCD_write_command(0xc0+3);}}if(0 == key3) //时减1的设置{Delay1Ms(5);if(0 == key3){while(!key3);hour--;if(hour < 0){hour = 23;}timestr[1] = hour%10+'0';timestr[0] = hour/10+'0';LCD_write_char(2,1,timestr[0]);LCD_write_char(3,1,timestr[1]);LCD_write_command(0xc0+3);}}break;case 4:if(0 == key2) //日加1的设置{Delay1Ms(5);if(0 == key2){while(!key2);calculate = 1;if(calculate == 1){if(month==1|month==3|month==5|month==7|month==8|month==10|month==12){day++;if(day > 31){day=1;}}if(month==4|month==6|month==9|month==11){day++;if(day > 30){day=1;}}if(month == 2){cal_year = 1;while(cal_year == 1){leap_year = ((year % 4 == 0 && year % 100 != 0)||(year % 400 == 0));cal_year = 0;}if(leap_year==1){day++;if(day > 30){day=1;}}else{day++;if(day > 29){day=1;}}}calculate = 0;}daystr[9] = day%10+'0';daystr[8] = day/10+'0';LCD_write_char(10,0,daystr[8]);LCD_write_char(11,0,daystr[9]);LCD_write_command(0x80+11);}}if(0 == key3) //日减1的设置{Delay1Ms(5);if(0 == key3){while(!key3);calculate = 1;if(calculate == 1){if(month==1|month==3|month==5|month==7|month==8|month==10|month==12){day--;if(day == 0){day=31;}}if(month==4|month==6|month==9|month==11){day--;if(day == 0){day=30;}}if(month == 2){cal_year = 1;while(cal_year == 1){leap_year = ((year % 4 == 0 && year % 100 != 0)||(year % 400 == 0));cal_year = 0;}if(leap_year==1){day--;if(day == 0){day=30;}}else{day--;if(day == 0){day=29;}}}calculate = 0;}daystr[9] = day%10+'0';daystr[8] = day/10+'0';LCD_write_char(10,0,daystr[8]);LCD_write_char(11,0,daystr[9]);LCD_write_command(0x80+11);}}break;case 5:if(0 == key2) //月加1的设置{Delay1Ms(5);if(0 == key2){while(!key2);month++;if(13 == month){month = 1;}daystr[6] = month%10+'0';daystr[5] = month/10+'0';LCD_write_char(7,0,daystr[5]);LCD_write_char(8,0,daystr[6]);LCD_write_command(0x80+8);}}if(0 == key3) //月减1的设置{Delay1Ms(5);if(0 == key3){while(!key3);month--;if(month == 0){month = 12;}daystr[6] = month%10+'0';daystr[5] = month/10+'0';LCD_write_char(7,0,daystr[5]);LCD_write_char(8,0,daystr[6]);LCD_write_command(0x80+8);}}break;case 6:if(0 == key2) //年加1的设置{Delay1Ms(5);if(0 == key2){while(!key2);year++;}daystr[3] = year%10+'0';daystr[2] = year/10%10+'0';daystr[1] = year/100%10+'0';daystr[0] = year/1000+'0';LCD_write_char(2,0,daystr[0]);LCD_write_char(3,0,daystr[1]);LCD_write_char(4,0,daystr[2]);LCD_write_char(5,0,daystr[3]);LCD_write_command(0x80+5);}if (0 == key3) //年减1的设置{Delay1Ms(5);if(0 == key3){while(!key3);year--;if(year == 0){year = 2020;}daystr[3] = year%10+'0';daystr[2] = year/10%10+'0';daystr[1] = year/100%10+'0';daystr[0] = year/1000+'0';LCD_write_char(2,0,daystr[0]);LCD_write_char(3,0,daystr[1]);LCD_write_char(4,0,daystr[2]);LCD_write_char(5,0,daystr[3]);LCD_write_command(0x80+5);}}break;case 7:if(0 == key2) //星期加1的设置{Delay1Ms(5);if(0 == key2){while(!key2);week++;if(7 == week){week = 0;}LCD_write_char(14,1,week+'0');LCD_write_command(0xc0+14);}}if (0 == key3) //星期减1的设置{Delay1Ms(5);if(0 == key3){while(!key3);week--;if(week < 0){week = 6;}LCD_write_char(14,1,week+'0');LCD_write_command(0xc0+14);}}break;case 8:TR0 = 1;break;}}}/****************************************************************************** ***************************** 主函数******************************************************************************************************************* *******/void main(void){systimer0_init();LCD_init();LCD_write_str(0,0,str1);LCD_write_str(0,1,str2);LCD_write_str(13,0,str3);speaker = 0;while (1){TimeChange();scan_key();naozhong();LCD_write_str(2,0,daystr);LCD_write_str(2,1,timestr);LCD_write_char(14,1,WeekData);if(1 == run){if(sec==sec1 & month==month1 & hour==hour){speaker_num =30;beep = 1;}}else{speaker_num =0;beep = 0;}}}/****************************************************************************** ***************************** 定时中断0 ******************************************************************************************************************* *******/void time_0() interrupt 1{TH0 = 0xDC; // 定时10msTL0 = 0x00;number++;if(number ==100){sec++;if(beep){speaker=!speaker;speaker_num--;if(speaker_num == 0){beep=0;speaker = 0;}}if(sec == 60){sec = 0;min++;if(min == 60){min = 0;hour++; //小时加1speaker_num = hour%12; //蜂鸣器响的次数beep = 1;if(hour == 24){hour = 0;calculate = 1;if(calculate == 1) //判断这个月有多少天{if(month==1|month==3|month==5|month==7|month==8|month==10|month==12){day++;if(month==7|month==12){week++;if(7 == week){week = 0;}}else{if(day <= 31){week++;if(7 == week){week = 0;}}}if(day > 31){if(month==7|month==12){day = 1;}else{day=0;}month++;if(month > 12){month=1;year++;cal_year=1;}}}if(month==4|month==6|month==9|month==11) {day++;week++;if(7 == week){week = 0;}if(day > 30){day=1;month++;if(month > 12){month=1;year++;cal_year=1;}}}if(month == 2){while(cal_year == 1){leap_year = ((year % 4 == 0 && year % 100 != 0)||(year % 400 == 0));cal_year = 0;}if(leap_year==1){day++;if(day <= 30){week++;if(7 == week){week = 0;}}if(day > 30){day=1;month++;if(month > 12){month=1;year++;cal_year=1;}}}else{day++;week++;if(7 == week){week = 0;}if(day > 29){day=1;month++;if(month > 12){month=1;year++;cal_year=1;}}}}}calculate=0;}}}}}////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Lcd1602.c子程序:////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /****************************************************************************** ***************************** lcd1602低层函数********************************************************************************************************************* *******/# include <reg52.h># include <intrins.h># include "lcd16024.h"# define LCD_DATA P0 //LCD1602的数据口定义sbit LCD_RS = P0^0; //LCD1602控制线的定义,4位控制方式sbit LCD_RW = P0^1;sbit LCD_EN = P0^2;/****************************************************************************** ***************************** 延时1MS********************************************************************************************************************* *******/void Delay1Us(uint16 n){for(;n>0;n--){_nop_();}}/****************************************************************************** ***************************** 延时1MS********************************************************************************************************************* *******/void Delay1Ms(uint16 n){while(n--){Delay1Us(1000);}}/****************************************************************************** ***************************** 延时1MS********************************************************************************************************************* *******/void LCD_en_write(void){LCD_EN=0;LCD_EN=1;Delay1Us(1);LCD_EN=0;}/****************************************************************************** ************************ LCD写一个字节命令函数************************************************************************************************************ *******/void LCD_write_command(uint8 command){Delay1Us(16);LCD_RS=0;LCD_RW=0;LCD_DATA&=0x0f;LCD_DATA|=command&0xf0;LCD_en_write();command=command<<4;LCD_DATA&=0x0f;LCD_DATA|=command&0xf0;LCD_en_write();}/****************************************************************************** ********************** LCD写一个字节数据函数*************************************************************************************************************** *******/void LCD_write_data(uint8 Data){Delay1Us(16);LCD_RS=1;LCD_RW=0;LCD_DATA&=0x0f;LCD_DATA|=Data&0xf0;LCD_en_write();Data=Data<<4;LCD_DATA&=0x0f;LCD_DATA|=Data&0xf0;LCD_en_write();}/****************************************************************************** ***************************** LCD1602光标定位函数************************************************ x--列0~15;y--行0~1********************************************************************************************************* *******/void LCD_set_xy(uint8 x,uint8 y){uint8 address;if(y==0)address=0x80+x;else address=0xc0+x;LCD_write_command(address);}/***************************************************************************************************** LCD1602 初始化函数,四位显示方式******************************************************************************************************* *******/void LCD_init(){LCD_write_command(0x28);// Delay1Us(40);LCD_write_command(0x28);LCD_write_command(0x0c);LCD_write_command(0x01);LCD_write_command(0x06);Delay1Ms(2);}/****************************************************************************** ***************************** LCD写字符串函数******************************************************* x--列0~15;y--行0~1******************************************************* s指向字符串数组**************************************************************************************************************** *******/void LCD_write_str(uint8 x,uint8 y,uint8 *s){LCD_set_xy(x,y);while(*s){LCD_write_data(*s);s++;}}/****************************************************************************** ***************************** LCD写一个字符函数******************************************************* x--列0~15;y--行0~1******************************************************* d--字符的ASCII码**************************************************************************************************************** *******/void LCD_write_char(uint8 x,uint8 y,uint8 d){LCD_set_xy(x,y);LCD_write_data(d);}/*////////////////////////////////////////////////////////////////// 等待繁忙标志/////////////////////////////////////////////////////////////////void LCD_wait(void){P0 = 0xFF;do{LCD_RS = 0;LCD_RW = 1;LCD_EN = 0;LCD_EN = 1;}while (BUSY == 1);LCD_EN = 0;}*//****************************************************************************** ***************************** LCD1602左移********************************************************************************************************************* *******void LCD_youyi(uint8 y,uint8 *s){LCD_write_str(17,y,s);for(a=0;a<16;a++){LCD_write_command(0x1c); //左移LCD_write_command(0x1c); 为右移Delay1Ms(6);}}*///LCD_write_command(0x0d);//光标闪烁//LCD_write_command(0x0e);//光标显示不闪烁//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Lcd1602.h头文件////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #ifndef _LCD16024_H_#define _LCD16024_H_typedef unsigned char uint8;typedef unsigned int uint16;typedef unsigned long uint32;void Delay1Us(uint16 n);void Delay1Ms(uint16 n);void LCD_write_data(uint8 dat);void LCD_write_command(uint8 com); //BuysC为0时忽略忙检测void LCD_set_xy(uint8 x,uint8 y);void LCD_en_write(void);void LCD_write_char(uint8 x, uint8 y, uint8 Data1);void LCD_write_str(uint8 x, uint8 y,uint8 *s);void LCD_init();//void LCD_wait(void);//void LCD_youyi(uint8 y,uint8 *s);#endif。

定时闹钟-C51单片机课程设计

定时闹钟-C51单片机课程设计

题目:定时闹钟目录一、概述 (1)1.1设计目的及意义 (1)1.2设计任务 (1)1.3设计系统的主要功能 (1)二、系统总体方案及硬件设计 (2)2.1系统总体方案 (2)2.2系统设计总框图 (2)2.3硬件设计 (2)2.3.1单片机最小系统设计 (2)2.3.2报警模块设计 (6)2.3.3显示模块设计 (7)2.3.4调时模块设计 (9)三、软件设计 (10)3.1主程序流程图 (10)3.2定时中断子程序流程图 (11)3.3程序设计 (11)四、系统的仿真与调试 (12)4.1 proteus软件仿真 (12)4.2系统的调试 (11)五、设计总结与体会 (13)参考文献 (13)附录1:源程序代码 (14)附录2:系统原理图 (24)一、概述1.1设计目的及意义学习和巩固单片机技术、电子技术、传感器技术及智能仪器等知识,使对已学过的基础知识能有更深入的理解,并融会贯通。

学会独立思考、独立工作,培养一定的自学能力和独立分析问题能力,以及增强系统地运用已学理论知识去解决实际问题的能力,同时培养成良好的科学态度和严谨的设计习惯。

1.2设计任务完成所选题目的分析与设计,达到技术性能要求。

提交正式课程设计总结报告一份。

本文设计的定时闹钟的核心模块采用AT89C51芯片,时、分、秒用6位LED数码管显示。

在电路中通过四个按键S1、S2、S3和S4来进行定时、调时和复位,定时时间到通过蜂鸣器发出报警声。

1.3设计系统的主要功能(1)能显示时时-分分-秒秒。

(2)能够设置定时时间、修改定时时间。

(3) 定时时间到能发出报警声。

二、系统总体方案及硬件设计2.1系统总体方案(1) 由于LED显示器相对于其它显示器(如LCD显示器)来说其价格要便宜许多,而且亮度更高,耐温范围较广,所以采用6位数码管来显示“时时-分分-秒秒”。

(2) 时间的定时用单片机内部时钟电路,在一定的时间内能使其误差较小,如经过一年其误差才仅有数秒。

基于51单片机的简易电子钟设计

基于51单片机的简易电子钟设计

基于51单片机的简易电子钟设计一、设计目的现代社会对于时间的要求越来越精确,电子钟成为家庭和办公场所不可缺少的设备之一、本设计基于51单片机,旨在实现一个简易的电子钟,可以显示当前的时间,并且能够通过按键进行时间的调整和设置闹钟。

二、设计原理本设计主要涉及到51单片机的IO口、定时器、中断、LCD显示技术等方面知识。

1.时钟模块时钟模块采用定时器0的中断进行时间的累加和更新。

以1秒为一个时间单位,每当定时器0中断发生,就将时间加1,并判断是否需要更新小时、分钟和秒的显示。

同时,根据用户按键的操作,可以调整时间的设定。

2.显示模块显示模块采用16x2字符LCD显示屏,通过51单片机的IO口与LCD连接。

可以显示当前时间和设置的闹钟时间。

初次上电或者重置后,LCD显示时间为00:00:00,通过定时器中断和键盘操作,实现时间的更新和设定闹钟功能。

3.键盘模块键盘模块采用矩阵键盘连接到51单片机的IO口上,用于用户进行时间的调整和设置闹钟。

通过查询键盘的按键状态,根据按键的不同操作,实现时间的调整和闹钟设定功能。

4.中断模块中断模块采用定时器0的中断,用于1秒的定时更新时间。

同时可以添加外部中断用于响应用户按键操作。

三、主要功能和实现步骤1.系统初始化。

2.设置定时器,每1秒产生一次中断。

3.初始化LCD显示屏,显示初始时间00:00:00。

4.查询键盘状态,判断是否有按键按下。

5.如果按键被按下,根据不同按键的功能进行相应的操作:-功能键:设置、调整、确认。

-数字键:根据键入的数字进行时间的调整和闹钟设定。

6.根据定时器的中断,更新时间的显示。

7.判断当前时间是否与闹钟设定时间相同,如果相同,则触发闹钟,进行提示。

8.循环执行步骤4-7,实现连续的时间显示和按键操作。

四、系统总结和改进使用51单片机设计的简易电子钟可以显示当前时间,并且实现时间的调整和闹钟设定功能。

但是由于硬件资源有限,只能实现基本的功能,不能进行其他高级功能的扩展,例如闹铃的音乐播放、温度、湿度的显示等。

基于C51单片机的数字时钟课程设计(C语言带闹钟)

基于C51单片机的数字时钟课程设计(C语言带闹钟)

单片机技术课程设计数字电子钟学院:班级:姓名:学号:教师:摘要电子钟在生活中应用非常广泛,而一种简单方便的数字电子钟则更能受到人们的欢迎。

所以设计一个简易数字电子钟很有必要。

本电子钟采用AT89C52单片机为核心,使用12MHz 晶振与单片机AT89C52 相连接,通过软件编程的方法实现以24小时为一个周期,同时8位7段LED数码管(两个四位一体数码管)显示小时、分钟和秒的要求,并在计时过程中具有定时功能,当时间到达提前定好的时间进行蜂鸣报时。

该电子钟设有四个按键KEY1、KEY2、KEY3、KEY4和KEY5键,进行相应的操作就可实现校时、定时、复位功能。

具有时间显示、整点报时、校正等功能。

走时准确、显示直观、运行稳定等优点。

具有极高的推广应用价值。

关键词:电子钟 AT89C52 硬件设计软件设计目录NO TABLE OF CONTENTS ENTRIES FOUND.一、数字电子钟设计任务、功能要求说明及方案介绍1.1 设计课题设计任务设计一个具有特定功能的电子钟。

具有时间显示,并有时间设定,时间调整功能。

1.2 设计课题的功能要求说明设计一个具有特定功能的电子钟。

该电子钟上电或按键复位后能自动显示系统提示符“d.1004-22”,进入时钟准备状态;第一次按电子钟启动/调整键,电子钟从12时59分0秒开始运行,进入时钟运行状态;按电子钟S5键,则电子钟进入时钟调整状态,此时可利用各调整键调整时间,调整结束后可按S5键再次进入时钟运行状态。

1.3 设计课的设计总体方案介绍及工作原理说明本电子钟主要由单片机、键盘、显示接口电路和复位电路构成,设计课题的总体方案如图1所示:图1-1总体设计方案图本电子钟的所有的软件、参数均存放在AT89C52的Flash ROM和内部RAM 中,减少了芯片的使用数量简化了整体电路也降低了整机的工作电流。

键盘采用动态扫描方式。

利用单片机定时器及计数器产生定时效果通过编程形成数字钟效果,再利用数码管动态扫描显示单片机内部处理的数据,同时通过端口读入当前外部控制状态来改变程序的不同状态,实现不同功能。

C51单片机实验报告

C51单片机实验报告

C51单片机实验报告
一、实验内容
本次实验的目的是实现用C51单片机实现简易的闹钟功能:即用户可以设置闹钟时间,当到达闹钟的设定时间的时候,单片机会控制LED灯或者蜂鸣器发出报警信号来提醒用户。

二、实验任务
本次实验任务如下:
1.使用C51单片机读取外部时钟的时间。

2.实现从按键输入闹钟设定的时间。

3.使用定时器实现任务调度,即在每个时刻检查一次外部时钟的时间是否到达闹钟的设定时间,如果到达设定时间,则控制LED灯或者蜂鸣器发出报警信号。

三、实验过程
1.硬件部分:本实验使用的硬件是硬件C51单片机,它具有单片机主频11.059MHz,外部内存2K和内部RAM 128字节。

本次实验采用的C51单片机核心是AT89C51,它具有4K字节的Flash存储器,它有128个8位I/O口和3个定时器/计数器。

本次实验使用到的外设有:LCD1602显示模块、4个4*4的数字键盘、AT24C02的IIC从机存储器、LED灯和蜂鸣器。

2.软件部分:本次实验使用的软件工具是Keil C51编译器,使用它来编写C51单片机程序。

基于at89c51单片机的定时闹钟的设计

基于at89c51单片机的定时闹钟的设计

基于at89c51单片机的定时闹钟的设计本文介绍了基于AT89C51单片机的定时闹钟的设计。

文章将探讨设计目的和背景,并着重阐述定时闹钟的实现原理和功能。

本文档将介绍基于at89c51单片机的定时闹钟的硬件设计要点,包括电源、显示器、按键等组件选择和连接方式。

电源选择与连接在设计定时闹钟的硬件方案时,选择合适的电源是非常重要的。

以下是一些电源选择和连接的要点:使用稳定可靠的电源模块,例如直流电源模块,以确保单片机工作的稳定性。

将电源模块的正负极连接到at89c51单片机的VCC和GND引脚上。

注意电源的电压和电流要符合at89c51单片机的工作要求。

显示器选择与连接显示器是定时闹钟中显示时间和其他信息的重要组件。

以下是一些显示器选择和连接的要点:考虑使用液晶显示器 (LCD) 或数码管作为显示器,这些显示器可以清晰地显示数字和字符。

根据设计需求,选择合适的显示器尺寸和类型。

将显示器的控制引脚与at89c51单片机的相应引脚连接,以实现时间和信息的显示。

按键选择与连接按键是控制定时闹钟设置和功能的重要组件。

以下是一些按键选择和连接的要点:选择合适的按键类型,例如触摸按键或机械按键。

根据设计需求,确定所需的按键数量和布局。

将按键的引脚连接到at89c51单片机的GPIO引脚,以接收按键输入并实现相应的功能。

上述是基于at89c51单片机的定时闹钟的硬件设计要点,通过合理选择和连接电源、显示器和按键等组件,可以确保定时闹钟的稳定运行和正常功能。

本文将阐述基于at89c51单片机的定时闹钟的软件设计要点,包括如下内容:定时器的设置:使用at89c51单片机的定时器来实现定时功能,可以通过对定时器寄存器的设置来调整定时的时间间隔。

中断处理:在定时器到达设定的时间间隔时,通过中断处理来触发相应的操作。

可以通过设定中断优先级来确保定时器中断的可靠性。

闹钟功能的实现:通过软件算法和控制电路,将定时器和中断处理结合起来实现闹钟功能。

基于c51的电子钟设计

基于c51的电子钟设计

电子时钟设计一、设计目的在我们现代日常生活中,电子时钟已得到及其广泛的应用,已成为我们日常生活中的不可或缺的一部分。

本次设计的主要目的即是利用51单片机设计一个可实现24小时计时的电子时钟,计时从0时0分0秒开始,到23小时59分59秒后返回0时0分0秒自动重新开始计时。

本设计拥有时间调整功能和时间显示功能,无年、月计数和闹钟功能。

二、需求分析本设计中的时钟要求使用8个8段数码管显示当前时间,其中秒单元与分单元中间以“-”符号隔开,分单元与时单元中间同样以“-”符号隔开。

计时范围为从00-00-00到23-59-59,当计时到23-59-59后自动返回00-00-00并重新开始计时。

设计中使用3个按键分为set、add和sub,当在计时功能工作时按下set键即可进入调时模式,在调试模式下累计按6次set后便退出调时功能,重新返回计时功能。

三、总体设计1、总体设计框图图3-1 总体设计框图2、器件选型:主要使用的器件为STC89C51RC型单片机。

该型号的单片机有P1、P2、P3、P4共4个准双向口,且包含3个16位可编程定时/计数器T0、T1、T2。

其定时可由硬件电路与中断方式控制,而定时时间和范围则完全由所编写的代码来确定和改变。

在本次设计中主要实用0号和1号定时/计数器,通过设置使它们均实现50ms计数,其中0号计数器配合20次循环计数以实现1m计时,1号计数器配合10次循环计数以实现对相应调整位的0.5m闪烁。

设计中还主要使用到3个74LS373数据锁存器、1个74LS244输入缓冲器以及8个8段数码显示器。

四、硬件设计1、硬件框图图4-1 硬件框图2、硬件模块设计a、时间计时模块设计:该模块的功能实现是将十位时、个位时、十位分、个位分、十位秒和个位秒分别存入s_hou、g_hou、s_min、g_min、s_sec和g_sec中,每个数值对应一个无符号字节。

T0计数器实现计数功能,但计数满20次50ms即1000ms时,g_sec 的值加1,当g_sec计数值为10时将g_sec清零并使s_sec计数加1,以此类推,直到计数值为23-59-59,并在下一秒返回00-00-00。

51单片机设置的电子闹钟(可调时间和闹钟)

51单片机设置的电子闹钟(可调时间和闹钟)

#include<reg52.h>#define uint unsigned int#define uchar unsigned char#define LED P0 // 数码管的段选#define LIGHT P1 // 时分秒位的指示灯#define WS P2 // 数码管的位选sbit key1=P3^0; // 时间暂停/开始sbit key2=P3^1; // 时间/闹钟设置sbit key3=P3^2; // 增加sbit key4=P3^3; // 减少sbit alarm=P3^6; // 闹铃uchar tab[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; // 0-9 uchar tab_dp[10]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef}; // 0.-9.(带小数点)uchar data1[]={0,0,0,0,0,0};uchar data2[]={0,0,0,0,0,0};uint t,k,kk,k1,flag;uint bbh,bbm,bbs,bbh1,bbm1,bbs1;uint sec,min,hour,sec1,min1,hour1; // 定义秒,分,时void init();void display();void display_bb();void delay( uint );void keyscan();void main(){init();while(1){keyscan();if(k1==0||k1==1||k1==2||k1==3) // 显示调节时间{display();}if(k1==4||k1==5||k1==6) // 显示调节闹钟{display_bb();}if((bbh==hour)&&(bbm==min)&&data1[4]==0&&data1[5]==5) // 5s报时{alarm=~alarm;delay(1);}if((bbs==sec)&&(bbm==min)&&(bbh==hour)) // 可调报时{alarm=~alarm;delay(1);}}}void init(){WS=LIGHT=flag=0;sec=min=hour=0; // 将0赋给时分秒TMOD=0x01; // 方式1 P129(见课本)TH0=0x3c; // 65536-50000=15536=0x3cb0(50ms) P128(见课本)TL0=0xb0;EA=1; // 开总中断 P161(见课本)TR0=1; // 定时/计数器0开启ET0=1; // 定时器/计数器0溢出中断启动 P161(见课本)}void delay( unsigned int t) // 延时函数{unsigned int i;while(t--)for(i=0;i<125;i++);}void display() // 显示时间函数{if(TF0==1) // 定时器/计数器溢出 P130(见课本){TF0=0; // 清中断标志位t++;if(t==20) // (50ms*20=1s){t=0;sec++; // 秒加1if(sec==60) // 秒为60,则清零,分加1 {sec=0;min++;}if(min==60) // 分为60,则清零,时加1{min=0;hour++;}if(hour==24)// 时为24,则清零{hour=0;}}}data1[5]=sec%10;data1[4]=sec/10;data1[3]=min%10;data1[2]=min/10;data1[1]=hour%10;data1[0]=hour/10;WS=0xdf; // 1101 1111 ,低电平显示LED=tab[data1[5]];delay(1);WS=0xef; // 1110 1111LED=tab[data1[4]];delay(1);WS=0xf7; // 1111 0111LED=tab_dp[data1[3]];delay(1);WS=0xfb; // 1111 1011LED=tab[data1[2]];delay(1);WS=0xfd; // 1111 1101LED=tab_dp[data1[1]];delay(1);WS=0xfe; // 1111 1110LED=tab[data1[0]];delay(1);}void display_bb() // 显示闹钟函数{data2[5]=bbs%10;data2[4]=bbs/10;data2[3]=bbm%10;data2[2]=bbm/10;data2[1]=bbh%10;data2[0]=bbh/10;WS=0xdf; // 1101 1111 ,低电平显示LED=tab[data2[5]];delay(1);WS=0xef; // 1110 1111LED=tab[data2[4]];delay(1);WS=0xf7; // 1111 0111LED=tab_dp[data2[3]];delay(1);WS=0xfb; // 1111 1011LED=tab[data2[2]];delay(1);WS=0xfd; // 1111 1101LED=tab_dp[data2[1]];delay(1);WS=0xfe; // 1111 1110LED=tab[data2[0]];delay(1);}void keyscan() // 键盘扫描{if(key1==0) // 暂停/开始{++kk;while(!key1){display();if(kk==1){TR0=0;if(k1==0||k1==1||k1==2||k1==3) // 显示调节时间{display();}if(k1==4||k1==5||k1==6) // 显示调节闹钟{display_bb();}if(key2==0) // 模式选择(调节时间/闹钟){k1++;while(!key2){if(k1==1) // 第1次按下{sec1=sec; // 保存秒的数值sec=88; // 显示88,表示可以调节秒的数值了display(); // 显示88sec=sec1; // 恢复前一刻秒的数值}if(k1==2){min1=min;min=88;display();delay(1);min=min1;}if(k1==3){hour1=hour;hour=88;display();delay(1);hour=hour1;}if(k1==4){sec1=bbs; // 保存秒的数值bbs=66; // 显示66,表示可以调节秒的数值了display_bb(); // 显示66bbs=sec1; // 恢复前一刻秒的数值}if(k1==5){min1=bbm;bbm=66;display_bb();delay(10);bbm=min1;}if(k1==6){hour1=bbh;bbh=66;display_bb();delay(10);bbh=hour1;}if(k1==7){k1=0;display();}}}if(key3==0) // 时间/闹钟增加设置{while(!key3){if(k1==1){sec++; // 秒加1delay(60);if(sec==60)sec=0;display();}if(k1==2){min++;delay(60);if(min==60)min=0;display();}if(k1==3){hour++;delay(60);if(hour==24)hour=0;display();}if(k1==4){bbs++; // 秒加1delay(60);if(bbs==60)bbs=0;display_bb();}if(k1==5){bbm++;delay(60);if(bbm==60)bbm=0;display_bb();}if(k1==6){bbh++;delay(60);if(bbh==24)display_bb();}if(k1==7){k1=0;display();}}}if(key4==0) // 时间/闹钟减少设置 {while(!key4){if(k1==1){sec--; // 秒加1delay(60);if(sec==0)sec=60;display();}if(k1==2){min--;delay(60);if(min==0)min=60;display();}if(k1==3){hour--;delay(60);if(hour==0)hour=24;display();}if(k1==4){bbs--; // 秒减1delay(60);if(bbs==0)display_bb();}if(k1==5){bbm--;delay(60);if(bbm==0)bbm=60;display_bb();}if(k1==6){bbh--;delay(60);if(bbh==0)bbh=24;display_bb();}if(k1==7){k1=0;display();}}}}}if(kk==2){kk=0;k1=0;TR0=1;}}}。

基于C51的电子钟设计

基于C51的电子钟设计

基于AT89C51单片机的电子钟设计1 系统电路设计1.1 系统总体设计思路此设计原理框图如下所示,电路包括四个部分:单片机,键盘,锁存及显示电路,掉电保护电路。

图1.1 单片机实现数码管显示电子钟总框图对于各部分:(1)单片机发送的信号经过锁存电路最终在数码管上显示出来。

(2)单片机通过输出各种电脉冲信号来驱动控制各部分正常工作。

(3)掉电保护电路保证系统掉电时时钟不会停止。

(4)为使时钟走时与标准时间一致,校时电路是必不可少的,键盘用来校正数码管上显示的时间。

1.2 工作原理设计的电路主要由四大模块构成:掉电保护电路,单片机控制电路,显示电路以及校正电路。

本设计采用C语言程序设计,使单片机控制数码管显示年、月、日、时、分、秒,当秒计数计满60时就向分进位,分计数器计满60后向时计数器进位,小时计数器按“23翻0”规律计数。

时、分、秒的计数结果经过数据处理可直接送显示器显示。

当计时发生误差的时候可以用校时电路进行校正。

时计数器计满24小时后自动向日计数器进一,日计数器需判断平年、闰年和大月、小月,当日计数器计满时,向月计数器进位,月计数器计满12月向年计数器进位。

设计采用的是年、月、日、时、分、秒显示,单片机对数据进行处理同时在数码管上显示。

2 单元电路设计2.1 单片机电路设计本设计采用AT89C52单片机进行设计,它是一种低功耗,高性能的CMOS8位微处理器,内部有8K字节的程序存储器和256字节的数据存储单元,32个I/O 端口,3个16位定时/计数器,8个中断源。

时钟电路是单片机系统的心脏,它控制着单片机的工作节奏。

本设计采用内部时钟方式,12MHz的石英晶体振荡器。

电路图如下图2.1 时钟电路复位电路由单片机引脚RST接入,只要RST端保持10ms以上的高电平,就能使单片机有效地复位,本设计采用上电复位和手动复位两种方式。

电路图如下图2.2 复位电路2.2 掉电保护电路设计本设计采用如下掉电保护电路,当电源供电正常时,一方面给单片机供电,另一方面给电池充电,当电源断电时,电池放电,继续给单片机供电,保证其正常工作。

基于C51单片机的数字时钟课程设计(C语言带闹钟)

基于C51单片机的数字时钟课程设计(C语言带闹钟)

单片机技术课程设计数字电子钟学院:班级:姓名:学号:教师:摘要电子钟在生活中应用非常广泛,而一种简单方便的数字电子钟则更能受到人们的欢迎。

所以设计一个简易数字电子钟很有必要。

本电子钟采用AT89C52单片机为核心,使用12MHz 晶振与单片机AT89C52 相连接,通过软件编程的方法实现以24小时为一个周期,同时8位7段LED数码管(两个四位一体数码管)显示小时、分钟和秒的要求,并在计时过程中具有定时功能,当时间到达提前定好的时间进行蜂鸣报时。

该电子钟设有四个按键KEY1、KEY2、KEY3、KEY4和KEY5键,进行相应的操作就可实现校时、定时、复位功能。

具有时间显示、整点报时、校正等功能。

走时准确、显示直观、运行稳定等优点。

具有极高的推广应用价值。

关键词:电子钟 AT89C52 硬件设计软件设计目录NO TABLE OF CONTENTS ENTRIES FOUND.一、数字电子钟设计任务、功能要求说明及方案介绍1.1 设计课题设计任务设计一个具有特定功能的电子钟。

具有时间显示,并有时间设定,时间调整功能。

1.2 设计课题的功能要求说明设计一个具有特定功能的电子钟。

该电子钟上电或按键复位后能自动显示系统提示符“d.1004-22”,进入时钟准备状态;第一次按电子钟启动/调整键,电子钟从12时59分0秒开始运行,进入时钟运行状态;按电子钟S5键,则电子钟进入时钟调整状态,此时可利用各调整键调整时间,调整结束后可按S5键再次进入时钟运行状态。

1.3 设计课的设计总体方案介绍及工作原理说明本电子钟主要由单片机、键盘、显示接口电路和复位电路构成,设计课题的总体方案如图1所示:图1-1总体设计方案图本电子钟的所有的软件、参数均存放在AT89C52的Flash ROM和内部RAM 中,减少了芯片的使用数量简化了整体电路也降低了整机的工作电流。

键盘采用动态扫描方式。

利用单片机定时器及计数器产生定时效果通过编程形成数字钟效果,再利用数码管动态扫描显示单片机内部处理的数据,同时通过端口读入当前外部控制状态来改变程序的不同状态,实现不同功能。

51单片机设置的电子闹钟(可调时间和闹钟)

51单片机设置的电子闹钟(可调时间和闹钟)

#include<reg52.h>#define uint unsigned int#define uchar unsigned char#define LED P0 // 数码管的段选#define LIGHT P1 // 时分秒位的指示灯#define WS P2 // 数码管的位选sbit key1=P3^0; // 时间暂停/开始sbit key2=P3^1; // 时间/闹钟设置sbit key3=P3^2; // 增加sbit key4=P3^3; // 减少sbit alarm=P3^6; // 闹铃uchar tab[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; // 0-9uchar tab_dp[10]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef}; // 0.-9.(带小数点)uchar data1[]={0,0,0,0,0,0};uchar data2[]={0,0,0,0,0,0};uint t,k,kk,k1,flag;uint bbh,bbm,bbs,bbh1,bbm1,bbs1;uint sec,min,hour,sec1,min1,hour1; // 定义秒,分,时void init();void display();void display_bb();void delay( uint );void keyscan();void main(){init();while(1){keyscan();if(k1==0||k1==1||k1==2||k1==3) // 显示调节时间{display();}if(k1==4||k1==5||k1==6) // 显示调节闹钟{display_bb();}if((bbh==hour)&&(bbm==min)&&data1[4]==0&&data1[5]==5) // 5s报时{alarm=~alarm;delay(1);}if((bbs==sec)&&(bbm==min)&&(bbh==hour)) // 可调报时{alarm=~alarm;delay(1);}}}void init(){WS=LIGHT=flag=0;sec=min=hour=0; // 将0赋给时分秒TMOD=0x01; // 方式1 P129(见课本)TH0=0x3c; // 65536-50000=15536=0x3cb0(50ms) P128(见课本)TL0=0xb0;EA=1; // 开总中断P161(见课本)TR0=1; // 定时/计数器0开启ET0=1; // 定时器/计数器0溢出中断启动P161(见课本)}void delay( unsigned int t) // 延时函数{unsigned int i;while(t--)for(i=0;i<125;i++);}void display() // 显示时间函数{if(TF0==1) // 定时器/计数器溢出P130(见课本){TF0=0; // 清中断标志位t++;if(t==20) // (50ms*20=1s){t=0;sec++; // 秒加1if(sec==60) // 秒为60,则清零,分加1{sec=0;min++;}if(min==60) // 分为60,则清零,时加1{min=0;hour++;}if(hour==24)// 时为24,则清零{hour=0;}}}data1[5]=sec%10;data1[4]=sec/10;data1[3]=min%10;data1[2]=min/10;data1[1]=hour%10;data1[0]=hour/10;WS=0xdf; // 1101 1111 ,低电平显示LED=tab[data1[5]];delay(1);WS=0xef; // 1110 1111LED=tab[data1[4]];delay(1);WS=0xf7; // 1111 0111LED=tab_dp[data1[3]];delay(1);WS=0xfb; // 1111 1011LED=tab[data1[2]];delay(1);WS=0xfd; // 1111 1101LED=tab_dp[data1[1]];delay(1);WS=0xfe; // 1111 1110LED=tab[data1[0]];delay(1);}void display_bb() // 显示闹钟函数{data2[5]=bbs%10;data2[4]=bbs/10;data2[3]=bbm%10;data2[2]=bbm/10;data2[1]=bbh%10;data2[0]=bbh/10;WS=0xdf; // 1101 1111 ,低电平显示LED=tab[data2[5]];delay(1);WS=0xef; // 1110 1111LED=tab[data2[4]];delay(1);WS=0xf7; // 1111 0111LED=tab_dp[data2[3]];delay(1);WS=0xfb; // 1111 1011LED=tab[data2[2]];delay(1);WS=0xfd; // 1111 1101LED=tab_dp[data2[1]];delay(1);WS=0xfe; // 1111 1110LED=tab[data2[0]];delay(1);}void keyscan() // 键盘扫描{if(key1==0) // 暂停/开始{++kk;while(!key1){display();if(kk==1){TR0=0;if(k1==0||k1==1||k1==2||k1==3) // 显示调节时间{display();}if(k1==4||k1==5||k1==6) // 显示调节闹钟{display_bb();}if(key2==0) // 模式选择(调节时间/闹钟){k1++;while(!key2){if(k1==1) // 第1次按下{sec1=sec; // 保存秒的数值sec=88; // 显示88,表示可以调节秒的数值了display(); // 显示88sec=sec1; // 恢复前一刻秒的数值}if(k1==2){min1=min;min=88;display();delay(1);min=min1;}if(k1==3){hour1=hour;hour=88;delay(1);hour=hour1;}if(k1==4){sec1=bbs; // 保存秒的数值bbs=66; // 显示66,表示可以调节秒的数值了display_bb(); // 显示66bbs=sec1; // 恢复前一刻秒的数值}if(k1==5){min1=bbm;bbm=66;display_bb();delay(10);bbm=min1;}if(k1==6){hour1=bbh;bbh=66;display_bb();delay(10);bbh=hour1;}if(k1==7){k1=0;display();}}}if(key3==0) // 时间/闹钟增加设置{while(!key3){if(k1==1){sec++;// 秒加1if(sec==60)sec=0;display();}if(k1==2){min++;delay(60);if(min==60)min=0;display();}if(k1==3){hour++;delay(60);if(hour==24)hour=0;display();}if(k1==4){bbs++; // 秒加1delay(60);if(bbs==60)bbs=0;display_bb();}if(k1==5){bbm++;delay(60);if(bbm==60)bbm=0;display_bb();}if(k1==6){bbh++;delay(60);if(bbh==24)bbh=0;display_bb();if(k1==7){k1=0;display();}}}if(key4==0) // 时间/闹钟减少设置{while(!key4){if(k1==1){sec--; // 秒加1delay(60);if(sec==0)sec=60;display();}if(k1==2){min--;delay(60);if(min==0)min=60;display();}if(k1==3){hour--;delay(60);if(hour==0)hour=24;display();}if(k1==4){bbs--; // 秒减1delay(60);if(bbs==0)bbs=60;display_bb();if(k1==5){bbm--;delay(60);if(bbm==0)bbm=60;display_bb();}if(k1==6){bbh--;delay(60);if(bbh==0)bbh=24;display_bb();}if(k1==7){k1=0;display();}}}}}if(kk==2){kk=0;k1=0;TR0=1;}}}。

C51单片机实现电子闹钟

C51单片机实现电子闹钟
先进行系统得整体规划确定整个系统得功能,然后按照每个功能得具体要求,进行各个模块得实物设计并逐个调试,待全部通过后,进行整个系统得联调,最终实现一个完整得系统。
整个系统得设计步骤如下:
在单片机最小系统得基础上,完成按键电路与复位电路得设计.
完成显示电路、数字按键、单片机时钟电路。
Ⅰ硬件设计
系统硬件得设计可以根据系统得各个功能,把整个系统划分成若干个模块,分别对这些模块来进行设计,然后在通过单片机程序来实现对各个硬件模块功能得调度。
数码管主要包括位选与段选信号线。位选就是用来选通数码管得,只有位选信号有效该数码管才会亮并显示要现实得数字;段选就是选择数码管7段得那一笔亮,从而显示不同得数字。
本设计中单片机P0口输出段选数据,P3口输出位选数据.
数码管与单片机相连得电路如下图所示:
电路中使用了芯片74ls245,该芯片用来驱动LED。其片选引脚要接地,使其一致为低电平,芯片一直可以工作。
1)输入数字按键得功能.
保证数字得输入。
2)复位电路得功能.
所有时间回到初始化状态,用于启动设定时间参数(调时或设定闹钟时间);
3)显示电路得功能。
当输入数字时显示24小时时间功能。
4)闹铃功能
设置闹铃得时间后、能按设置好得时间准时闹铃.
二、系统方案得设计要求
根据以上各模块并结合显示屏得功能及元器件材料得情况,决定采用AT89C51为内核显示设计方案.
本题画出得虽然就是独立按键,但就是内部驱动依然就是行列式按键得驱动,这里只就是为了画图方便。
(4)复位电路
当按下复位键时单片机进入复位状态,可以进行时间得设置等。
电路图如下所示:
四、系统软件部分得设计
本设计得软件系统用来配合硬件电路实现特定得功能。程序主要包含键盘扫描模块、时间处理模块、与数码管显示程序3大部分.

毕设-基于C51单片机的电子时钟的设计

毕设-基于C51单片机的电子时钟的设计

3.3 时钟电路
• DS12C887时钟芯片能
自动产生世纪、年、月
、日、星期、时、分、 秒等时间信息,具有闰
年补偿。
• DS12C887中自带锂电 池,外部掉电时,其内 部信息还能保持十年之 久。
3.4 液晶1602显示电路
• 本次设计将LCD1602芯片的 AD0~AD07与单片机的P0 口相连,由于P0口没有上拉 电阻固外接上拉电阻。
• 本设计的硬件电路主要是采用了专用的时钟芯片
DS12C887,其内部自带锂电池,一旦设置好时间,即使 系统的主电源掉电,该时钟芯片仍然可以靠它内部集成的 锂电池走数年,当系统重新上电时,又可为锂电池重新充 电,这样一来可以非常有效地保持时间的连续性,使用非 常方便。同时本设计的显示电路采用了LCD1602液晶显示 ,与传统的数码管显示电路相比,电路连接简单了很多。 同时本系统主要通过80C51单片机来进行控制,具有可调 性,通过按键来调节时间,并带有闹钟功能,闹铃时发出 铃声。
主程序流程图
开始
初始化
是否闹钟 N
Y
响铃
Y
是否有按键按下
N
时间显示
按键检测设计流程图
开始
时间显示
本次设
计就是以延
时函数为主 来消除抖动。
按键是否按下
N
Y
检测哪个按键按下
复 位 键
闹 钟 键
调 大 键
调 小 键
功能 选择 键
5 仿真与调试
• 图
6 总结
• 单片机是一种集成电路芯片,是采用超大规模集成电路技术 把具有数据处理能力的中央处理器CPU随机存储器RAM、只 读存储器ROM、多种I/O口和中断系统、定时器/计时器等功

51单片机电子时钟(C语言)

51单片机电子时钟(C语言)

#include <reg51.h>#include <intrins.h>#define uchar unsigned char //宏定义#define uint unsigned intuchar sec,min,hour,sec50,jishu,dtp2; //sec、min、hour、为显示单元,sec50为60秒计数单元,jishu为扫描数码管计数单元uchar sec1,min1,hour1; //时间中介单元uchar nzmin,nzhour,nzjishu=0,dispjishu=0; //闹钟分、时定义uchar data nzbit=0; //闹钟标志位,闹钟默认为开启uchar data dispbit=0; //显示标志位,默认显示当前时间uchar data disp[8]; //秒、分、时个位与十位存放数组及‘—’uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //数字0-9sbit KEYmin=P3^2; //分加1按钮sbit KEYhour=P3^3; //时加1按钮sbit LABA=P1^0; //闹钟输出I/O口sbit NZdisplay=P3^4; //闹钟显示按钮,按住不放显示闹钟时间,放开则显示当前时间sbit KEYnzmin=P3^5; //闹钟分加1按钮sbit KEYnzhour=P3^6; //闹钟时加1按钮sbit KEYoff=P3^7; //关闭闹钟按钮,按第一次为关闭,第二次为开启void display(); //显示函数声明void keyscan(); //按键扫描函数声明void naozhong(); //闹钟判别函数声明void keynz(); //闹钟按键函数声明void main(){sec=0; //时间初始化为00—00—00min=0;hour=0;sec1=0; //显示单元初始化为00—00—00min1=0;hour1=0;nzmin=01; //闹钟初始时间为01:01nzhour=01;jishu=0;dtp2=0xfe;P0=0xff;TMOD=0x11; //设T0、T1为模式1IE=0x8a;TH0=0xb8; //T0定时20msTL0=0x0;TH1=0xfc; //T1定时1msTL1=0x66;TR0=1;TR1=1;while(1){display(); //调用显示子程序keyscan(); //调用按键子程序keynz(); //调用闹钟按键子程序}}void t0int() interrupt 1 //T0定时中断程序{TH0=0xb8;TL0=0x0;sec50++;if(sec50==50) //对20ms计数50次即1s{sec50=0; //清秒计数器,为下次做准备naozhong(); //调用闹钟判别子程序sec1++; //秒加1}if(sec1==60) //对秒计数60次即1min{sec1=0;min1++; //分加1}if(min1==60) //对分计数60次即1hour{min1=0;hour1++; //时加1}if(hour1==24){hour1=0;}if(dispbit==0) //判断显示标志位是否为0,为0显示当前时间{sec=sec1;min=min1;hour=hour1;}else //显示标志位为1,显示闹钟时间{min=nzmin; //将闹钟时间给显示单元hour=nzhour;}}void t1int() interrupt 3 //T1中断程序{TH1=0xfc;TL1=0x66;P2=0xff; //关闭所有数码管P2=dtp2;dtp2=_crol_(dtp2,1);P0=disp[jishu];jishu++;if(jishu==8) //扫描完8位数码管清0,重新从第一位开始扫描{jishu=0;}}void delay(uint x) //延时函数uchar i;while(x--){for(i=0;i<120;i++);}}void display() //显示子程序{disp[7]=table[sec%10]; //秒个位显示disp[6]=table[sec/10]; //秒十位显示disp[4]=table[min%10]; //分个位显示disp[3]=table[min/10]; //分十位显示disp[1]=table[hour%10]; //时个位显示disp[0]=table[hour/10]; //时十位显示disp[2]=0xbf; //显示‘_’disp[5]=0xbf;}void keyscan() //按键子程序{delay(20); //延时消抖if(KEYmin==0)//时间分加1按钮{min1++; //时间分加1if(min1==60){min1=0;hour1++; //分加到60对时加1}if(hour1==24){hour1=0;}while(!KEYmin); //等待按键放开}delay(20); //延时消抖if(KEYhour==0) //时间时加1按钮{hour1++; //时间时加1if(hour1==24){hour1=0;}while(!KEYhour); //等待按键放开}void naozhong() //闹钟判断{if(nzbit==0) //判断闹钟标志位,0为开启闹钟判断,1为关闭闹钟{if(min1==nzmin) //闹钟与时间分的判别if(hour1==nzhour) //闹钟与时间时的判别LABA=0; //时间分、时与闹钟分、时相等就打开蜂鸣器}elseLABA=1;}void keynz() //闹钟加、减及闹钟关闭、开启按键处理子程序{delay(20); //延时消抖if(KEYnzmin==0) //判别闹钟分加1按键{nzmin++; //闹钟分加1if(nzmin==60){nzmin=0;nzhour++; //闹钟分加到60对闹钟时加1if(nzhour==24)nzhour=0;}while(!KEYnzmin); //等待按键放开}delay(20); //延时消抖if(KEYnzhour==0) //判别闹钟时加1按键{nzhour++; //闹钟时加1if(nzhour==24)nzhour=0;while(!KEYnzhour); //等待按键放开}if(KEYoff==0)//判断关闭闹钟按键是否按下{delay(20); // 延时消抖nzjishu++;if(nzjishu==1) //判断是否为第一次按下{nzbit=1; //第一次按下关闭闹钟if(nzjishu==2) //判断是否为第二次按下{nzjishu=0; //第二次按下清计数单元nzbit=0; // 第二次按下开启闹钟判别}while(!KEYoff); //等待按键放开}if(NZdisplay==0) //判别显示切换闹钟按键是否按下{dispjishu++;if(dispjishu==1) //第一次按下显示闹钟时间{dispbit=1; //第一次按下,把标志位置1,显示切换为闹钟时间}if(dispjishu==2) //第二次按下显示为当前时间{dispjishu=0; //清零,重新计数dispbit=0; //第二次按下清零显示标志位,显示切换为当前时间}while(!NZdisplay); //等待按键放开}}。

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

课程名称:单片机原理与接口技术实践设计课题:基于MCS 51单片机实现电子闹钟功能的设计学院:电子与信息工程学院专业:通信工程小组成员:电子闹钟在科学技术高度发展的今天,千家万户都少不了它,所以很多家庭个人都需要有一个电子闹钟,为人们提供报时方便,但普通电子闹钟不够方便实用。

本文给出了一种基于MCS51单片机实现电子闹钟功能的设计方法,从而给人们带来更为方便的工作与生活。

一.电子闹钟简介我们设计的电子闹钟是以MCS 51单片机中的计时器作为时钟,用8位数码管显示当前时间,并且可以设置闹钟时间,并在设置的时间点发出闹铃。

简易闹钟具有以下功能:1.时钟能准确地走时,并可以通过数码管进行显示2.复位后可以进行当前时间的设置3.可以随意设置闹钟时间,闹钟会在设置时间响铃整个系统的任务要求:1)输入数字按键的功能。

保证数字的输入。

2)复位电路的功能。

所有时间回到初始化状态,用于启动设定时间参数(调时或设定闹钟时间);3)显示电路的功能。

当输入数字时显示24小时时间功能。

4)闹铃功能设置闹铃的时间后.能按设置好的时间准时闹铃。

二.系统方案的设计要求根据以上各模块并结合显示屏的功能及元器件材料的情况,决定采用AT89C51为核显示设计方案。

先进行系统的整体规划确定整个系统的功能,然后按照每个功能的具体要求,进行各个模块的实物设计并逐个调试,待全部通过后,进行整个系统的联调,最终实现一个完整的系统。

整个系统的设计步骤如下:在单片机最小系统的基础上,完成按键电路和复位电路的设计。

完成显示电路、数字按键、单片机时钟电路。

Ⅰ硬件设计系统硬件的设计可以根据系统的各个功能,把整个系统划分成若干个模块,分别对这些模块来进行设计,然后在通过单片机程序来实现对各个硬件模块功能的调度。

本系统涉及到的硬件模块有:按键电路、数码管显示电路、单片机时钟电路、蜂鸣器电路。

各部分实现功能如下:按键电路:提供按键信号。

单片机时钟电路、复位电路:提供部时钟。

数码管驱动显示电路:显示当前时间。

蜂鸣器电路:闹钟报时。

Ⅱ软件设计本系统的软件部分主要完成功能:时分秒的进位算法处理、数码管的时间显示、时间调整设置、闹钟功能。

根据软件的功能划分软件设计模块结构,如下所示其中各个模块具体任务如下:按键驱动模块:对各个按键的功能进行相关的定义。

LED驱动模块:根据系统需要显示相应的数字时间;时间处理模块:时、分、秒的进位算法处理三.系统硬件电路的设计1根据确定的硬件方案设计硬件框图,如下图所示:2系统原理图的设计系统总的硬件电路如下图所示实际要用到5个按键,受空间限制仿真电路中只画出4个。

单 片 机蜂鸣器电路晶振电路复位电路按键电路数码管驱动及显示单片机管脚资源分配:P0口为数码管段选信号输出口。

P3口为数码管位选信号输出口。

P1.0、P1.1、P1.2、P1.3、P1.4为键盘的输入信号。

P3.6为蜂鸣器信号的输出口。

下面分别介绍各个电路。

(1)数码管驱动及显示电路本设计采用8位7段共阳极数码管用来显示时间。

为了将时间在LED数码管上显示可采用动态显示法。

通过对每位数码管的依次扫描,使对应数码管亮;同时向该数码管送对应的字码使其显示数字。

由于数码管扫描周期很短,而且人眼有视觉暂留效应,所以数码管看起来总是亮的从而实现了数字的同时显示。

数码管主要包括位选和段选信号线。

位选是用来选通数码管的,只有位选信号有效该数码管才会亮并显示要现实的数字;段选是选择数码管7段的那一笔亮,从而显示不同的数字。

本设计中单片机P0口输出段选数据,P3口输出位选数据。

数码管与单片机相连的电路如下图所示:电路中使用了芯片74ls245,该芯片用来驱动LED。

其片选引脚要接地,使其一致为低电平,芯片一直可以工作。

(2)晶振电路晶体以及电容C1、C2构成并联谐振电路,接在放大器的反馈回路中构成部单片机部时钟。

晶体可在1.2MHz-12MHz之间任选,电容C1、C2的典型值为通常选择为30pF左右,这时对应的始终频率为12MHz。

单片机部晶振电路图及连接电路如下:(3)按键电路本设计采用行列式按键电路,它由行线和列线组称成,按键位于行列的交叉点。

一个4*4的行列结构可以构成一个16个按键的键盘,如下图所示。

在按键数目较多的场合,行列式按键可以节省很多的I/O口线。

按键的识别是通过扫描来实现的。

单片机会依次扫描每一行和每一列,通过行线和列线的电平高低即可判断哪个按键被按下。

本设计中用到四个按键,P1.0、P1.1、P1.2、P1.3 、P1.4,分别用于时间校准设置、定闹设置、秒分时切换、加1调整、减1调整。

按键与单片机相连电路如下:由原理图可以明显看出,当按键未被按下时,对应引脚为高电平;按键被按下时为低电平。

通过扫描即可辨别哪一个按键被按下。

本题画出的虽然是独立按键,但是部驱动依然是行列式按键的驱动,这里只是为了画图方便。

(4)复位电路当按下复位键时单片机进入复位状态,可以进行时间的设置等。

电路图如下所示:四.系统软件部分的设计本设计的软件系统用来配合硬件电路实现特定的功能。

程序主要包含键盘扫描模块、时间处理模块、和数码管显示程序3大部分。

程序大致流程如下:1.时间处理模块单片机晶振频率为12MHz,一个机器周期等于12个振荡脉冲周期,因此机器时序频率是振荡频率的1/12,即1MHz,所以一个机器周期为1μs。

本设计用的是计时器0的方式1,对于方式1,计数个数M与计数初值N的关系为 M=2^16 –N,定时时间t与计数个数M和初值N的关系为 t = M*机器周期 =(2^16-N)*时钟周期*12。

计时过程中,秒sec等于60时清零,分min加一;分min等于60时清零,小时hour加一;当小时大于24时,置为0。

时分秒的进位算法代码如下:void timecontrol(){sec++;if(sec==60) //秒sec到60清零,分min加一{sec=0;min++;if(min==60) //分min到60清零,时hour加一{min=0;hour++;if(hour==24) //小时hour等于24时清零hour=0;}}}定时器的先关设置:void main(){TMOD=0x01;//定时器0工作在方式1TH0=(65536-45872)/256; //装初值,50msTL0=(65536-45872)%256;EA=1; //总中断允许ET0=1; //T0中断允许TR0=1; //开定时器0while(1){keyscan_settime();keyscan_time();buz();}}2.数码管显示模块本设计中以P0口作为数码管的段选输出,P3口为位选信号输出。

由于所用数码管为共阳极连接,所以要点亮的数码管位选端为高电平1.位选信号的I/O口声明#include<reg51.h>#define uchar unsigned char#define uint unsigned intsbit s1=P3^0; //数码管位选控制端的定义sbit s2=P3^1;sbit s3=P3^2;sbit s4=P3^3;sbit s5=P3^4;sbit s6=P3^5;sbit s7=P3^6;段码表:uchar code mum[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //共阳数码管0-9编码数码管显示函数如下:void display(uchar zs,uchar zm, uchar zh) //数码管显示函数{s1=1; //P3即S系列输出位选信号P0=mum[zh/10]; //P0输出段选信号,显示小时的十位delayms(5);s1=0;s2=1;P0=mum[zh%10]&0x7f; // 显示时的个位加上小数点delayms(5);s2=0;s3=1;P0=mum[zm/10]; //显示分的十位delayms(5);s3=0;s4=1;P0=mum[zm%10]&0x7f; //分的个位加上小数点delayms(5);s4=0;s5=1;P0=mum[zs/10]; //秒的十位delayms(5);s5=0;s6=1;P0=mum[zs%10]; //秒的个位delayms(5);s6=0;}3.键盘扫描模块首先要声明各个按键的功能以及对应的I/O口,然后驱动程序将对按键进行扫描以识别被按下的键。

按键对应I/O口声明/*k1设置时间,k2定时,k3时分秒选择,k4加数字,k5减数字。

*/sbit k1=P1^0;sbit k2=P1^1;sbit k3=P1^2;sbit k4=P1^3;sbit k5=P1^4;键盘扫描以进行时间设置void keyscan_settime() //时间设置模块{uchar st,mt,ht;if(k1==0){delayms(10); //延迟一段时间再次扫描以达到软件消抖的目的if(k1==0){st=sec,mt=min,ht=hour;TR0=0; //关闭定时器while(k1==0) //等待用户按键{display(st,mt,ht);if(k3==0){delayms(10);if(k3==0){while(!k3);ss++;if(ss==3) ss=0;}}/*通过ss选择时分秒设置*/if(k4==0) //加数{delayms(10);if(k4==0){while(!k4);switch(ss){case 0:st++;if(st==60)st=0;break;case 1:mt++;if(mt==60)mt=0;break;case 2:ht++;if(ht==24)ht=0;break;default :;}}}if(k5==0) //减数{delayms(10);if(k5==0){while(!k5);switch(ss){case 0:if(st>0)st--;else st=0;break;case 1:if(mt>0)mt--;else mt=0;break;case 2:if(ht>0)ht--;else ht=0;break;default : ;}}}}TR0=1; //设置完毕,开启定时器sec=st,min=mt,hour=ht;}}display(sec,min,hour);}用户定闹钟时间模块void keyscan_time() //用户定时模块{if(k2==0){delayms(10);if(k2==0){s=sec;m=min;h=hour;while(k2==0) //开始定时设置{display(s,m,h);if(k3==0){delayms(10);if(k3==0){while(!k3);ss++;if(ss==3) ss=0;}}/*通过ss选择时分秒设置*/if(k4==0) //加一{delayms(10);if(k4==0){while(!k4);switch(ss){case 0:s++;if(s==60)s=0;break;case 1:m++;if(m==60)m=0;break;case 2:h++;if(h==24)h=0;break;default :;}}}if(k5==0) //减一{delayms(10);if(k5==0){while(!k5);switch(ss){case 0:if(s>0)s--;else s=0;break;case 1:if(m>0)m--;else m=0;break;case 2:if(h>0)h--;else h=0;break;default : ;}}}}}}}4.其他程序(1)delay延时函数void delayms(uint k) //延时函数{uint i,j;for(i=k;i>0;i--)for(j=110;j>0;j--);}该函数是一个循环,对于输入的k值,本程序将循环k*110次以达到延时的目的。

相关文档
最新文档