基于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单片机的工作原理基于冯诺伊曼体系结构,即程序指令和数据存储在同一块存储器中,通过总线系统进行传输。
基于51单片机的简易数字钟系统设计

简易数字钟系统设计完成一个简易数字时钟系统设计。
要求:用3个独立按键调整时间。
一个按键控制启动运行。
在调整结束后按运行键后开始运行。
1,开机时,显示00:00:00时间从零开始调整。
2,P10控制秒的调整,每按一次加1s。
3,p11控制分的调整,每按一次加1min。
4,p12控制时的调整,每按一次加1h。
5,p13控制运行和停止。
程序:#include<reg52.h>sbit key1=P3^4;sbit key2=P3^5;sbit key3=P3^6;sbit key4=P3^7;#define uchar unsigned char#define uint unsigned intuchar shi,ge,aa,num,num1,num2,tt;uint n;uchar q1,q2,b1,b2;sbit dula=P2^6;sbit wela=P2^7;void keyscan();void delay(uint);void display();uchar table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};void keyscan(){if(key1==0){ num2++;if(num2==24)num2=0;while(!key1);if(key2==0){num1++;if(num1==60)num1=0;while(!key2);}if(key3==0){num++;if(num==60)num=0;while(!key3);}if(key4==0){ TR0=~TR0;while(!key4);}}void main(){TMOD=0x00;TH0=(65536-50000)/256;TL0=(65536-50000)%256;EA=1;ET0=1;while(1){ k eyscan();display();}}void time0()interrupt 1{TH0=(65536-50000)/256;TL0=(65536-50000)%256;tt++;if(tt==100){ tt=0;num++;if(num==60){ num=0;num1++;if(num1==60){ num1=0;num2++;if(num2==24)num2=0;}}}}void display(){q1=num2/10;q2=num2%10;b1=num1/10;b2=num1%10;shi=num/10;ge=num%10;wela=1;P0=0xfe;wela=0;P0=0xff;P0=table[q1]; dula=0; delay(1);wela=1;P0=0xfd; wela=0;P0=0xff; dula=1;P0=table[q2]; dula=0; delay(1);wela=1;P0=0xfb; wela=0;P0=0xff; dula=1;P0=table[b1]; dula=0; delay(1);wela=1;P0=0xf7; wela=0;P0=0xff; dula=1;P0=table[b2]; dula=0; delay(1);wela=1;P0=0xef; wela=0;P0=0xff; dula=1;P0=table[shi]; dula=0; delay(1);wela=1;P0=0xdf;P0=0xff;dula=1;P0=table[ge];dula=0;delay(1);}void delay(uint x){uint i,j;for(i=x;i>0;i--)for(j=110;j>0;j--); }。
(完整版)基于51单片机的数字钟毕业论文

西安邮电学院毕 业 设 计(论 文)题 目: 基于51单片机的数字钟设计院 (系):专 业:班 级:学生姓名:导师姓名: 职称:基于单片机的数字钟毕业论文摘要…………………………………………………………………………… ⅠAbstract……………………………………………………………………… (Ⅱ)第1章 绪 论 (2)1.1 课题背景 (2)1.2 课题来源 (2)1.3 本章小结 (3)第2章 MCS-51单片机的结构 (4)2.1 控制器 (4)2.2 存储器的结构 (4)2.3 并行IO口 (5)2.4 时钟电路与时序 (5)2.5 单片机的应用领域 (6)2.6 本章小结 (6)第3章 电路的硬件设计 (7)3.1 复位电路 (7)3.2 时钟电路 (7)3.3 按键电路 (8)3.4 相关控制电路 (9)3.4.1 控制打铃电路 (9)3.4.2 时间表显示电路 (9)3.5 数码管显示电路 (10)3.6 电源电路设计 (10)3.7 本章小结 (10)第4章 电路的软件设计 (11)4.1 软件程序内容 (11)4.2 软件流程图 (11)4.3 定时程序设计 (12)4.3.1实时时钟实现的基本方法 . (13)4.3.2 实时时钟程序设计步骤 (13)4.4程序说明 (13)4.5 本章小结 (14)第5章 结论与展望 (15)5.1 结论 (15)5.2 单片机的发展趋势 (15)参考文献 (17)附录………………………………………………………………………………18第1章 绪 论1.1 课题背景单片机自1976年由Intel公司推出MCS-48开始,迄今已有二十多年了。
由于单片机集成度高、功能强、可靠性高、体积小、功耗地、使用方便、价格低廉等一系列优点,目前已经渗入到人们工作和生活的方方面面,几乎“无处不在,无所不为”。
单片机的应用领域已从面向工业控制、通讯、交通、智能仪表等迅速发展到家用消费产品、办公自动化、汽车电子、PC 机外围以及网络通讯等广大领域。
基于51单片机的数字钟设计

