51单片机电子时钟设计报告

合集下载

基于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单片机的电子时钟

基于51单片机的电子时钟

1、电子闹钟的硬件系统框架:设计出电子闹钟的基本整体框架。

2、电子闹钟的电源设计:采用交直流供电电源。

电子钟一般采用数码管等显示介质,因而必须以交流供电为主,以直流电源为后备辅助电源。

3、电子闹钟的主机电路设计:主要有1)系统时钟电路设计:对时间要求不是很高,只要能使系统可靠起振并稳定运行就行。

2)系统复位电路设计:本系统采用的是RC复位方式3)按键与按钮电路设计:按键与按钮电路设计中关键要考虑的就是按键的去抖动问题。

本系统采用软件去抖。

考虑到对时和设定闹铃时间操作的使用频率不高,为了精简系统和降低成本,本系统只设置两个按键。

a)SET键,对应系统的不同工作状态,具有3个功能:在复位后的待机状态下,用于启动设定时间参数(对时或定闹);在设定时间参数状态而且不是设定最低位(即分个位)的状态下,用于结束当前位的设定,当前设定位下移;在设定最低位(分个位)的状态下,用于结束本次时间设定。

b)+1键,用于对当前设定位进行加1操作。

4)闹铃声光指示电路设计:本系统采用声音指示,关键元件是蜂鸣器。

4、电子闹钟的显示电路设计:设计一个由LED数码管组成的显示电路,显示采用共阳极数码管,其目的是为了简化限流电路的设计和实现亮度可调的要求。

一功能模、设计指标:1. 显示时、分、秒。

2. 可以24小时制或12小时制。

3. 具有校时功能,可以对小时和分单独校时,对分校时的时候,停止分向小时进位。

校时时钟源可以手动输入或借用电路中的时钟。

4. 具有正点报时功能,正点前10秒开始,蜂鸣器1秒响1秒停地响5次。

5. 为了保证计时准确、稳定,由晶体振荡器提供标准时间的基准信号。

二、设计要求:1. 画出总体设计框图,以说明数字钟由哪些相对独立的块组成,标出各个模块之间互相联系,时钟信号传输路径、方向和频率变化。

并以文字对原理作辅助说明。

2. 设计各个功能模块的电路图,加上原理说明。

3. 选择合适的元器件,在面包上接线验证、调试各个功能模块的电路,在接线验证时设计、选择合适的输入信号和输出方式,在充分电路正确性同时,输入信号和输出方式要便于电路的测试和故障排除。

单片机课程设计报告--电子时钟(2021整理)

单片机课程设计报告--电子时钟(2021整理)

一、设计内容该课程设计是利用MCS-51单片机内部的定时/计数器、中断系统、以及行列键盘和LED显示器等部件,设计一个单片机电子时钟。

设计的电子时钟通过数码管显示,并能通过按键实现设置时间和暂停、启动控制等。

二、电子时钟设计思想:用定时/计数器T0,工作于定时,采用方式1,对12MHZ的系统时钟进行定时计数,初值设为XXYY〔自己计算〕。

形成定时时间为50ms。

用片内RAM的7BH单元对50ms 计数,计20次产生秒计数器78H单元加1,秒计数器加到60那么分计数器79H单元加1,分计数器加到60那么时计数器7AH单元加1,时计数器加到24那么时计数器清0。

然后把秒、分、时计数器分成十位和个位放到8个数码管的显示缓冲区,通过数码管显示出来。

显示格式为小时十位、小时个位---分十位、分个位---秒十位、秒个位。

在处理过程中加上了按键判断程序,能对按键处理。

三、MCS-51单片机系统简介单片机应用系统由硬件系统和软件系统两局部组成。

硬件系统是指单片机以及扩展的存储器、I\O接口、外围扩展的功能芯片以及接口电路。

软件系统包括监控程序和各种应用程序。

在单片机应用系统中,单片机是整个系统的核心,对整个系统的信息输入、处理、信息输出进行控制。

与单片机配套的有相应的复位电路、时钟电路以及扩展的存储器和I\O接口,使单片机应用系统能够运行。

在一个单片机应用系统中,往往都会输入信息和显示信息,这就涉及键盘和显示器。

在单片机应用系统中,一般都根据系统的要求配置相应的键盘和显示器。

配置键盘和显示器一般都没有统一的规定,有的系统功能复杂,需输入的信息和显示的信息量大,配置的键盘和显示器功能相对强大,而有些系统输入/输出的信息少,这时可能用几个按键和几个LED 指示灯就可以进行处理了。

在单片机应用系统在中配置的键盘可以是独立键盘,也可能是矩阵键盘。

显示器可以是LED指示灯,也可以是LED数码管,也可以是LCD显示器,还可以使用CRT显示器。

基于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单片机设计的简易电子钟可以显示当前时间,并且实现时间的调整和闹钟设定功能。

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

51单片机电子时钟课程设计报告实验报告

51单片机电子时钟课程设计报告实验报告

