单片机课程设计—带有LCD的定时闹钟(26页).doc
-第 I 页单片机课程设计单片机课程设计带有带有 LCD 的定时的定时闹钟闹钟-第 II 页设计总说明设计总说明这次课程设计的任务是是利用 MCS51 系列单片外加必要的辅助电路从而设计一个带有 LCD 显示的定时闹钟。该闹钟应具有的功能是:当定时闹钟到了人为设定好的时间后,它就发出声音,并且在 LCD 显示器上显示出你所设定的闹钟时间以及当前时间,并能够随时调整时间。本课设所用器件有:AT89C52 单片机、LCD 显示器(LM016L)、上拉电阻(Respack-8)、晶振电路、复位电路(带有复位键)以及四个控制键。1、在控制时分电路设计中,分别设置了四个键:K1 键-用来设置当前时间以及在设置中用来设置时钟K2 键-显示闹钟时间以及在设置中用来设置分钟K3 键-设置闹钟时间K4 键-控制闹铃的开关2、在控制时分秒电路的设计中,分别设置了五个键,即在 1 的基础上增加了一个控制秒的按键。当然本课程设计中所用到的元器件还可以应用其他的一些器件。比如AT89C52 完全可以用 AT89C51 来代替,LM016L 型号的 LCD 显示器可以用 LM017L 型号的 LCD 显示器来代替(其他一些显示器也可以用),上来电阻也可以用分电阻来表示。初次做课程设计,肯定会有许多不足之处,希望老师们指点!关键字关键字:AT89C52AT89C52 单片机单片机LCDLCD 显示器显示器闹钟闹钟-第 3 页目录1、主要内容32、目的和意义33、基本要求33.1、显示时-分功能33.2、显示时-分-秒功能34、系统设计4.1AT89C52 单片机简介44.2电路总体设计64.3主程序流程图75、详细设计5.1设计电路图75.2程序代码125.2.1时-分程序代码125.2.2时-分-秒程序代码236、结论6.1结果分析336.2心得体会337、设计总结348、参考文献341 1、主要内容:主要内容:本次课程设计的内容为设计一个以 MCS51 单片机为核心的带有 LCD 显示的定时闹钟,完成原理图设计,软件编制及设计报告。设使用 AT89C52 单片机结合字符型 LCD 显示器设计一个简易的定时闹钟 LCD 时钟,若 LCD选择有背光显示的模块,在夜晚或黑暗的场合中也可以使用。2 2、设计本电子定时闹钟的目的和意义设计本电子定时闹钟的目的和意义本课程设计的目的和意义在于提高对单片机课程的认识以及对该课程的实践应用能力。-第 4 页通过本次课程设计的实践,了解单片机工作的原理及应用技术,掌握根据硬件电路设计软件的方法,了解设计过程中的各个基本环节,也为今后的实际应用奠定基础3 3、基本要求:、基本要求:.字符型 LCD(16*2)显示器.显示格式“时时:分分:秒秒”。.一旦时间到则发出声响,表示程序开始执行,LCD 显示“0000”,按下操作键 K1-k4 动作如下:3.1、显示时-分功能:(1)K1设置现在的时间。(2)K2显示闹铃的时间(3)K3设置闹铃的时间。(4)K4闹铃 ON/OFF(即按下 k4 键可以开启或停止声响)的状态设置,定时“开始”按键,启动定时。(5)K5复位键设置当前时间或闹铃时间如下:1K1对时的调整。2K2对分的调整。3K3设置完成。3.2、显示时-分-秒功能:(6)K1设置现在的时间。(7)K2显示闹铃的时间(8)K3设置闹铃的时间。(9)K4设置完成。(10)K5闹铃 ON/OFF(即按下 k4 键可以开启或停止声响)的状态设置,定时“开始”按键,启动定时(11)K6复位键设置当前时间或闹铃时间如下:4K1对时的调整。5K2对分的调整。6K3对秒的调整。7K4设置完成。4 4、系统设计系统设计4.14.1 AT89C52AT89C52 单片机简介单片机简介许多由关硬件设计中都使用到单片机AT89C52,其功能比以往的单片机强大的多。AT89C52 是一种高性能低功耗的采用 CMOS工艺制造的 8 位微控制器,它提供下列标准特征:4K 字节的程序存储器,128 字节的 RAM,32条 I/O 线,2 个 16 位定时器/计数器,一个 5 中-第 5 页断源和两个优先级的中断结构,一个双工的串行口,片上震荡器和时钟电路。引脚说明:VCC:电源电压GND:地P0 口:P0 口是一组 8 位漏极开路型双向 I/O 口,作为输出口用时,每个引脚能驱动 8 个 TTL 逻辑门电路。当对 0 端口写入 1 时,可以作为高阻抗输入端使用。当 P0 口访问外部程序存储器或数据存储器时,它还可设定成地址数据总线复用的形式。在这种模式下,P0 口具有内部上拉电阻。在 EPROM 编程时,P0 口接收指令字节,同时输出指令字节在程序校验时。程序校验时需要外接上拉电阻。P1 口:P1 口是一带有内部上拉电阻的 8 位双向 I/O 口。P1 口的输出缓冲能接受或输出 4 个 TTL 逻辑门电路。当对 P1 口写 1 时,它们被内部的上拉电阻拉升为高电平,此时可以作为输入端使用。当作为输入端使用时,P1 口因为内部存在上拉电阻,所以当外部被拉低时会输出一个低电流(IIL)。P2 口:P2 是一带有内部上拉电阻的 8 位双向的 I/O 端口。P2 口的输出缓冲能驱动 4 个 TTL 逻辑门电路。当向 P2 口写 1 时,通过内部上拉电阻把端口拉到高电平,此时可以用作输入口。作为输入口,因为内部存在上拉电阻,某个引脚被外部信号拉低时会输出电流(IIL)。P2 口在访问外部程序存储器或 16 位地址的外部数据存储器(例如 MOVX DPTR)时,P2 口送出高 8 位地址数据。在这种情况下,P2 口使用强大的内部上拉电阻功能当输出 1 时。当利用 8 位地址线访问外部数据存储器时(例 MOVX R1),P2口输出特殊功能寄存器的内容。当 EPROM 编程或校验时,P2 口同时接收高 8 位地址和一些控制信号。P3 口:P3 是一带有内部上拉电阻的 8 位双向的 I/O 端口。P3 口的输出缓冲能驱动 4 个 TTL 逻辑门电路。当向 P3 口写 1 时,通过内部上拉电阻把端口拉到高电平,此时可以用作输入口。作为输入口,因为内部存在上拉电阻,某个引脚被外部信号拉低时会输出电流(IIL)。P3 口同时具有 AT89C52 的多种特殊功能,具体如下表 1 所示:端口引脚第二功能图 89S52 引脚图-第 6 页P3.0RXD(串行输入口)P3.1TXD(串行输出口)P3.20INT(外部中断 0)P3.31INT(外部中断 1)P3.4T0(定时器 0)P3.5T1(定时器 1)P3.6WR(外部数据存储器写选通)P3.7RD(外部数据存储器都选通)表 1P3 口的第二功能RST:复位输入。当振荡器工作时,RST 引脚出现两个机器周期的高电平将使单片机复位。ALE/PROG:当访问外部存储器时,地址锁存允许是一输出脉冲,用以锁存地址的低 8 位字节。当在 Flash 编程时还可以作为编程脉冲输出(PROG)。一般情况下,ALE 是以晶振频率的 1/6 输出,可以用作外部时钟或定时目的。但也要注意,每当访问外部数据存储器时将跳过一个 ALE 脉冲。PSEN:程序存储允许时外部程序存储器的读选通信号。当 AT89S52 执行外部程序存储器的指令时,每个机器周期PSEN两次有效,除了当访问外部数据存储器时,PSEN将跳过两个信号。EA/VPP:外部访问允许。为了使单片机能够有效的传送外部数据存储器从0000H 到 FFFH 单元的指令,EA必须同 GND 相连接。需要主要的是,如果加密位 1 被编程,复位时 EA 端会自动内部锁存。当执行内部编程指令时,EA应该接到 VCC 端。XTAL1:振荡器反相放大器以及内部时钟电路的输入端。XTAL2:振荡器反相放大器的输出端。4.24.2 电路总体设计电路总体设计LCD 定时闹钟,是以单片机及外围接口电路为核心硬件,辅以其他外围硬件电路,用 C语言设计的程序来实现的。根据 C51 单片机的外围接口特点扩展相应的硬件电路,然后根据单片机的指令设计出数字钟相应的软件,再利用软件执行一定的程序来实现数字钟的功能。-第 7 页由于采用集成芯片性的单片机来制作电子钟,这样设计制作简单而且功能多、精确度高,也可方便扩充其他功能,实现也十分简单。本设计是利用 AT89C52 单片机为主控芯片,由 LCD、电阻、电容、按键、蜂鸣器等元件组成硬件电路,通过编写软件程序来实现和控制的数字定时闹钟4.34.3 主程序流程图主程序流程图开始开始NNNN5 5、详细设计、详细设计5.15.1 硬件电路设计硬件电路设计5.1.15.1.1 所需硬件所需硬件1主控芯片 AT89C52(或 AT89C51)单片机2上拉电阻 respack-83液晶显示器(LM016L)LCD 1AT89C52震荡电路调时电路蜂鸣器LCD片选代码系统初始定时器初始化定时器初始化串口初始化显示待机指示符设定闹铃时间设 置 闹 铃 时 间显示刷新启动走时有关变量初始化刷新显示判断复位状况秒指示判断时间是否变闹铃判是否到闹铃时延时YYYY结束-第 8 页4蜂鸣器 speaker5.1.25.1.2 单片机硬件资源分配单片机硬件资源分配1、时-分功能的控制键接口:P1.0 连接按键 K1P1.2 连接按键 K2P1.3 连接按键 K3P1.4 连接按键 K4RST连接复位键 K5P3.4 连接蜂鸣器P0.0/AD0P0.7/AD7 依次接 LCD1(LM016L)的 0007,为数据线连接2、时-分-秒功能的控制接口:P1.0 连接按键 K1P1.1 连接按键 K2P1.2 连接按键 K3P1.3 连接按键 K4P1.4 连接按键 K4RST连接复位键 K6P3.4 连接蜂鸣器P0.0/AD0P0.7/AD7 依次接 LCD1(LM016L)的 0007,为数据线连接5.1.35.1.3 本本 LCDLCD 电子闹钟的特点和功能介绍电子闹钟的特点和功能介绍数字钟介绍数字钟介绍时钟是将小时、分钟、秒显示于人的肉眼的计时装置。而单片机模块中最常见的正是数字钟,数字钟是一种用数字电路技术实现时、分、秒计时的装置,与机械式时钟相比具有更高的准确性和直观性,且无机械装置,具有更长的使用寿命,因此得到了广泛的使用。而LCD 电子定时闹钟是以单片机为基础的数字电路实现对时、分、秒的数字显示的数字计时装置,它的计时周期为 24 小时,另外应有校时功能和闹钟等附加功能。一个基本的数字钟电路主要由译码显示器、“时”,“分”,“秒”,“星期”计数器、校时电路、报时电路和振荡器组成。目前电子钟广泛用于各种私人和公众场合,成为我们生活、工作和学习中不可缺少的好帮手。16021602LCDLCD 液晶液晶显示显示器介绍器介绍为了获得更好的效果,本设计并没有采用常见的 LED,而是采用了型号为 LM016L(1602)-第 9 页的 LCD。LCD 有比 LED 数码显示更好更直观的效果,也更加经久耐用。液晶显示模块体积小、功耗低、显示内容丰富,现在字符型液晶显示模块已经是单片机应用设计中最常用的信息显示器件之一了。本 LCD 是 2 行 16 列液晶,可显示 2 行 16 列英文字符,有 8 位数据总线 D0-D7,RS,R/W,E 三个控制端口(共 14 线),工作电压为 5V。没背光,和常用的 1602B 功能和引脚一样(除了调背光的二个线脚)。D4-D7 作为四位数据分两次传送。这样的话可以节省 MCU 的 I/O 口资源。引脚说明,见表 3.1。VDD:电源正极,4.55.5V,通常使用 5V 电压;RS:MCU 写入数据或者指令选择端。MCU 要写入指令时,使 RS 为低电平;MCU 要写入数据时,使 RS 为高电平;R/W:读写控制端。R/W 为高电平时,读取数据;R/W 为低电平时,写入数据;E:LCD 模块使能信号控制端。写数据时,需要下降沿触发模块。D0D7:8 位数据总线,三态双向。如果 MCU 的 I/O 口资源紧张的话,该模块也可以只使用 4 位数据线 D4D7 接口传送数据。本充电器就是采用 4 位数据传送方式;表 3.1LCD1(LM016L)显示屏引脚说明编号符号引脚说明编号符号引脚说明1VSS电源,接地9D2双向数据口2VDD电源,接+5V10D3双向数据口3VEE电源,LCD 亮度调节。电压越低,屏幕越亮。11D4双向数据口4RS数据/命令选择12D5双向数据口5R/W读/写选择13D6双向数据口6E模块使能端14D7双向数据口-第 10 页5.25.2 软件设计软件设计5.2.15.2.1 软件设计概述软件设计概述这里用 C 的单片机程序构成了本 LCD 电子闹钟的软件系统。该程序实现时间及定时(时间以 0 点 0 分 0 秒为基准计算,闹铃定时以 0 时 0 分为基准计算)的显示,有外部中断 0 和五个开关实现校时,闹钟功能。其中程序的晶振频率为 12MHz,最小计时单位为 1/20 秒。主芯片 p0.1-p0.7 输出数据到 LCD 数据总线,p3.0-p3.2 输出 LCD 控制信号,P2.6 输出声音信号,.P1.0-P1.3 输入外部控制信号,整个软件系统也是根据这个关系连接成一个完整的系统。1、程序初始化在系统开始通电时,需要.首先初始化液晶:void TimeInit()write_com(0 x01);/初始化 1602 液晶write_com(0 x80);/设置现实初始坐标for(num=0;num9;num+)/显示时分秒write_date(tablenum);delay(5);write_com(0 x80+0 x40+6);/写出时间显示部分的两个冒号write_date(:);delay(5);write_com(0 x80+0 x40+9);write_date(:);delay(5);write_sfm(4,shi);/分别送去液晶显示write_com(0 x80+0 x40+4);write_sfm(7,fen);write_com(0 x80+0 x40+7);write_sfm(10,miao);write_com(0 x80+0 x40+10)-第 11 页2、闹钟的实现闹钟功能的实现涉及到两个方面:闹铃时间设定和是否闹铃判别与相应处理。闹铃时间设定模块的设计可参照时间设定模块,这里着重阐述闹铃判别与处理模块的设计问题。闹铃判别与闹铃处理的关键在于判别何时要进行闹铃。当时-十位、时-个位、分-十位、分-个位中任一位发生改变(进位)时,就必须进行闹铃判别。程序设计思想如图 4.3。8图 4.3N3、显示程序显示程序包括时钟显示和定时显示程序。具体程序见附录。液晶显示模块是一个慢显示器件,所以在执行每条指令之前一定要确认模块的忙标志为低电平,表示不忙,否则此指令失效。要显示字符时需先输入显示字符地址,也就是告诉模块在哪里显示字符,表 4.1 是 LM016LLCD1 液晶模块的内部显示地址。15表 4.1内部显示地址12345678910111213141516000102030405060708090A0B0C0D0E0F404142434445464748494A4B4C4D4E4F、硬件原理图、硬件电路图5.2.2 程序代码如下:1、显示时-分:#include/reg52.h 是 AT89C52 的头文件#define uint unsigned int#define uchar unsigned charuchar code table=NOW TIME:;uchar code table1=SET NOW TIME:;uchar code table2=SET ALARM TIME:;uchar code alarm=ALARM TIME:;uchar code alarmoff=ALARM TIME:OFF;uchar code alarmon=ALARM TIME:ON;sbit lcden=P32;/定义 icden 的地址为 P3.2(以下的 sbit 命令以此类推)sbit lcdrs=P30;sbit lcdrw=P31;sbit K1=P10;sbit K2=P11;时十位、个位,分十位、个位改变了设置闹铃标志是否设置了闹铃清除闹铃标志判当前时间是设定时间中断返回中断返回闹铃判别处理-第 12 页sbit K3=P12;sbit K4=P13;sbit beep=P26;uchar flag,num,count,k1num,k2num,k3num,k4num;char miao,shi,fen,ashi,afen;void delay(uint z)/延时函数uint x,y;for(x=z;x0;x-)for(y=110;y0;y-);void di()/蜂鸣器子程序beep=0;delay(100);beep=1;void write_com(uchar com)/写命令函数lcdrs=0;lcdrw=0;lcden=0;P0=com;delay(5);lcden=1;delay(5);lcden=0;void write_date(uchar date)/写数据函数lcdrs=1;lcdrw=0;lcden=0;P0=date;delay(5);lcden=1;delay(5);lcden=0;void write_sfm(uchar add,uchar date)/写时间函数uchar shi,ge;shi=date/10;ge=date%10;write_com(0 x80+0 x40+add);write_date(0 x30+shi);write_date(0 x30+ge);void TimeInit()/显示时间初始化write_com(0 x01);write_com(0 x80);for(num=0;num9;num+)write_date(tablenum);delay(5);-第 13 页write_com(0 x80+0 x40+6);write_date(:);delay(5);write_com(0 x80+0 x40+9);write_date(:);delay(5);write_sfm(4,shi);write_com(0 x80+0 x40+4);write_sfm(7,fen);write_com(0 x80+0 x40+7);write_sfm(10,miao);write_com(0 x80+0 x40+10);void SetNowTime()/设置当前时间if(K1=0)delay(5);if(K1=0)while(!K1);di();shi+;if(shi=24)shi=0;write_sfm(4,shi);write_com(0 x80+0 x40+4);if(K2=0)delay(5);if(K2=0)while(!K2);di();fen+;if(fen=60)fen=0;write_sfm(7,fen);write_com(0 x80+0 x40+7);if(K3=0)delay(5);if(K3=0)while(!K3);di();k1num=0;TR0=1;TimeInit();void SetAlarmTime()/设置闹钟时间flag=0;if(K1=0)-第 14 页delay(5);if(K1=0)while(!K1);di();ashi+;if(ashi=24)ashi=0;write_sfm(4,ashi);write_com(0 x80+0 x40+4);if(K2=0)delay(5);if(K2=0)while(!K2);di();afen+;if(afen=60)afen=0;write_sfm(7,afen);write_com(0 x80+0 x40+7);if(K3=0)delay(5);if(K3=0)while(!K3);di();k3num=0;EA=1;flag=1;TimeInit();void DisplayAlarmTime()/显示闹钟函数write_com(0 x01);write_com(0 x80);for(num=0;num11;num+)write_date(alarmnum);delay(5);write_com(0 x80+0 x40+6);write_date(:);delay(5);write_sfm(4,ashi);write_com(0 x80+0 x40+4);write_sfm(7,afen);write_com(0 x80+0 x40+7);void keyscan()/键盘扫描函数if(K1=0)delay(5);-第 15 页if(K1=0)TR0=0;while(!K1);di();k1num+;if(k1num!=0)write_com(0 x80);for(num=0;num13;num+)write_date(table1num);delay(5);SetNowTime();elseif(K2=0)delay(5);if(K2=0)while(!K2);di();k2num+;if(k2num=1)EA=0;DisplayAlarmTime();k2num=2;if(k2num=3)k2num=0;EA=1;TimeInit();elseif(K3=0)delay(5);if(K3=0)while(!K3);di();k3num+;write_com(0 x01);if(k3num=1)EA=0;write_com(0 x80);for(num=0;num15;num+)write_date(table2num);delay(5);write_com(0 x80+0 x40+6);write_date(:);delay(5);write_sfm(4,ashi);-第 16 页write_com(0 x80+0 x40+4);write_sfm(7,afen);write_com(0 x80+0 x40+7);SetAlarmTime();elseif(K4=0)delay(5);if(K4=0)while(!K4);di();k4num+;if(k4num=1)di();k4num=2;flag=0;if(k4num=3)k4num=0;di();delay(500);di();delay(500);di();flag=1;if(flag=1&shi=ashi&fen=afen)beep=beep;delay(500);if(K4=0&flag=1)delay(5);if(K4=0&flag=1)while(!K4);di();flag=0;k4num=0;void init()/lcd1602 初始化lcden=0;shi=0;fen=0;miao=0;ashi=0;afen=0;count=0;k1num=0;write_com(0 x38);/设置 16X2 显示,5X7 点阵,8 位数据接口write_com(0 x0c);/设置开显示,不显示光标-第 17 页write_com(0 x06);/写一个字符后地址指针加 1write_com(0 x01);/显示清 0,数据指针清 0TimeInit();TMOD=0 x01;TH0=(65536-50000)/256;TL0=(65536-50000)%256;EA=1;ET0=1;TR0=1;void main()/主函数init();write_com(0 x80);while(1)keyscan();void timer0()interrupt 1/中断服务子程序TH0=(65536-50000)/256;TL0=(65536-50000)%256;count+;if(count=20)count=0;miao+;if(miao=60)miao=0;fen+;if(fen=60)fen=0;shi+;if(shi=24)shi=0;write_sfm(4,shi);write_sfm(7,fen);write_sfm(10,miao);4、单程序执行结果如下(秒计数):5、仿真执行结果如下:、按 K5 键-复位初始状态(NOW TIME)、按 K1 键(SET NOW TIME)(3)、按 K3 键(SET ALARM TIME)(4)、再按 K2 键即可定时 1 分钟或更长2、显示时-分-秒:#include/reg52.h 是 AT89C52 的头文件#define uint unsigned int#define uchar unsigned charuchar code table=NOW TIME:;/code 为程序储存器(即将语句NOW TIME存入程序以便显示)-第 18 页uchar code table1=SET NOW TIME:;uchar code table2=SET ALARM TIME:;uchar code alarm=ALARM TIME:;uchar code alarmoff=ALARM TIME:OFF;uchar code alarmon=ALARM TIME:ON;sbit lcden=P32;/定义 icden 的地址为 P3.2(以下的 sbit 命令以此类推)sbit lcdrs=P30;sbit lcdrw=P31;sbit K1=P10;sbit K2=P11;sbit K3=P12;sbit K4=P13;sbit K5=P14;sbit beep=P26;uchar flag,num,count,k1num,k2num,k3num,k4num,k5num;char miao,shi,fen,ashi,afen,amiao;void delay(uint z)/延时函数uint x,y;for(x=z;x0;x-)for(y=110;y0;y-);void di()/蜂鸣器子程序beep=0;delay(100);beep=1;void write_com(uchar com)/写命令函数lcdrs=0;lcdrw=0;lcden=0;P0=com;delay(5);lcden=1;delay(5);lcden=0;void write_date(uchar date)/写数据函数lcdrs=1;lcdrw=0;lcden=0;P0=date;delay(5);lcden=1;delay(5);lcden=0;void write_sfm(uchar add,uchar date)/写时间函数uchar shi,ge;-第 19 页shi=date/10;ge=date%10;write_com(0 x80+0 x40+add);write_date(0 x30+shi);write_date(0 x30+ge);void TimeInit()/显示时间初始化write_com(0 x01);write_com(0 x80);for(num=0;num9;num+)write_date(tablenum);delay(5);write_com(0 x80+0 x40+6);write_date(:);delay(5);write_com(0 x80+0 x40+9);write_date(:);delay(5);write_sfm(4,shi);write_com(0 x80+0 x40+4);write_sfm(7,fen);write_com(0 x80+0 x40+7);write_sfm(10,miao);write_com(0 x80+0 x40+10);void SetNowTime()/设置当前时间if(K1=0)delay(5);if(K1=0)while(!K1);di();shi+;if(shi=24)shi=0;write_sfm(4,shi);write_com(0 x80+0 x40+4);if(K2=0)delay(5);if(K2=0)while(!K2);di();fen+;if(fen=60)fen=0;write_sfm(7,fen);write_com(0 x80+0 x40+7);-第 20 页if(K3=0)delay(5);if(K3=0)while(!K3);di();miao+;if(miao=60)miao=0;write_sfm(10,miao);write_com(0 x80+0 x40+10);if(K4=0)delay(5);if(K4=0)while(!K4);di();k1num=0;TR0=1;TimeInit();void SetAlarmTime()/设置闹钟时间flag=0;if(K1=0)delay(5);if(K1=0)while(!K1);di();ashi+;if(ashi=24)ashi=0;write_sfm(4,ashi);write_com(0 x80+0 x40+4);if(K2=0)delay(5);if(K2=0)while(!K2);di();afen+;if(afen=60)afen=0;write_sfm(7,afen);write_com(0 x80+0 x40+7);if(K3=0)delay(5);if(K3=0)while(!K3);-第 21 页di();amiao+;if(amiao=60)amiao=0;write_sfm(10,amiao);write_com(0 x80+0 x40+10);if(K4=0)delay(5);if(K4=0)while(!K4);di();k4num=0;EA=1;flag=1;TimeInit();void DisplayAlarmTime()/显示闹钟函数write_com(0 x01);write_com(0 x80);for(num=0;num11;num+)write_date(alarmnum);delay(5);write_com(0 x80+0 x40+6);write_date(:);delay(5);write_com(0 x80+0 x40+6);write_date(:);delay(5);write_sfm(4,ashi);write_com(0 x80+0 x40+4);write_sfm(7,afen);write_com(0 x80+0 x40+7);write_sfm(10,amiao);write_com(0 x80+0 x40+10);void keyscan()/键盘扫描函数if(K1=0)delay(5);if(K1=0)TR0=0;while(!K1);di();k1num+;if(k1num!=0)write_com(0 x80);for(num=0;num13;num+)-第 22 页write_date(table1num);delay(5);SetNowTime();elseif(K2=0)delay(5);if(K2=0)while(!K2);di();k2num+;if(k2num=1)EA=0;DisplayAlarmTime();k2num=2;if(k2num=3)k2num=0;EA=1;TimeInit();elseif(K4=0)delay(5);if(K4=0)while(!K4);di();k4num+;write_com(0 x01);if(k4num=1)EA=0;write_com(0 x80);for(num=0;num15;num+)write_date(table2num);delay(5);write_com(0 x80+0 x40+6);write_date(:);delay(5);write_com(0 x80+0 x40+9);write_date(:);delay(5);write_sfm(4,ashi);write_com(0 x80+0 x40+4);write_sfm(7,afen);write_com(0 x80+0 x40+7);write_sfm(10,amiao);write_com(0 x80+0 x40+10);-第 23 页SetAlarmTime();elseif(K5=0)delay(5);if(K5=0)while(!K5);di();k5num+;if(k5num=1)di();k5num=3;flag=0;if(k5num=4)k5num=0;di();delay(500);di();delay(500);di();flag=1;if(flag=1&shi=ashi&fen=afen&miao=amiao)beep=beep;delay(500);if(K5=0&flag=1)delay(5);if(K5=0&flag=1)while(!K5);di();flag=0;k5num=0;void init()/lcd1602 初始化lcden=0;shi=0;fen=0;miao=0;ashi=0;afen=0;amiao=0;count=0;k1num=0;write_com(0 x38);/设置 16X2 显示,5X7 点阵,8 位数据接口write_com(0 x0c);/设置开显示,不显示光标write_com(0 x06);/写一个字符后地址指针加 1write_com(0 x01);/显示清 0,数据指针清 0-第 24 页TimeInit();TMOD=0 x01;TH0=(65536-50000)/256;TL0=(65536-50000)%256;EA=1;ET0=1;TR0=1;void main()/主函数init();write_com(0 x80);while(1)keyscan();void timer0()interrupt 1/中断服务子程序TH0=(65536-50000)/256;TL0=(65536-50000)%256;count+;if(count=10)count=0;miao+;if(miao=60)miao=0;fen+;if(fen=60)fen=0;shi+;if(shi=24)shi=0;write_sfm(4,shi);write_sfm(7,fen);write_sfm(10,miao);仿真结果(不加晶振电路)如图所示:加晶振电路:加晶振电路与不加晶振电路,结果看似相同但实践上晶振对控制电路来说极其重要,特-第 25 页别是对 CPU 有着举足轻重的作用。它在电路中的作用主要是提供频率稳定的时钟信号。6 6、结论、结论6 6.1.1 结果分析结果分析由实验结果,可以得出设计的程序和电路能够较好的完成课设预期的目标。刚开始定时器延时太小,运行后发现显示器显示不稳定,并且键盘扫描时,消抖不是非常理想,经过几次的尝试改变后,得到了一个比较满意的延迟时间。若延迟值太小,会使显示器显示不稳定;若值太大,会使数码管显示时间过短,达不到人眼视觉暂留的效果,达不到动态扫描的要求。6 6.2.2 心得体会心得体会这次课设紧随着课程的脚步,加深了我对 51 系列单片机的认识。上课老师主要给我们讲述了 51 单片机的汇编语言编程,通过这次课设我认识到在实际应用中往往 C 语言编程更常用,汇编语言一般只用于精确定时。而且以前编程都只是书面上的,没有真正嵌入到单片机中运行过。由此,我认识到单片机程序不是理想中怎么编,就能运行出符合要求的结果,需要和实际硬件结合,不断调试才能得出良好的效果。还有就是我对 51 单片机的认识还很浅薄,只是学会了一些最基础的操作。单片机理论的学习是为课程的设计作准备的,但有时学习的理论也解决不了实践中的问题。实践中获得的知识能让我对单片机的知识有更好的认识和理解。虽然这次的课程设计我参考了一些文献资料,没有做到创新,但在对程序的读写过程中我明白了许多。这次课程设计的最大收获是只有把理论用到实践中我们才能真正掌握好所学知识。设计总结设计总结通过此次单片机课程设计,我学到了了很多东西。在一个礼拜的学习与实