基于51单片机的数字钟设计目录1 作品的背景与意义 12 功能指标设计 13 作品方案设计 13.1总体方案的选择 13.1.1方案一:基于单片机的数字钟设计 23.1.1方案二:基于数电实验的数字钟设计 33.1.2两种方案的比较......... (3)3.2控制方案比较 33.3显示方案比较 33.4单片机理论知识介绍 43.4.1单片机型号........ (5)3.4.2硬件电路平台.............. (6)3.4.3内部时钟电路........... . (7)3.4.4复位电路............. . (7)3.4.5按键部分............ (8)4 硬件设计94.1显示模块电路图95 软件设计115.1主程序流程图115.2中断服务以及显示 126 系统测试136.1测试环境136.2测试步骤136.2.1硬件测试6.2.2软件测试1.连接单片机和计算机串接............ ..136.2.3实施过程............. .. (14)6.3测试结果187 实验总结................ . (18)7.1代码编写过程中出现问题........... .. (18)7.2整个实验过程的体会................. . (19)7.3实验误差分析。
19参考文献20附录1 系统电路图21附录2 系统软件代码21附录3 系统器件清单261 作品的背景与意义数字钟是采用数字电路实现对.时,分,秒。
数字显示的计时装置,由于数字集成电路的发展和石英晶体振荡器的广泛应用,使得数字钟的精度,远远超过老式钟表, 而且大大地扩展了钟表原先的报时功能。
基于单片机的数字钟具有功能强,体积小,功耗低,价格便宜,工作可靠,使用方便等特点,因此特别适合于与控制有关的系统,越来越广泛地应用于自动控制,智能化仪器,仪表,数据采集,军工产品以及家用电器等各个领域,生活中诸如定时自动报警、按时自动打铃、时间程序自动控制、定时广播、自动起闭路灯、定时开关烘箱、通断动力设备、甚至各种定时电气的自动启用等也可广泛应用,单片机往往是作为一个核心部件来使用,在根据具体硬件结构,以及针对具体应用对象特点的软件结合,以作完善。
基于51单片机的数字电子时钟设计

课程设计任务书摘要数字钟因其小巧,价格低廉,走时精度高,使用方便,功能多,便于集成化而受广大消费的喜爱,因此得到了广泛的使用。
单片机为基础上设计出来的数字时钟数字钟,在日常生活中最常见,应用也最广泛。
本次课程设计的时钟就是以STC89C52单片机为核心,配备LED显示模块、时钟模块、等功能模块的数字电子钟。
采用24小时制方式显示时间。
文章主要从硬件设计和软件编程两个大的方面。
硬件电路设计主要包括中央处理模块、时钟模块,显示模块等几部分。
时钟电路采用DS1302芯片,并选用LED显示器。
软件方面用keil C语言来实现。
软硬件配合,达到电子时钟精准的显示。
关键字:单片机,时钟模块,精准目录1绪论 (2)1.1设计概述 (2)1.2技术简述 (2)1.3本课题的背景 (3)1.4本课题的意义 (3)2系统设计 (4)2.1设计目的 (4)2.2设计功能及要求 (4)2.3设计思路 (4)2.4硬件方案 (4)2.4.1时钟芯片的选择 (5)2.4.2显示屏的选择 (5)2.4.3单片机的选择 (5)2.5软件方案 (5)2.6整体方案 (6)2.7元器件清单 (6)3硬件设计 (7)3.1单片机最小系统 (7)3.1.1时钟电路 (7)3.1.2复位电路 (8)3.2时钟电路 (8)3.3电源电路 (9)3.4系统整体电路 (9)3.5系统仿真 (10)3.6硬件制作 (10)4软件设计 (11)4.1程序设计步骤 (11)4.2系统主程序 (11)4.3时钟模块子程序 (12)4.4显示模块子程序 (12)4.5主程序 (13)5联机调试 (14)6总结 (15)7参考文献 (16)1绪论1.1设计概述在单片机技术日趋成熟的今天,其灵活的硬件电路和软件程序的设计,使单片机得到广泛的应用,从小的电子产品,到大的工业控制,单片机都起到了举足轻重的作用。
数字电子时钟是基于单片机和DS1302时钟芯片的一种计时工具。
51单片机数字钟实验(原理图及程序)