《单片机原理与应用》课程设计总结报告题目:单片机电子时钟(带秒表)的设计设计人员:张保江江润洲学号:********** **********班级:自动化1211指导老师:***目录1.题目与主要功能要求 (2)2.整体设计框图及整机概述 (3)3.各硬件单元电路的设计、参数分析及原理说明 (3)4.软件流程图和流程说明 (4)5.总结设计及调试的体会 (10)附录1.图一:系统电路原理图 (11)2.图二:系统电路PCB (12)3.表一:元器件清单 (13)4.时钟程序源码 (14)题目:单片机电子时钟的设计与实现课程设计的目的和意义课程设计的目的与意义在于让我们将理论与实践相结合。

培养我们综合运用电子课程中的理论知识解决实际性问题的能力。

让我们对电子电路、电子元器件、印制电路板等方面的知识进一步加深认识,同时在软件编程、排错调试、焊接技术、相关仪器设备的使用技能等方面得到较全面的锻炼和提高,为今后能够独立完成某些单片机应用系统的开发和设计打下一个坚实的基础。

课程设计的基本任务利用89C51单片机最小系统,综合应用单片机定时器、中断、数码显示、键盘输入等知识,设计一款单片机和简单外设控制的电子时钟。

主要功能要求最基本要求1)使用MCS-51单片机设计一个时钟。

要求具有6位LED显示、3个按键输入。

2)完成硬件实物制作或使用Pruteus仿真(注意位驱动应能提供足够的电流)。

3)6位LED数码管从左到右分别显示时、分、秒(各占用2位),采用24小时标准计时制。

开始计时时为000000,到235959后又变成000000。

4)使用3个键分别作为小时、分、秒的调校键。

每按一次键,对应的显示值便加1。

分、秒加到59后再按键即变为00;小时加到23后再按键即变为00。

在调校时均不向上一单位进位(例如分加到59后变为00,但小时不发生改变)。

5) 软件设计必须使用MCS-51片内定时器,采用定时中断结构,不得使用软件延时法,也不得使用其他时钟芯片。

51单片机电子时钟

51单片机电子时钟

一,总体方案设计数字钟是一个将“ 时”,“分”,“秒”显示于人的视觉器官的计时装置。

它的计时周期为24小时,显示满刻度为23时59分59秒,另外应有校时功能和一些显示星期、报时、停电查看时间等附加功能。

因此,一个基本的数字钟电路主要由译码显示器、“时”,“分”,“秒”,“星期”计数器、校时电路、报时电路和振荡器组成。

干电路系统由秒信号发生器、“时、分、秒、星期”计数器、译码器及显示器、校时电路、整点报时电路组成。

秒信号产生器是整个系统的时基信号,它直接决定计时系统的精度,一般用石英晶体振荡器加分频器来实现。

将标准秒信号送入“秒计数器”,“秒计数器”采用60进制计数器,每累计60秒发出一个“分脉冲”信号,该信号将作为“分计数器”的时钟脉冲。

“分计数器”也采用60进制计数器,每累计60分钟,发出一个“时脉冲”信号,该信号将被送到“时计数器”。

“时计数器”采用24进制计时器,可实现对一天24小时的累计。

每累计24小时,发出一个“星期脉冲”信号,该信号将被送到“星期计数器”,“星期计数器” 采用7进制计时器,可实现对一周7天的累计。

译码显示电路将“时”、“分”、“秒”、“星期”计数器的输出状态送到七段显示译码器译码,通过七位LED七段显示器显示出来。

整点报时电路时根据计时系统的输出状态产生一脉冲信号,然后去触发一音频发生器实现报时。

校时电路时用来对“时”、“分”、“秒”、“星期”显示数字进行校对调整的。

但是基于我们是初学者,我们只做一些比较简单的设计,可以显示时分秒,可以计时,还有闹钟提示,还加上温度的测量,即焊接上温度传感器18DS120在P1口进行温度的测量。

数字电子钟主体电路应由以下几部分组成:通过分频器产生标准秒信号;60进制分秒计数器以及24小时计数器;分、时的译码显示部分;校时电路。

(电子钟的总体电路)二,单元模块设计1)晶体振荡器电路晶体振荡器电路给数字钟提供一个频率稳定准确的32768Hz 的方波信号,此外还有一校正电容可以对温度进行补偿,以提高频率准确度和稳定度,使稳定度优于10-4,可保证数字钟的走时准确及稳定。

单片机电子时钟课程设计报告

单片机电子时钟课程设计报告

单片机电子时钟课程设计报告一、设计目的。

本课程设计旨在通过单片机技术的应用,设计并制作一个简单的电子时钟。

通过这一设计,学生将能够掌握单片机的基本原理和应用,培养学生的动手能力和创新意识,提高学生的实际操作能力。

二、设计原理。

本电子时钟采用单片机作为控制核心,通过晶振产生的时钟信号来实现时间的计时和显示。

利用数码管来显示小时和分钟,通过按键来调整时间。

同时,通过蜂鸣器发出报时信号,实现基本的闹钟功能。

三、设计方案。

1. 硬件设计。

(1)单片机选择,本设计选用常见的51单片机作为控制核心,具有成本低、易于编程的特点。

(2)时钟电路,采用晶振作为时钟信号源,通过单片机的定时器来实现时间的计时。

(3)显示模块,采用数码管来显示小时和分钟,通过数码管的扫描显示来实现时间的动态显示。

(4)按键输入,设计按键来调整时间,包括调整小时和分钟。

(5)报时功能,通过蜂鸣器来实现基本的报时功能,可以设置闹钟时间。

2. 软件设计。

(1)时钟控制,通过单片机的定时器来实现时间的计时和更新。

(2)显示控制,设计数码管的扫描显示程序,实现时间的动态显示。

(3)按键处理,设计按键扫描程序,实现对时间的调整。

(4)报时功能,设计蜂鸣器的报时程序,实现基本的闹钟功能。

四、设计实现。

1. 硬件实现。

根据上述设计方案,完成了电子时钟的硬件连接和布线,保证各个模块之间的正常通讯和工作。

2. 软件实现。

编写了单片机的程序,实现了时钟的计时、显示和控制功能,保证了电子时钟的正常运行。

五、实验结果。

经过调试,电子时钟能够准确显示当前的时间,并能够通过按键调整时间和设置闹钟功能,报时功能也能够正常工作。

六、总结与展望。

通过本课程设计,学生掌握了单片机的基本原理和应用,培养了动手能力和创新意识。

在今后的学习和工作中,学生将能够更好地应用单片机技术,设计和制作更加复杂的电子产品。

同时,也为学生今后的科研和创新工作奠定了良好的基础。

单片机实验电子钟报告

单片机实验电子钟报告

实验四 电子钟(定时器、中断综合实验)一、实验目的熟悉MCS51类CPU 的定时器、中断系统编程方法, 了解定时器的应用、实时程序的设计和调试技巧。

二、实验内容编写一个时钟程序, 产生一个50ms 的定时中断, 对定时中断计数, 将时、分、秒显示在数码管上。

三、程序框图主程序中断处理电子钟程序框图四、实验步骤 1.连线说明: E5 区A0 ←→ A3 区A0 E5 区CS ←→ A3 区CS5 E5 区CLK ←→ B2 区2MHzE5 区A.B.C.D ←→ G5 区A.B.C.D (排线每个8 位, 注意高低位一致) 2.时间显示在数码管上五、程序清单 ms50 DATA 31H ;存放多少个50ms sec DATA 32H ;秒 min DATA 33H ;分hour DATA 34H ;时buffer DATA 35H ;显示缓冲区EXTRN CODE(Display8)ORG 0000HLJMP STARORG 000BH ;定时器T0中断处理入口地址LJMP INT_Timer0ORG 0100HSTAR: MOV SP,#60H ;堆栈MOV ms50,A ;清零ms50MOV hour,#12 ;设定初值: 12:59:50MOV min,#59MOV sec,#50MOV TH0,#60 ;定时中断计数器初值MOV TL0,#176 ;定时50msMOV TMOD,#1 ;定时器0: 方式一MOV IE,#82H ;允许定时器0中断SETB TR0 ;开定时器T0STAR1: LCALL Display ;调用显示JNB F0,$CLR F0SJMP STAR1 ;需要重新显示时间;中断服务程序INT_Timer0: MOV TL0,#176-5MOV TH0,#60PUSH 01HMOV R1,#ms50INC @R1 ;50ms单元加1CJNE @R1,#20,ExitIntMOV @R1,#0 ;恢复初值INC R1INC @R1 ;秒加1CJNE @R1,#60,ExitInt1MOV @R1,#0INC R1INC @R1 ;分加1CJNE @R1,#60,ExitInt1MOV @R1,#0INC R1INC @R1 ;时加1CJNE @R1,#24,ExitInt1MOV @R1,#0ExitInt1: SETB F0ExitInt: POP 01HRETIHexToBCD: MOV B,#10DIV ABMOV @R0,BINC R0MOV @R0,AINC R0RETDisplay: MOV R0,#bufferMOV A,secACALL HexToBCDMOV @R0,#10H ;第三位不显示INC R0MOV A,minACALL HexToBCDMOV @R0,#10H ;第六位不显示INC R0MOV A,hourACALL HexToBCDMOV R0,#bufferLCALL Display8RETENDEXTRN CODE (Display8)BUFFER DA TA 60HORG 0000HAJMP MAINORG 000BHAJMP IT0PMAIN: MOV TMOD,#01HMOV 20H,#20HCLR AMOV 52H,A ;计数和显示MOV 51H,A ;空间清零MOV 50H,#50HMOV 40H,AMOV 41H,AMOV 43H,AMOV 44H,AMOV 46H,AMOV 47H,ASETB ET0SETB EAMOV TH0,#9EH ;计数器赋初值MOV TL0,#58HSETB TR0MOV 45H,#11HMOV 42H,#11HMOV R0,#BUFFERLCALL Display8HERE: AJMP HEREIT0P: PUSH PSWPUSH ACCMOV TH0,#9EH ;重新转入计数值MOV TL0,#58HDJNZ 20H,RETURN ;计数不满20返回MOV 20H,#20H ;重置中断次数MOV A,#01H ;秒加1ADD A,50HDA A ;秒单元十进制调制PUSH ACCCJNE A,#60H,SWS ;是否到60秒, 否则返回MOV A,#00HSWS: MOV R5,ASW AP AANL A,#0FHMOV 41H,AMOV A,R5ANL A,#0FHMOV 40H,A ;满60秒, 秒单元清零LCALL AAAPOP ACCMOV 50H,ACJNE A,#60H,RETURNMOV 50H,#00HMOV A,#01H ;分单元加1ADD A,51H ;分单元十进制调整DA APUSH ACCCJNE A,#60H,SWS1;是否到60分, 否则返回MOV A,#00HSWS1: MOV R5,A·SW AP AANL A,#0FHMOV 44H,AMOV A,R5ANL A,#0FHMOV 43H,ALCALL AAAPOP ACCMOV 51H,ACJNE A,#60H,RETURNMOV 51H,#00H ;满60分, 分单元清零MOV A,#01H ;时单元加1ADD A,52HDA APUSH ACCCJNE A,#24H,SWS2 ;是否到24小时, 否则返回MOV A,#00HSWS2: MOV R5,ASW AP AANL A,#0FHMOV 47H,AMOV A,R5ANL A,#0FHMOV 46H,ALCALL AAAPOP ACCMOV 52H,ACJNE A,#24H,RETURNMOV 52H,#00H ;满24小时, 时单元清零RETURN:POP PSWPOP ACCRETIAAA: MOV R0,#40H ;计数器的值赋MOV R1,#60H ;给显示空间MOV R5,#08HABC: MOV A,@R0MOV @R1,AINC R1INC R0DJNZ R5,ABCMOV R0,#BUFFERLCALL Display8RETEND六、思考题1.电子钟走时精度与哪些有关系?中断程序中给TL0赋值为什么与初始化程序中不一样?2、使用定时器方式二, 重新编写程序。

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