51单片机数字钟实验(原理图及程序)1.实验任务(1.开机时,显示12:00:00的时间开始计时;(2.P0.0/AD0控制“秒”的调整,每按一次加1秒;(3.P0.1/AD1控制“分”的调整,每按一次加1分;(4.P0.2/AD2控制“时”的调整,每按一次加1个小时;2.电路原理图图4.20.13.系统板上硬件连线(1.把“单片机系统”区域中的P1.0-P1.7端口用8芯排线连接到“动态数码显示”区域中的A-H端口上;(2.把“单片机系统:区域中的P3.0-P3.7端口用8芯排线连接到“动态数码显示”区域中的S1-S8端口上;(3.把“单片机系统”区域中的P0.0/AD0、P0.1/AD1、P0.2/AD2端口分别用导线连接到“独立式键盘”区域中的SP3、SP2、SP1端口上;4.相关基本知识(1.动态数码显示的方法(2.独立式按键识别过程(3.“时”,“分”,“秒”数据送出显示处理方法5.程序框图6.汇编源程序SECOND EQU 30HMINITE EQU 31HHOUR EQU 32HHOURK BIT P0.0MINITEK BIT P0.1SECONDK BIT P0.2DISPBUF EQU 40HDISPBIT EQU 48HT2SCNTA EQU 49HT2SCNTB EQU 4AHTEMP EQU 4BHORG 00HLJMP STARTORG 0BHSTART: MOV SECOND,#00HMOV MINITE,#00HMOV HOUR,#12MOV DISPBIT,#00HMOV T2SCNTA,#00HMOV T2SCNTB,#00HMOV TEMP,#0FEHLCALL DISPMOV TMOD,#01HMOV TH0,#(65536-2000) / 256 MOV TL0,#(65536-2000) MOD 256 SETB TR0SETB ET0SETB EAWT: JB SECONDK,NK1LCALL DELY10MSJB SECONDK,NK1INC SECONDMOV A,SECONDCJNE A,#60,NS60MOV SECOND,#00HNS60: LCALL DISPJNB SECONDK,$NK1: JB MINITEK,NK2LCALL DELY10MSJB MINITEK,NK2INC MINITECJNE A,#60,NM60 MOV MINITE,#00H NM60: LCALL DISPJNB MINITEK,$ NK2: JB HOURK,NK3LCALL DELY10MS JB HOURK,NK3INC HOURMOV A,HOURCJNE A,#24,NH24 MOV HOUR,#00H NH24: LCALL DISPJNB HOURK,$NK3: LJMP WTDELY10MS:MOV R6,#10D1: MOV R7,#248DJNZ R7,$DJNZ R6,D1RETDISP:MOV A,#DISPBUF ADD A,#8DEC AMOV R1,AMOV A,HOURMOV B,#10MOV @R1,ADEC R1MOV A,BMOV @R1,ADEC R1MOV A,#10MOV@R1,ADEC R1MOV A,MINITE MOV B,#10DIV ABMOV @R1,ADEC R1MOV A,BMOV @R1,ADEC R1MOV A,#10MOV@R1,ADEC R1MOV A,SECOND MOV B,#10DIV ABMOV @R1,ADEC R1MOV A,BMOV @R1,ADEC R1INT_T0:MOV TH0,#(65536-2000) / 256 MOV TL0,#(65536-2000) MOD 256 MOV A,#DISPBUFADD A,DISPBITMOV R0,AMOV A,@R0MOV DPTR,#TABLEMOVC A,@A+DPTRMOV P1,AMOV A,DISPBITMOV DPTR,#TABMOVC A,@A+DPTRMOV P3,AINC DISPBITMOV A,DISPBITCJNE A,#08H,KNAMOV DISPBIT,#00HKNA: INC T2SCNTAMOV A,T2SCNTACJNE A,#100,DONEMOV T2SCNTA,#00HINC T2SCNTBMOV A,T2SCNTBCJNE A,#05H,DONEMOV T2SCNTB,#00HINC SECONDMOV A,SECONDCJNE A,#60,NEXTMOV SECOND,#00HINC MINITEMOV A,MINITECJNE A,#60,NEXTMOV MINITE,#00HINC HOURMOV A,HOURCJNE A,#24,NEXTMOV HOUR,#00HNEXT: LCALL DISPDONE: RETITABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,40H TAB: DB 0FEH,0FDH,0FBH,0F7H,0EFH,0DFH,0BFH,07FHEND7.C语言源程序#include <AT89X51.H>unsigned char code dispcode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00}; unsigned char dispbitcode[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; unsigned char dispbuf[8]={0,0,16,0,0,16,0,0};unsigned char dispbitcnt;unsigned char second;unsigned char minite;unsigned char hour;unsigned int tcnt;unsigned char mstcnt;unsigned char i,j;void main(void){TMOD=0x02;TH0=0x06;TL0=0x06;TR0=1;ET0=1;EA=1;while(1){if(P0_0==0){for(i=5;i>0;i--)for(j=248;j>0;j--);if(P0_0==0){second++;if(second==60){second=0;}dispbuf[0]=second%10; dispbuf[1]=second/10; while(P0_0==0);}}if(P0_1==0){for(i=5;i>0;i--)for(j=248;j>0;j--);if(P0_1==0){minite++;if(minite==60){minite=0;}dispbuf[3]=minite%10; dispbuf[4]=minite/10; while(P0_1==0);}}if(P0_2==0){for(i=5;i>0;i--)for(j=248;j>0;j--);if(P0_2==0){hour++;if(hour==24){hour=0;}dispbuf[6]=hour%10;dispbuf[7]=hour/10;while(P0_2==0);}}}}void t0(void) interrupt 1 using 0{mstcnt++;if(mstcnt==8){mstcnt=0;P1=dispcode[dispbuf[dispbitcnt]]; P3=dispbitcode[dispbitcnt];dispbitcnt++;if(dispbitcnt==8){dispbitcnt=0;}}tcnt++;if(tcnt==4000){tcnt=0;second++;if(second==60){second=0;minite++;if(minite==60){minite=0;hour++;if(hour==24) {hour=0; }}}dispbuf[0]=second%10; dispbuf[1]=second/10; dispbuf[3]=minite%10; dispbuf[4]=minite/10; dispbuf[6]=hour%10; dispbuf[7]=hour/10; }}。
基于51单片机的数字时钟,带秒表和时间设置

要求:
使用1个6位共阴数码管,3个按键,1个74LS254和51单片机最小系统制作一个带秒表功能的电子时钟,并要求当使用秒表功能时可以对秒表进行暂停和清零,且秒表精度为100ms以上;显示时钟时要求时、分、秒用数码上的点隔开;设置时钟时可以切换设置“时”和“分”,并在数码管上有相应闪烁以区分
以下是我做的原理图:
刚写的程序,有很详细的注释,希望大家一起学习交流:
以下是仿真文件和C程序,网盘分享给大家:
/share/link?shareid=3375444058&uk=453592216 /share/link?shareid=3375444058&uk=453592216 /share/link?shareid=3375444058&uk=453592216
(上面3个是一样的,怕有些吧友没看到)
希望吧友们一起分享自己的作品。
基于51单片机的数字钟设计与制作

一.基于52单片机制作的数字钟1.设计任务⑴时间显示: 上电后,系统自动进入时钟显示,从00:00:00开始计时,此时可以设定当前时间.⑵时间调整:按下k1,k2,k3键可以顺序设置秒、分、时,并在相应数码管上显示设置值,直至6位设置完毕。
2.系统基本方案选择和论证本时钟的设计具体有两种方法。
一是通过单纯的数字电路来实现;二是使用单片机来控制实现。
本次设计选取了较为简单的单片机控制;而选择这一方法后还要进行各个芯片的选择。
以下是我在这次设计中所用的方案。
2.1 芯片的选择方案一:采用AT89C51芯片,其为高性能CMOS 8位单片机,该芯片内含有4k bytes的可反复擦写的只读程序存储器(PEROM)、128 bytes的随机存取数据存储器(RAM)、 32位可编程I/O口线、2个16位定时/计数器、6个中断源、可编程串行UART通道及低功耗空闲和掉电模式,但是由于AT89C51芯片可擦写的空间不够大,且中断源提供的较小,为防止运行过程中出现不必要的问题,我们不选用AT89C51。
方案二:采用AT89C52芯片,它除了具备AT89C51的所有功能与部件外,其最大的优势就是AT89C52提供了8K字节可擦写Flash闪速存储器空间、8个中断源、及256*8字节内部存储器(RAM),解决了我们对可反复擦写的Flash闪速存储器空间大小与中断源的不够问题的担心。
2.2显示模块选择方案和论证方案一:采用LCD,电路比较简单,且在软件设计上也相对简单,具有低功耗功能。
价格贵。
方案二:采用LED数码管显示,显示较为清楚。
价格便宜。
所以本方案采用LED数码管显示。
2.3 时钟信号的选择方案和论证直接采用单片机定时计数器提供的秒信号,使用程序实现年、月、日、周、时、分、秒计数。
采用此种方案可减少芯片的使用,节约成本,实现的时间误差较小。
2.4 电路设计最终方案决定综上各方案所述,对此次数字时钟的方案选定为: 采用AT89C52作为主控制系统; 并由其定时计数器提供时钟; LED作为显示电路来实现功能。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
专业课程设计报告专业班级课程题目基于51单片机的数字钟的设计报告学号学生姓名指导教师成绩2013年6月20日基于A T89C51的数字钟总体设计说明书目录1. 51单片机设计数字钟设计的现实意义 (2)2. 总体设计 (2)2.1.开发与运行环境 (2)2.2.硬件功能描述 (2)2.3.硬件结构 (3)3. 硬件模块设计 (3)3.1.描述 (3)3.1.1. AT89C51单片机简介 (3)3.1.2. 键盘电路的设计 (4)3.1.3. 显示器的选择 (5)3.1.4. 蜂鸣器驱动电路 (5)3.1.5. 各部分功能 (6)4. 嵌入式软件设计 (7)4.1.流程逻辑 (7)4.2.算法 (7)4.2.1. 中断定时器的设置 (27)4.2.2. 闹钟子函数 (28)4.2.3. 计时函数 (29)4.2.4. 键盘扫描函数 (31)4.2.5. 时间和闹钟的设置 (32)5. 实验器材清单 (33)6. 测试与性能分析 (33)6.1.测试结果 (33)6.2.优点 (33)6.3.结论 (34)7. 心得体会 (36)8. 致谢 (36)9. 参考文献 (37)1.51单片机设计数字钟设计的现实意义20世纪末,电子技术获得了飞速的发展,在其推动下,现代电子产品几乎渗透了社会的各个领域,有力地推动了社会生产力的发展和社会信息化程度的提高,同时也使现代电子产品性能进一步提高,产品更新换代的节奏也越来越快。
时间对人们来说总是那么宝贵,工作的忙碌性和繁杂性容易使人忘记当前的时间。
忘记了要做的事情,当事情不是很重要的时候,这种遗忘无伤大雅。
但是,一旦重要事情,一时的耽误可能酿成大祸。
例如,许多火灾都是由于人们一时忘记了关闭煤气或是忘记充电时间等造成的。
而钟表的数字化给人们生产生活带来了极大的方便。
数字钟是通过数字电路实现时,分,秒数字显示的计时装置,广泛用于个人家庭、车站、码头办公室等公共场所,成为人们日常生活中不可少的必需品。
由于数字集成电路的发展和石英晶体振荡器的广泛应用,使得数字钟的精度,远远超过老式钟表,钟表的数字化给人们生产生活带来了极大的方便,而且大大地扩展了钟表原先的报时功能,诸如定时自动报警、按时自动打铃、时间程序自动控制、定时广播、自动起闭路灯、定时开关烤箱、通断动力设备、甚至各种定时电气的自动启用等。
所有这些,都是以钟表数字化为基础的。
因此,研究数字钟及扩大其应用,有着非常现实的意义。
2.总体设计2.1.开发与运行环境在硬件方面,除了CPU外,使用八个七段LED数码管来进行显示,LED采用的是动态扫描显示。
通过LED能够较为准确地显示时、分、秒。
四个简单的按键实现对时间的调整。
软件方面采用C语言编程。
使用Keil单片机模拟调试软件,测试程序的可行性并用Proteus进行仿真。
2.2.硬件功能描述硬件部分设置了的三个按键S1、S2、S3、S4。
当按键S1第一次按下时,停止计时进入闹钟1的秒设置,当按键S1第二、第三次按下时,分别进入闹钟1的分设置和时设置,当按S1第四、第五、第六次按下时分别进入闹钟2的秒、分、时设置,当按S1第七、第八、第九次按下时分别进入闹钟3的秒、分、时设置,当按S1第十、第二一、第十二次按下时分别进入时间的秒、分、时设置,在S1按下的各阶段,可用按键S2、S3进行时间和闹铃时间的时、分、秒进行加减设置;当按键S1第十三次按下时恢复到时间显示功能。
当显示的时间和定时设置的时间一致时,蜂鸣器发出等时间断蜂鸣声,闹铃时间设置为60秒。
在各个闹钟设置阶段,如果有S4按下,则相应闹钟功能关闭或开启;如在闹铃时有S4按下则提前停止闹铃。
2.3.硬件结构3.硬件模块设计3.1.描述3.1.1.AT89C51单片机简介AT89C51是一款单片封装的微控制器,适合于许多要求高集成度、低成本的场合。
可以满足多方面的性能要求。
AT89C51采用了高性能的处理器结构,指令执行时间只需2到4个时钟周期。
6倍于标准51单片机器件。
AT89C51集成了许多系统级的功能,这样可大大减少元件的数目和电路板面积并降低系统的成本。
AT89C51单片机内部主要有以下部件:8031CPU、振荡电路、总线控制部件、中断控制部件、片内Flash存储器、并行I/O接口、定时器和串行I/O接口。
3.1.2.键盘电路的设计方案一:4×4矩阵式键盘。
如果选择此方案,那么在修改时钟或设置闹铃时间时就可以直接从键盘输入,方便、快捷,但程序较为复杂。
方案二:独立式按键。
如果设置过多按键,将会占用较多I/O口,而且会给布线带来不便,因此,此方案适用于按键较少的情况。
若选择此方案,由于按键较少,在修改时间或设置闹铃时间时就不能直接输入,只能通过加或减完成,稍为麻烦一些,但其程序简单。
由于并不需要经常修改时间和设置闹铃时间,而且方案二的程序简单,按键少、成本低,因此,选择方案二。
图3-1 独立按键图3-2 键盘输入电路3.1.3.显示器的选择方案一:液晶显示器。
如果选择此方案,将会降低系统的功耗,这样就可以用电池供电,便于携带。
但液晶显示器的驱动电路复杂,使用起来有一定的难度。
方案二:用数码管作为显示器。
数码管的驱动电路简单,使用方便,如果选择了此方案,那么在夜间看时间的时候就不需要有光源,非常方便。
其缺点是功耗较大。
由于数码管使用起来较为方便,在夜间看时间也很方便,因此我选择了方案二。
图3-3数码管显示3.1.4.蜂鸣器驱动电路发音部分是通过三极管放大驱动蜂鸣器工作,再通过软件这时产生等时时间方波驱动蜂鸣器发出间断嘀声,这样就可以省去硬件振荡电路,降低成本。
图3-4 蜂鸣器驱动电路3.1.5.各部分功能1.键盘模块在此次设计时用了四个按键,分别为S1,S2,S3,S4. 当按键S1第一次按下时,停止计时进入闹钟1的秒设置,当按键S1第二、第三次按下时,分别进入闹钟1的分设置和时设置,当按S1第四、第五、第六次按下时分别进入闹钟2的秒、分、时设置,当按S1第七、第八、第九次按下时分别进入闹钟3的秒、分、时设置,当按S1第十、第二一、第十二次按下时分别进入时间的秒、分、时设置,在S1按下的各阶段,可用按键K2、S3进行时间和闹铃时间的时、分、秒进行加减设置;当按键S1第十三次按下时恢复到时间显示功能。
当显示的时间和定时设置的时间一致时,蜂鸣器发出等时间断蜂鸣声,闹铃时间设置为60秒。
在各个闹钟设置阶段,如果有S4按下,则相应闹钟功能关闭或开启;如在闹铃时有S4按下则提前停止闹铃。
2.蜂鸣器电路发音部分是通过三极管放大驱动蜂鸣器工作,再通过软件这时产生等时时间方波驱动蜂鸣器发出间断嘀声,这样就可以省去硬件振荡电路,降低成本。
4.嵌入式软件设计4.1.流程逻辑图4-1主程序流程图4.2.算法//*********头文件****************** #include<reg51.h>#include<intrins.h> //**********宏定义**************** #define uchar unsigned char#define uint unsigned int//****************************位声明******************************** sbit key1=P1^0;sbit key2=P1^1;sbit key3=P1^2;sbit key4=P1^3;sbit fmq=P3^0;//************************数码管显示的数值**************************uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff};//****************************函数声明****************************** void jia();void jian();//********************数组定义,数组内含有8个数值****************** uchar table1[8],table2[8],table3[8],table4[8];//**************************时间显示初始值************************** uchar shi=12,fen=0,miao=0;//**************************定义全局变量**************************** uchar shi1,fen1,miao1,shi2,fen2,miao2,shi3,fen3,miao3;uchar shi4,fen4,miao4;uchar flag, flag1, wss, cnt, cnt1, alm1, alm2, alm3;// 1秒等时位闪次数校时闹1 闹2 闹3uint flag2;// 蜂鸣//*********************延时函数,用于动态扫描数码管***************** void delay(uchar i){ uchar x,y;for(x=i;x>0;x--)for(y=120;y>0;y--);}//*******************************初始化函数************************* void init(){ TMOD=0x01; //工作方式1TH0=0x3c; //定时时间为:50ms (65536-50000)/256TL0=0x0b0; //(65536-50000)%256ET0=1; //打开定时器EA=1; //开总中断TR0=1; //启动定时器}//********************显示子函数,用于显示时间数值***************** void display(){ uchar i,j;if(cnt!=10||wss==0){ table1[0]=miao%10; //分离秒的个位与十位table1[1]=miao/10;}else{ table1[0]=table1[1]=11;}if(cnt!=11||wss==0){ table1[3]=fen%10; //分离分的个位与十位table1[4]=fen/10;}else{ table1[3]=table1[4]=11;}if(cnt!=12||wss==0){ table1[6]=shi%10; //分离时的个位与十位table1[7]=shi/10;}else{ table1[6]=table1[7]=11;}table1[2]=table1[5]=10;j=0xfb;for(i=0;i<=7;i++) //从秒到时的扫描{ P2=j;P0=table[table1[i]]; //显示数值delay(10);j=_cror_(j,1); //循环右移}}//*******************显示子函数,用于显示定时1时间***************** void display1(){ uchar i,j;if(alm1==0){ if(cnt!=1||wss==0){ table2[0]=miao1%10; //以下含义同上table2[1]=miao1/10;}else{ table2[0]=table2[1]=11;}if(cnt!=2||wss==0){ table2[3]=fen1%10;table2[4]=fen1/10;}else{ table2[3]=table2[4]=11;}if(cnt!=3||wss==0){ table2[6]=shi1%10;table2[7]=shi1/10;}else{ table2[6]=table2[7]=11;}}elsetable2[0]=table2[1]=table2[3]=table2[4]=table2[6]=table2[7]=10; table2[2]= table2[5]=10;j=0xfb;for(i=0;i<=7;i++){ P2=j;P0=table[table2[i]];delay(10);j=_cror_(j,1);}}//********************显示子函数,用于显示定时2时间****************** void display2(){ uchar i,j;if(alm2==0){ if(cnt!=4||wss==0){ table3[0]=miao2%10; //以下含义同上table3[1]=miao2/10;}else{ table3[0]=table3[1]=11;}if(cnt!=5||wss==0){ table3[3]=fen2%10;table3[4]=fen2/10;}else{ table3[3]=table3[4]=11;}if(cnt!=6||wss==0){ table3[6]=shi2%10;table3[7]=shi2/10;}else{ table3[6]=table3[7]=11;}}elsetable3[0]=table3[1]=table3[3]=table3[4]=table3[6]=table3[7]=10;table3[2]= table3[5]=10;j=0xfb;for(i=0;i<=7;i++){ P2=j;P0=table[table3[i]];delay(10);j=_cror_(j,1);}}//***************显示子函数,用于显示定时3时间数值****************// void display3(){ uchar i,j;if(alm3==0){ if(cnt!=7||wss==0){ table4[0]=miao3%10; //分离秒的个位与十位table4[1]=miao3/10;}else{ table4[0]=table4[1]=11;}if(cnt!=8||wss==0){ table4[3]=fen3%10; //分离分的个位与十位table4[4]=fen3/10;}else{ table4[3]=table4[4]=11;}if(cnt!=9||wss==0){ table4[6]=shi3%10; //分离时的个位与十位table4[7]=shi3/10;}else{ table4[6]=table4[7]=11;}}elsetable4[0]=table4[1]=table4[3]=table4[4]=table4[6]=table4[7]=10; table4[2]= table4[5]=10;j=0xfb; //从秒到时的扫描for(i=0;i<=7;i++){ P2=j;P0=table[table4[i]]; //显示数值delay(10);j=_cror_(j,1); //循环右移}}//***********************时间子函数*****************************// void shijian(){ if(flag>=20) //判断是否到一秒{ wss=~wss;flag=0; //到了,则标志位清零if(cnt1!=0){ miao4++; //秒加1if( miao4>59) //判断秒是否到60s{ miao4=0; //到了,则清零fen4++; //分加1if(fen4>59) //以下含义同上{ fen4=0;shi4++;if(shi4>23)shi4=0;}}}else{ miao++; //秒加1if( miao>59) //判断秒是否到60s{ miao=0; //到了,则清零fen++; //分加1if(fen>59) //以下含义同上{ fen=0;shi++;if(shi>23)shi=0;}}}}}//**************************键盘扫描子函数************************// void key_scan(){ if(key1==0){ while(!key1) //防止掉显{ if(cnt==1||cnt==2||cnt==3){ display1(); }if(cnt==4||cnt==5||cnt==6){ display2(); }if(cnt==7||cnt==8||cnt==9){ display3(); }if(cnt==0||cnt==10||cnt==11||cnt==12||cnt==13){ display(); }}cnt++; //记下按键key1按下的次数if(cnt==10&&cnt1==0){ miao4=miao;fen4=fen;shi4=shi;cnt1++;}if(cnt==13){ cnt=0;if(cnt1==1){ miao=miao4;fen=fen4;shi=shi4;}cnt1=0;}}if(key2==0) //判断key2是否按下{ while(!key2) //防止掉显{ if(cnt==1||cnt==2||cnt==3){ display1(); }if(cnt==4||cnt==5||cnt==6){ display2(); }if(cnt==7||cnt==8||cnt==9){ display3(); }if(cnt==0||cnt==10||cnt==11||cnt==12||cnt==13) { display(); }}jia();}if(key3==0) //判断key3是否按下{ while(!key3) //防止掉显{ if(cnt==1||cnt==2||cnt==3){ display1(); }if(cnt==4||cnt==5||cnt==6){ display2(); }if(cnt==7||cnt==8||cnt==9){ display3(); }if(cnt==0||cnt==10||cnt==11||cnt==12||cnt==13) { display(); }}jian(); //调用减1子函数}if(key4==0) //判断key4是否按下{while(!key4) //防止掉{ if(cnt==1||cnt==2||cnt==3){ alm1=~alm1;display1();}if(cnt==4||cnt==5||cnt==6){ alm2=~alm2;display2();}if(cnt==7||cnt==8||cnt==9){ alm3=~alm3;display3();}if(cnt==0||cnt==10||cnt==11||cnt==12||cnt==13)display();}}}//****************************加1子函数*************************** void jia(){ if(cnt==1) //判断key1按下的次数是否为1{ miao1++; //是,则秒加1if(miao1>59) //判断秒是否大于60,是,则秒清零miao1=0;}if(cnt==2) //以下含意同上{ fen1++;if(fen1>59)fen1=0;}if(cnt==3){ shi1++;if(shi1>23)shi1=0;}if(cnt==4){ miao2++;if(miao2>59)miao2=0;}if(cnt==5){ fen2++;if(fen2>59)fen2=0;}if(cnt==6){ shi2++;if(shi2>23)shi2=0;}if(cnt==7){ miao3++;if(miao3>59)miao3=0;}if(cnt==8){ fen3++;if(fen3>59)fen3=0;}if(cnt==9){ shi3++;if(shi3>23)shi3=0;}if(cnt==10){ miao++;if(miao>59)miao=0;cnt1++;}if(cnt==11){ fen++;if(fen>59)fen=0;cnt1++;}if(cnt==12){ shi++;if(shi>23)shi=0;cnt1++;}}//***************************减1子函数**************************// void jian(){ if(cnt==1) //判断key1按下的次数是否为1,是则秒减1 { miao1--;if(miao1==255) //判断秒是否减到255,是,则秒置59miao1=59;}if(cnt==2) //以下含意同上{ fen1--;if(fen1==255)fen1=59;}if(cnt==3){ shi1--;if(shi1==255)shi1=23;}if(cnt==4){ miao2--;if(miao2==255)miao2=59;}if(cnt==5){ fen2--;if(fen2==255)fen2=59;}if(cnt==6){ shi2--;if(shi2==255)shi2=23;}if(cnt==7){ miao3--;if(miao3==255)miao3=59;}if(cnt==8){ fen3--;if(fen3==255)fen3=59;}if(cnt==9){ shi3--;if(shi3==255)shi3=23;}if(cnt==10){ miao--;if(miao==255)miao=59;cnt1++;}if(cnt==11){ fen--;if(fen==255)fen=59;cnt1++;}if(cnt==12){ shi--;if(shi==255)shi=23;cnt1++;}}//***************************闹铃子函数***************************//void clock()//判断秒的数值是否相等{ if(miao==miao1&&alm1==0||miao==miao2&&alm2==0||miao==miao3&&alm3==0) //是,在判断分是否相等if(fen==fen1&&alm1==0||fen==fen2&&alm2==0||fen==fen3&&alm3==0)//是,再判断时是否相等if(shi==shi1&&alm1==0||shi==shi2&&alm2==0||shi==shi3&&alm3==0){ flag2=0; //是,则标志位,flag2清零while(!(flag2==1200)&&(cnt==0)) //判断flag2是否到1200且不// 为调时状态{if(key4==0) //没有,则继续驱动蜂鸣器响{while(!key4)flag2=1200;}if(flag1>1) //等时方波驱动蜂鸣器{ fmq=~fmq;flag1=0;}shijian(); //调用时间子函数display(); //调用显示子函数}fmq=1; //关闭蜂鸣器}}//**************************主函数********************************// void main(){ init(); //调用初始化子函数while(1){ clock(); //闹钟子函数if(cnt==1||cnt==2||cnt==3) //显示子函数{ display1(); }if(cnt==4||cnt==5||cnt==6){ display2(); }if(cnt==7||cnt==8||cnt==9){ display3(); }if(cnt==0||cnt==10||cnt==11||cnt==12||cnt==13){ display(); }shijian(); //调用时间子函数key_scan(); //调用键盘扫描子函数}}//**************************定时中断******************************// void time0() interrupt 1{ TH0=0x3c; //初值50ms (65536-50000)/256TL0=0x0b0; // (65536-50000)%256flag++; //标志位flag1++;flag2++;}4.2.1.中断定时器的设置数字电子钟设计中主要使用定时器T0中断ET0,利用ET0中断进行计时时间的自增,从而实现计时功能。