电子时钟实验报告全部代码在文档末尾:51单片机,LCD1602液晶显示屏平台下编程实现,可直接编译运行目录:一,实验目的 (1)二,实验要求 (2)三,实验基本原理 (2)四,实验设计分析 (2)五,实验要现 (3)A.电路设计 (3)1. 整体设计 (3)2. 分块设计 (4)输入部分 (4)输出部分 (5)晶振与复位电路 (6)B.程序设计 (6)程序总体设计 (6)程序主要模块 (7)五.实验总结及感想 (7)一,实验目的20世纪末,电子技术获得了飞速的发展,在其推动下,现代电子产品几乎渗透了社会的各个领域,有力地推动了社会生产力的发展和社会信息化程度的提高,同时也使现代电子产品性能进一步提高,产品更新换代的节奏也越来越快。

现代生活的人们越来越重视起了时间观念,可以说是时间和金钱划上了等号。

对于那些对时间把握非常严格和准确的人或事来说,时间的不准确会带来非常大的麻烦,所以电子钟是以其小巧,价格低廉,走时精度高,使用方便,功能多,便于集成化而受广大消费的喜爱,得到了广泛的使用。

1. 学习8051定时器时间计时处理、按键扫描及LCD液晶显示的设计方法。

2. 设计任务及要求利用实验平台上LCD1602液晶显示屏,设计带有闹铃功能的数字时钟二,实验要求A.基本要求:1. 在LCD1602液晶显示屏上显示当前日期,时间。

2. 利用按键可对时间及闹玲进行设置,并可显示设置闹玲的时间。

闹玲时间到蜂鸣器发出声响,一分钟后闹铃停止。

B.扩展部分:1.日历功能(能对年,月,日,星期进行显示,分辨平年,闰年以及各月天数,并调整)实现年月日时分秒的调整,星期准确的随着日期改变而改变进行显示。

2.定时功能(设定一段时间长度,定时到后,闹铃提示)C.可扩展部分:1.闹铃重响功能(闹铃被停止后,以停止时刻开始,一段时间后闹铃重响,且重响时间的间隔可调)2.可进行备忘录提示,按照年月日,可在设定的某年某月进行闹铃提示。

三,实验基本原理利用单片机定时器完成计时功能,定时器0计时中断程序每隔中断一次并当作一个计数,设定定时1秒的中断计数初值为20,每中断一次中断计数初值加1,当减到20时,则表示1s到了,秒变量加1,同理再判断是否1min钟到了,再判断是否1h到了,是否一天到了,是否一个月到了,是否一年到了。

将时间在LCD液晶屏上显示,降低了程序的编写难度。

LCD的固定显示特性是我们省去了数码管的动态扫描显示。

四,实验设计分析针对要实现的功能,采用AT89S52单片机进行设计,AT89S52 单片机是一款低功耗,高性能CMOS8位单片机,片含4KB在线可编程(ISP)的可反复擦写1000次的Flash只读程序存储器,器件采用高密度、非易失性存储技术制造,兼容标准MCS- 51指令系统及80C51引脚结构。

这样,既能做到经济合理又能实现预期的功能。

在程序方面,采用分块设计的方法,这样既减小了编程难度、使程序易于理解,又能便于添加各项功能。

程序可分为闹钟的声音程序、时间显示程序、日期显示程序,秒表显示程序,时间调整程序、闹钟调整程序、定时调整程序,延时程序等。

运用这种方法,关键在于各模块的兼容和配合,若各模块不匹配会出现意想不到的错误。

首先,在编程之前必须了解硬件结构尤其是各引脚的用法,以及部寄存器、存储单元的用法,否则,编程无从下手,电路也无法设计。

这是前期准备工作。

第二部分是硬件部分:依据想要的功能分块设计设计,比如输入需要开关电路,输出需要显示驱动电路和数码管电路等。

第三部分是软件部分:先学习理解C语言的编程方法再根据设计的硬件电路进行分块的编程调试,最终完成程序设计。

第四部分是软件画图部分:设计好电路后进行画图,包括电路图和仿真图的绘制。

第五部分是软件仿真部分:软硬件设计好后将软件载入芯片中进行仿真,仿真无法完成时检查软件程序和硬件电路并进行修改直到仿真成功。

第六部分是硬件实现部分:连接电路并导入程序检查电路,若与设计的完全一样一般能实现想要的功能。

最后进行功能扩展,在已经正确的设计基础上,添加额外的功能!五,实验要现A.电路设计1. 整体设计此次设计主要是应用单片机来设计电子时钟,硬件部分主要分以下电路模块:显示电路用lcd1602显示,年份,月份,星期,小时、分钟和秒(日),使电路更加简单。

单片机采用AT89S51系列,这种单片机应用简单,适合电子钟设计。

电路的总体设计框架如下:2. 分块设计模块电路主要分为:输入部分、输出部分、复位和晶振电路。

输入部分输入信号主要是各种模式选择和调整信号,由按键开关提供。

以下为输入部分样例:在本实验中主要用用P3口输入按键信号,还用到了特殊的P0口。

对于P0口,由于其存在高阻状态,为了实现开关功能,给其添加上拉电阻,具体如下图所示:输出部分本电路的输出信号LCD的写入命令和写入数据,闹铃脉冲信号。

闹铃由端输出,模块如下:日期时间由LCD1602输出,模块如下:晶振与复位电路本实验单片机时钟用部时钟,模块如下:复位电路为手动复位构成,模块如下:B.程序设计程序总体设计本实验用汇编程序完成.程序总的流程图如下:程序主要模块中断服务程序:/******************一秒定时中断函数*****************/void timer0() interrupt 1 using 1{ET0=0; 验总结及感想一分耕耘,一分收获。

只有亲自用实践来验证这句话,在能得其要领。

经过这次单片机课程设计,我从一个单片机实践的门外汉,已经越升为略知一二的新手。

虽然还有很多有关单片机的应用有待学习,但万变不离其宗,只要深入了解单片的原理,全部知识点,各个细节,一切设计皆有可能。

在实验的开始几天,基本上没有收获,不知何从下手,不知所措。

为了看得更远,不妨站在前人的肩膀上,我在整体思路模糊的情况下,在网上大量招资粮,各种与电子时钟相关的文章,我阅读了不少。

随着涉猎的点滴积累,我对电子时钟的设计方案已经慢慢酝酿而成。

有了方向和不少知识储备后,在接下来的几天,几乎每天都有突破,虽然有时只是一句程序的修改或诞生,但那种收获的感觉很暖人心。

实验中遇到了不少问题,接下来总结一下,共同探讨。

1, P0口开关问题。

P0口比较特殊,它存在高阻态,要使其输入不是高电平就是低电平,就要接上拉电阻,给其高电平输入。

以上就是实验中遇到的主要问题,基本上都找到了相应的解决之道。

整个实验的过程就是一个解决问题的过程,每天都解决一些问题,我的实验也就解决了,当然结果不重要,功利化的追求结果,会使人浮躁,还是享受那份疑难迎刃而解的快感吧!全部完整代码:此代码未经本人优化,可以根据自己的需求优化代码。

盗版不究,可直接引用。

/****************************************************************/基于STC89S52单片机以及液晶1602显示的万年历项目/***************************************************************/#include<>#include<>#define uchar unsigned char#define uint unsigned int/***************液晶1602相关参数***************/#define data_port P0 //液晶屏指令、数据通信接口sbit rs=P1^0; //液晶屏寄存器选择接口(rs=0时选择指令寄存器,rs=1时选择数据寄存器)sbit rw=P1^1; //液晶屏读写选择接口(rw=0时选择写入,rw=1时选择读出)sbit en=P1^2; //液晶屏使能接口(en=0时通信接口中断,en=1时通信接口接通)uchar code line1_str[]={"----Welcome!----"};//液晶屏第一行要显示的字符串uchar code line2_str[]={" made by: MCU "};//液晶屏第二行要显示的字符串/***************按键设置的相关参数************/sbit timer=P1^5; //蜂鸣器sbit sound=P3^4; //进入闹铃设置状态键uchar sflag=0,ssflag=0; //闹铃设置标志位;闹铃工作标志位sbit set_key=P3^7; //进入设置sbit up_key=P3^6; //加号键sbit cancle_key=P3^5; //完成设置键uchar set=0; //是否进行了设置uchar flag=0; //设置选择标志uchar year=0x00; //"年"寄存器uchar month=0x01; //"月"寄存器uchar day=0x01; //"日"寄存器uchar week=0x06; //"星期"寄存器uchar hour; //"时"寄存器uchar minite; //"分"寄存器uchar second; //"秒"寄存器uchar jiamiao=0; //加秒参数uchar fen1,fen2; //(数据交换)分定时寄存器uchar shi1,shi2; // (数据交换)时定时寄存器uchar code num_tab[]={"09"}; //液晶屏要显示的数字表uchar dis_val[7]={0x00,0x01,0x01,0x06,0x00,0x00,0x00};//依次存储:年,月,日,星期,时,分,秒/******************子函数部分*****************/void lcd_int(); //初始化1602液晶void welcome(); //欢迎界面void in_command(uchar ); //向液晶屏输入命令void in_data(uchar dat); //向液晶屏输入数据void delay(uint ms); //延时函数void key(); //按键设置函数uchar calculate_week(); //星期计算函数void week_disp(uchar x); //LCD1602显示星期值子函数声明void lcd_disp_string(uchar str[]); //液晶屏显示一串字符子函数声明void brush_lcd(); //刷新液晶屏显示容子函数声明void run(); //万年历正常运行函数/**********************************************/void main(){TMOD=0x01; //0000 0001 使用定时器T0的模式1(16位模式)TH0=(65536-50000)/256; //设定每次中断间隔50msTL0=(65536-50000)%256;jiamiao=1;EA=1; //打开总中断允许ET0=1; //打开定时器T0中断允许位TR0=1; //启动定时器T0lcd_int();welcome();delay(1000);while(1){key();if(jiamiao==20){second++;dis_val[6]=((second/10)<<4)|(second%10); //刷新"秒"jiamiao=0;run();}if(flag==0){if(dis_val[0]==0x00 && dis_val[1]==0x01 && dis_val[2]==0x01)//2000年1月1日为星期六{dis_val[3]=0x06;}brush_lcd(); //刷新液晶屏显示容}if(hour==shi2 && minite==fen2 &&ssflag==1){timer=0;}else{timer=1;}}}/********延时子函数************/void delay(uint ms){uchar i;while(ms--){for(i=0;i<244;i++);}}/************LCD初始化*****************/void lcd_int(){delay(30); //延时15MS,等待LCD初始化in_command(0x01); //清显示屏in_command(0x38); //8位通信,2行显示,5*7点阵in_command(0x0c); //开显示,关光标,关闪烁in_command(0x06); //字符不动,光标右移动,地址加一}/**********液晶屏显示一串字符**********/void lcd_disp_string(uchar str[]){uchar i=0;while(str[i]!='\0'){in_data(str[i]); //显示数据(字符)i++;}}/***************欢迎界面函数***************/void welcome(){uchar i;in_command(0x80); //设定第一行字符串起始显示位置while(line1_str[i]!='\0'){delay(100);in_data(line1_str[i]); //显示数据(字符)i++;}i=0;in_command(0xc0); //设定第二行字符串起始显示位置while(line2_str[i]!='\0')delay(100);in_data(line2_str[i]); //显示数据(字符)i++;}}/********向液晶屏输入命令子函数************/void in_command(uchar ){delay(2);en=0;//关闭通信,为设置参数做准备rs=0;//选择指令寄存器rw=0;//写入液晶_nop_();data_port=;en=1;//开始通信_nop_();en=0;//关闭通信,为设置参数做准备}/********向液晶屏输入数据子函数************/void in_data(uchar dat){delay(2);en=0;//关闭通信,为设置参数做准备rs=1;//选择数据寄存器rw=0;//写入液晶_nop_();data_port=dat;_nop_();en=1;//开始通信_nop_();en=0;//关闭通信,为设置参数做准备}/***********计算星期值子函数**************/uchar calculate_week(){uint days_number; //存储天数值uchar i;if(year>=1){days_number=(((year-1)/4)+1); //从00年到year-1年的闰年个数days_number=days_number+(year*365); //从00年到year-1年的总天数}elsedays_number=0;}for(i=1;i<month;i++){switch(i){case 1:case 3:case 5:case 7:case 8:case 10:case 12:days_number+=31;//大月31天break;case 4:case 6:case 9:case 11:days_number+=30;//小月30天break;case 2: if(year%4==0) //闰年2月29天{days_number+=29;}else //平年2月28天{days_number+=28;}break;}}days_number+=day; //加上本月日期if((days_number+5)%7==0) //计算现在的星期值,并返回其值{return(7);}else{return((days_number+5)%7);}}/*********LCD1602显示星期值子函数************/void week_disp(uchar x){switch(x){case 1: lcd_disp_string("MON"); //显示"星期一"break;case 2: lcd_disp_string("TUE"); //显示"星期二"break;case 3: lcd_disp_string("WED"); //显示"星期三"break;case 4: lcd_disp_string("THU"); //显示"星期四"break;case 5: lcd_disp_string("FRI"); //显示"星期五"break;case 6: lcd_disp_string("SAT"); //显示"星期六"break;case 7: lcd_disp_string("SUN"); //显示"星期日"break;}}/*****************按键设置函数**************/void key(){if(set_key==0) //检测"设置"键是否按下{delay(5); //延时消抖if(set_key==0){ET0=0; //打开定时器T0中断允许位TR0=0; //启动定时器T0if(flag<6){flag++;}else{flag=0;}switch(flag){case 0: if(set==1) //检测时间是否更改{set=0; //时间更改标志复位dis_val[0]=((year/10)<<4)|(year%10); //刷新"年"dis_val[1]=((month/10)<<4)|(month%10); //刷新"月"dis_val[2]=((day/10)<<4)|(day%10); //刷新"日"dis_val[3]=week; //刷新"星期"dis_val[4]=((hour/10)<<4)|(hour%10); //刷新"时"dis_val[5]=((minite/10)<<4)|(minite%10); //刷新"分"dis_val[6]=((second/10)<<4)|(second%10); //刷新"秒"}in_command(0x0c); //开显示,关光标,关闪烁break;case 1: in_command(0x83); //设定显示(光标)位置----"年"低位闪烁in_command(0x0d); //开显示,关光标,开闪烁year=((dis_val[0]>>4)*10)+(dis_val[0]&0x0f); //预设调节变量初始值为当前时刻month=((dis_val[1]>>4)*10)+(dis_val[1]&0x0f);day=((dis_val[2]>>4)*10)+(dis_val[2]&0x0f);hour=((dis_val[4]>>4)*10)+(dis_val[4]&0x0f);minite=((dis_val[5]>>4)*10)+(dis_val[5]&0x0f);second=((dis_val[6]>>4)*10)+(dis_val[6]&0x0f);break;case 2: in_command(0x86); //设定显示(光标)位置----"月"低位闪烁break;case 3: in_command(0x89); //设定显示(光标)位置----"日"低位闪烁break;case 4: in_command(0xc5); //设定显示(光标)位置----"时"低位闪烁break;case 5: in_command(0xc8); //设定显示(光标)位置----"分"低位闪烁break;case 6: in_command(0xcb); //设定显示(光标)位置----"秒"低位闪烁break;}while(set_key==0);}}if(up_key==0 && flag!=0) //检测"设置时间"启动时,"上升"键是否按下{delay(5); //延时消抖if(up_key==0){switch(flag){case 1: if(sflag==1){break;}if(year<99){year++;}else{year=0;}if(year%4!=0 && month==2)//平年的2月{if(day>28){day=28;in_command(0x88); //设定显示(光标)位置----"日"高位in_data(num_tab[day/10]); //修正"日"in_data(num_tab[day%10]);}}week=calculate_week(); //计算星期值in_command(0x8c); //设定显示(光标)位置----"星期"week_disp(week); //LCD1602显示星期值in_command(0x82); //设定显示(光标)位置----"年"高位in_data(num_tab[year/10]); //显示正在调节的"年"in_data(num_tab[year%10]);in_command(0x83); //设定显示(光标)位置----"年"低位闪烁break;case 2: if(sflag==1){break;}if(month<12){month++;}else{month=1;}if(month==4 || month==6 || month==9 || month==11){if(day>30){day=30;in_command(0x88);//设定显示(光标)位置----"日"高位in_data(num_tab[day/10]); //修正"日"in_data(num_tab[day%10]);}}if(month==2){if(year%4!=0) //平年{if(day>28){day=28;in_command(0x88); //设定显示(光标)位置----"日"高位in_data(num_tab[day/10]); //修正"日"in_data(num_tab[day%10]);}}else //闰年{if(day>29){day=29;in_command(0x88); //设定显示(光标)位置----"日"高位in_data(num_tab[day/10]); //修正"日"in_data(num_tab[day%10]);}}}week=calculate_week();//计算星期值in_command(0x8c); //设定显示(光标)位置----"星期"week_disp(week); //LCD1602显示星期值in_command(0x85); //设定显示(光标)位置----"月"高位in_data(num_tab[month/10]); //显示正在调节的"月"in_data(num_tab[month%10]);in_command(0x86); //设定显示(光标)位置----"月"低位闪烁break;case 3: if(sflag==1){break;}if(month==4 || month==6 || month==9 || month==11){if(day<30){day++;}else{day=1;}}else if(month==2){if(year%4!=0) //平年{if(day<28){day++;}else{day=1;}}else //闰年{if(day<29){day++;}else{day=1;}}}else{if(day<31){day++;}else{day=1;}}week=calculate_week();//计算星期值in_command(0x8c); //设定显示(光标)位置----"星期"week_disp(week); //LCD1602显示星期值in_command(0x88); //设定显示(光标)位置----"日"高位in_data(num_tab[day/10]); //显示正在调节的"日"in_data(num_tab[day%10]);in_command(0x89); //设定显示(光标)位置----"日"低位闪烁break;case 4: if(hour<23){if(sflag==1) //完成闹钟状态下的数值变换,并保存设置前的状态{shi1=hour;hour++;shi2=hour;}else{hour++;}}else{hour=0;}in_command(0xc4); //设定显示(光标)位置----"时"高位in_data(num_tab[hour/10]); //显示正在调节的"时"in_data(num_tab[hour%10]);in_command(0xc5); //设定显示(光标)位置----"时"低位闪烁break;case 5: if(minite<59){if(sflag==1) //完成闹钟状态下的数值变换,并保存设置前的状态{fen1=minite;minite++;fen2=minite;}else{minite++;}}else{minite=0;}in_command(0xc7); //设定显示(光标)位置----"分"高位in_data(num_tab[minite/10]); //显示正在调节的"分"in_data(num_tab[minite%10]);in_command(0xc8); //设定显示(光标)位置----"分"低位闪烁break;case 6: if(second<59){second++;}else{second=0;}in_command(0xca); //设定显示(光标)位置----"秒"高位in_data(num_tab[second/10]); //显示正在调节的"秒"in_data(num_tab[second%10]);in_command(0xcb); //设定显示(光标)位置----"秒"低位闪烁break;}set=1; //时间更改标志置位while(up_key==0);}}if(sound==0 && flag!=0)//启动定时状态标志{sflag=1;}if(cancle_key==0 && flag!=0) //检测"设置时间"启动时,"完成"键是否按下{delay(5); //延时消抖if(cancle_key==0){set=0; //时间更改标志复位flag=0; //设置按键状态值复位in_command(0x0c); //开显示,关光标,关闪烁while(cancle_key==0);if(sflag==1) //判断是否进行过闹钟定时设置{minite=fen1;hour=shi1;ssflag=1; //启动闹钟工作标志sflag=0; //关闭闹钟定时状态标志}ET0=1; //打开定时器T0中断允许位TR0=1; //启动定时器T0}}}/********刷新液晶屏显示容子函数*********/void brush_lcd(){static uchar old_second=0x01;if(dis_val[6]!=old_second){old_second=dis_val[6]; //刷新原来的"秒"为新"秒"值in_command(0x80); //设定第一行字符串起始显示位置in_data('2'); //年的千位in_data('0'); //年的百位in_data(num_tab[dis_val[0]/16]); //显示"年"in_data(num_tab[dis_val[0]%16]);in_data('-'); //显示分隔符in_data(num_tab[dis_val[1]/16]); //显示"月"in_data(num_tab[dis_val[1]%16]);in_data('-'); //显示分隔符in_data(num_tab[dis_val[2]/16]); //显示"日"in_data(num_tab[dis_val[2]%16]);in_data(' '); //显示分隔符in_data('['); //显示分隔符week_disp(dis_val[3]); //LCD1602显示星期值in_data(']'); //显示分隔符in_command(0xc0); //设定第二行字符串起始显示位置in_data('-'); //显示分隔符in_data('-'); //显示分隔符in_data('-'); //显示分隔符in_data('-'); //显示分隔符in_data(num_tab[dis_val[4]/16]); //显示"时"in_data(num_tab[dis_val[4]%16]);in_data(':'); //显示分隔符in_data(num_tab[dis_val[5]/16]); //显示"分"in_data(num_tab[dis_val[5]%16]);in_data(':'); //显示分隔符in_data(num_tab[dis_val[6]/16]); //显示"秒"in_data(num_tab[dis_val[6]%16]);in_data('-'); //显示分隔符in_data('-'); //显示分隔符in_data('-'); //显示分隔符in_data('-'); //显示分隔符}}/******************一秒定时中断函数*****************/void timer0() interrupt 1 using 1{ET0=0; //关闭定时器T0中断允许位TR0=0; //关闭定时器T0jiamiao++;TH0=(65536-50000)/256; //设定每次中断间隔50msTL0=(65536-50000)%256;TR0=1; //启动定时器T0ET0=1; //打开定时器T0中断允许位}/********************万年历正常运行函数********************/ void run(){if(second>=59){minite++;second=0x00;}if(minite>=59){hour++;minite=0x00;}if(hour>=23){day++;hour=0x00;}if(month==4 || month==6 || month==9 || month==11){if(day>=30){day=0x01;month++;}}if(month==2){if(year%4!=0) //平年{if(day>=28){day=0x01;month++;}}else //闰年{if(day>=29){day=0x01;month++;}}}else{if(day>=31){day=1;month++;}}if(month>=12){month=0x01;year++;}dis_val[0]=((year/10)<<4)|(year%10); //刷新"年"dis_val[1]=((month/10)<<4)|(month%10); //刷新"月"dis_val[2]=((day/10)<<4)|(day%10); //刷新"日"dis_val[3]=week; //刷新"星期"dis_val[4]=((hour/10)<<4)|(hour%10); //刷新"时"dis_val[5]=((minite/10)<<4)|(minite%10); //刷新"分"dis_val[6]=((second/10)<<4)|(second%10); //刷新"秒" }。

相关文档
最新文档