1、前 言20世纪末,电子技术取得了飞速发展。在其推进下,现代电子产品几乎渗透了社会各个领域,有力地推进了社会生产力发展和社会信息化程度提升。同时也使现代电子产品性能深入提升,产品更新换代节奏也越来越快。 时间对大家来说总是那么宝贵,工作忙碌性和繁杂性轻易使人忘记目前时间。忘记了要做事情,当事情不是很关键时候,这种遗忘无伤大雅。不过,一旦关键事情,一时耽搁可能酿成大祸。比如,很多火灾全部是因为大家一时忘记了关闭煤气或是忘记充电时间。所以有必需制作一个定时系统。随时提醒这些轻易忘记时间人。 而钟表数字化给大家生产生活带来了极大方便,而且大大地扩展了钟表原先报时功效。诸如定时自动报警、按时自动打铃、时
2、间程序自动控制、定时广播、定时启闭电路、定时开关烘箱、通断动力设备,甚至多种定时电气自动启用等等。全部这些,全部是以钟表数字化为基础。所以,研究数字钟及扩大其应用,有着很现实意义。伴随生活水平提升,大家越来越追求人性化事物。传统时钟已不能满足大家需求。而现代时钟不仅需要模拟电路技术和数字电路技术而且更需要单片机技术,增加数字钟功效。利用软件编程尽可能做到硬件电路简单稳定,减小电磁干扰和其它环境干扰,减小因元器件精度不够引发误差,不过数字钟还是能够改善和提升如选择更精密元器件。但和机械式时钟相比已经含有更高正确性和直观性,且无机械装置,含有更长使用寿命,所以得到了广泛使用。数字钟经过数字电路实现
3、时、分、秒。数字显示计时装置,广泛用于个人家庭、车站、码头办公室等公共场所成为大家日常生活中不可少必需品。因为数字集成电路发展和石英晶体振荡器广泛应用,使得数字钟精度远远超出传统钟表。多功效数字钟应用很普遍。由单片机作为数字钟关键控制器,经过它时钟信号进行实现计时功效,将其时间数据经单片机输出,利用显示器显示出来。经过键盘能够进行校时、定时等功效。输出设备显示器能够用液晶显示技术和数码管来显示技术。 本系统利用单片机实现含有计时、校时等功效数字时钟,是以单片机STC89C52为关键元件同时采取LCD1602显示“时”、“分”、“秒”现代计时装置。另外含有校时功效,秒表功效,定时器功效和继电器控
4、制外围电路功效,利用单片机实现数字时钟含有编程灵活,便于功效扩充等优点。目 录前 言1摘 要I第1章 课题背景11.1 课题起源11.2 课题研究目标和意义11.3应处理关键问题及达成技术要求2第2章 方案选择和论证32.1 单片机型号选择32.2 按键选择32.3 显示器选择32.4 计时部分选择32.5 发音部分设计42.6 显示器驱动电路42.7 电源选择4第3章 数字电子钟设计原理和方法53.1 设计原理53.2 硬件电路设计53.2.1 STC89C52单片机介绍53.2.2 键盘电路设计63.2.3 时钟电路63.2.4 蜂鸣器驱动电路63.2.5 继电器电路73.2.6 LCD1
5、602电路73.2.7 复位电路83.3 软件部分设计83.3.1 主程序部分设计8总 结11附 录12摘 要单片机自20世纪70年代问世以来,以其极高性能价格比,受到大家重视和关注,应用很广、发展很快。而51单片机是各单片机中最为经典和最有代表性一个。本设计以STC89C52芯片为关键,辅以必需外围电路,设计了一个结构简单,功效齐全电子时钟,它由5V直流电源供电。在硬件方面,除了CPU外,使用LCD1602来进行显示。软件方面采取C语言编程。整个电子钟系统能完成时间显示、调时、校时和三组定时闹钟功效。选择单片机最小系统应用程序,添加比较程序、时间调整程序及蜂鸣程序,经过时间比较程序触发蜂鸣,
6、实现闹钟功效,完成设计所需求软件环境。介绍并使用Keil单片机模拟调试软件,测试程序可行性并用Proteus进行仿真。关键词:单片机,定时器,中止,闹钟,LCD1602 第1章 课题背景1.1 课题起源伴随生活水平提升,大家越来越追求人性化事物,传统时钟已不能满足大家需求。现代时钟不仅需要模拟电路技术而且需要数字电路技术和单片机技术,增加时钟功效。数字电子钟可利用软件编程尽可能做到硬件电路简单稳定,减小电磁干扰和其它环境干扰,减小因元器件精度不够引发误差;尽管如此数字钟还是能够改善和提升,比如选择更精密元器件。但和机械式时钟相比已经含有更高正确性和直观性,且无机械装置,含有更长使用寿命,所以得
7、到了广泛使用。1.2 课题研究目标和意义20世纪末,电子技术取得了飞速发展,在其推进下,现代电子产品几乎渗透了社会各个领域,有力地推进了社会生产力发展和社会信息化程度提升,同时也使现代电子产品性能深入提升,产品更新换代节奏也越来越快。 时间对大家来说总是那么宝贵,工作忙碌性和繁杂性轻易使人忘记目前时间。忘记了要做事情,当事情不是很关键时候,这种遗忘无伤大雅。不过,一旦关键事情,一时耽搁可能酿成大祸。比如,很多火灾全部是因为大家一时忘记了关闭煤气或是忘记充电时间等造成。而钟表数字化给大家生产生活带来了极大方便。数字钟是经过数字电路实现时,分,秒数字显示计时装置,广泛用于个人家庭、车站、码头办公室
8、等公共场所,成为大家日常生活中不可少必需品。因为数字集成电路发展和石英晶体振荡器广泛应用,使得数字钟精度,远远超出传统钟表,钟表数字化给大家生产生活带来了极大方便,而且大大地扩展了钟表原先报时功效,诸如定时自动报警、按时自动打铃、时间程序自动控制、定时广播、自动起闭路灯、定时开关烤箱、通断动力设备、甚至多种定时电气自动启用等。全部这些,全部是以钟表数字化为基础。所以,研究数字钟及扩大其应用,有着很现实意义。1.3应处理关键问题及达成技术要求使用STC89C52单片机结合字符型LCD显示器设计一个简易定时闹钟LCD时钟,若LCD选择有背光显示模块,在夜晚或黑暗场所中也可使用。定时闹钟基础功效以下
9、: (1) 同时设置一个夜晚全芯片休眠功效,当定时时间到后,激活单片机同时开启报警,以起到一个节能作用。(2) 显示格式为“时时:分分”。(3) 由LED闪动来做秒计数表示。(4) 一旦时间到则发出声响,同时继电器开启,能够扩充控制家电开启和关闭。(5) 程序实施后工作指示灯LED闪动,表示程序开始实施,LCD显示“00:00”,按下操作键K1K4动作以下: K1设置现在时间。 K2显示闹钟设置时间。 K3设置闹铃时间。K4闹铃ON/OFF状态设置,设置为ON时连续三次发出“哗”一声,设置为OFF发出“哗”一声。设置目前时间或闹铃时间以下。K1时调整。K2分调整。K3设置完成。K4闹铃时间到时
10、,发出一阵声响,按下本键能够停止声响。第2章 方案选择和论证2.1 单片机型号选择经过对多个单片机性能分析,最终认为STC89C52是最理想电子时钟开发芯片。STC89C52是STC企业生产一个低功耗、高性能CMOS8位微控制器,含有 8K 在系统可编程Flash存放器。STC89C52使用经典MCS-51内核,但做了很多改善使得芯片含有传统51单片机不含有功效。在单芯片上,拥有灵巧8 位CPU 和在系统可编程Flash,使得STC89C52为众多嵌入式控制应用系统提供高灵活、超有效处理方案。2.2 按键选择方案一:44矩阵式键盘。假如选择此方案,那么在修改时钟或设置闹铃时间时就能够直接从键盘
11、输入,方便、快捷,但程序较为复杂。 方案二:独立式按键。假如设置过多按键,将会占用较多I/O口,而且会给布线带来不便,所以,此方案适适用于按键较少情况。假如选择此方案,因为按键较少,在修改时间或设置闹铃时间时就不能直接输入,只能经过加或减完成,稍为麻烦部分,但其程序简单。 因为并不需要常常修改时间和设置闹铃时间,而且方案二程序简单,按键少、成本低,所以,选择方案二。2.3 显示器选择方案一:液晶显示器。假如选择此方案,将会降低系统功耗,这么就能够用电池供电,便于携带。但液晶显示器驱动电路复杂,使用起来有一定难度。 方案二:用数码管作为显示器。数码管驱动电路简单,使用方便,其缺点是功耗较大。因为
12、液晶显示器功耗低,显示内容灵活,所以选择方案一。2.4 计时部分选择假如使用时钟芯片,系统就不怕掉电且时间正确。但这种芯片比较贵,况且,设计本系统关键是为了学习单片机程序编写和调试和设计硬件电路部分方法,所以采取软件方法来计时而没有采取价格较高时钟芯片。2.5 发音部分设计经过三极管放大后驱动蜂鸣器工作。2.6 显示器驱动电路采取LCD1602显示所需显示字符,需要用电位器调整背光。2.7 电源选择假如是用电池供电,就比较方便携带,但需要常常更换电池。况且,本系统体积较大,即使使用电池供电也不能随身携带,所以,用电池供电不大适宜,所以用5V外部稳压电源来供电。第3章 数字电子钟设计原理和方法3
13、.1 设计原理 系统原理图STC89C52LCD1602晶振继电器蜂鸣器按键图3-1 系统原理图3.2 硬件电路设计3.2.1 STC89C52单片机介绍STC89C52是STC企业生产一个低功耗、高性能CMOS8位微控制器,含有 8K 在系统可编程Flash存放器。STC89C52使用经典MCS-51内核,但做了很多改善使得芯片含有传统51单片机不含有功效。含有以下标准功效: 8k字节Flash,512字节RAM, 32 位I/O 口线,看门狗定时器,内置4KB EEPROM,MAX810复位电路,3个16 位定时器/计数器,4个外部中止,一个7向量4级中止结构(兼容传统515向量2级中止结
14、构),全双工串行口。3.2.2 键盘电路设计键盘采取4个独立按键实现对时钟和闹钟设定及修改。 3.2.3 时钟电路单片机时钟产生方法有两种:内部时钟方法和外部时钟方法。本系统中STC89C52单片机采取内部时钟方法。最常见内部时钟方法是采取外接晶体和电容组成并联谐振回路。振荡晶体可在1.2MHz12MHz之间。电容值无严格要求,但电容取值对振荡频率输出稳定性、大小和振荡电路起振速度有少许影响,通常可在20pF100pF之间取值3.2.4 蜂鸣器驱动电路发音部分是经过三极管放大驱动蜂鸣器工作,当闹钟开启时响三声,闹钟关闭时响一声。图3-6 蜂鸣器驱动电路3.2.5 继电器电路当单片机引脚输出高电
15、平时,三极管截止,继电器线圈两端没有电位差,继电器衔铁释放,同时状态指示发光二极管也熄灭,继电器常开触点释放,相当于开关断开。在三极管截止瞬间,因为线圈中电流不能突变为零,继电器线圈两端会产生一个较高电压感应电动势,线圈产生感应电动势则能够经过二极管IN4148释放,从而保护了三极管免被击穿,也消除了感应电动势对其它电路干扰,这就是二极管保护作用。3.2.6 LCD1602电路3.2.7 复位电路复位电路工作原理如上图所表示,VCC上电时,电容充电,在电阻上出现电压,使得单片机复位;多个毫秒后,电容充满,电阻上电流降为0,电压也为0,使得单片机进入工作状态。工作期间,按下按键,电容放电。松手,
16、电容又充电,在电阻上出现电压,使得单片机复位。总电路图3.3 软件部分设计3.3.1 主程序部分设计主程序步骤图以下图3-7。初始化设置开始和闹钟时间相同显示时间蜂鸣器响,继电器开启否是图 3-7主程序步骤图4个按键每个全部含有两个功效,以最终实现菜单化输入功效。采取经过逐层嵌套循环扫描,实现嵌套式键盘输入。当抵达所设定时间以后,蜂鸣器发出声音,而且继电器开启,以此控制连接外围器件。要达成按键含有多个功效,需在程序内设置变量,当按键按下和变量值同时满足实现一个功效,不一样时满足时实现另一个功效。第4章 试验结果此电子闹钟设计是先利用Proteus仿真软件进行仿真,实现了课程设计要求实现功效。然
17、后在使用AltiumDesigner绘制原理图和PCB,图3-14 运行仿真图实际电路运行图总 结经过自己不懈努力,我完成了单片机课程设计上任务要求。功效上达标:时钟显示,调时功效、校时功效、闹铃功效、闹钟设功效。其正确度完全能够满足日常生活显示时间需要;调时功效,方便快捷;校时功效确保了时钟正确和可靠性,经过继电器能够扩展多个外围电路可能。硬件设施合乎要求,软件设计能够配合硬件实现要求功效。可见技术在不停进步,机械式时钟已经被淘汰,取而代之是含有高度正确性和直观性且无机械装置,含有更长使用寿命等优点数字时钟。数字时钟更具人性化,更能提升大家生活质量,更受大家欢迎。 无可否认机械时代已经过去,
18、电子时代已经到来。做为新时代我们,更应该提升本身能力,适应新时代发展。知识来自实践,多去生活中探询所需要。对于上述所提到研究课题,我们应尽可能考虑到人原因,增强时钟实用性和操作性,为使用者提供切实方便,营造一个舒适生活气氛。所以,在设计时候,应该从多方面、多角度去考虑问题,而且应该深入提升时钟质量。另外,在此次设计过程中,我发觉很多问题,即使以前没有做过这么设计但经过这次设计我学会了很多东西,单片机课程设计关键就在于软件算法设计,需要有很巧妙程序算法,即使以前写过几次程序,但我觉写好一个程序并不是一件简单事,比如写一个程序看其功效极少认为编写程序简单,但到编程时候才发觉部分细微知识或低级错误常
19、常犯做不到最终常常失败,所以有些东西只有学精弄懂而且要细心才行,只学习理论有些东西是极难了解,更谈不上掌握。从这次课程设计中,我们真真正正意识到,在以后学习中,要理论联络实际,把我们所学理论知识用到实际当中,学习单机片机更是如此,程序只有在常常练习过程中才能提升,我想这就是我在这次课程设计中最大收获。附 录相关程序代码:#include#include#define uint unsigned int#define uchar unsigned char#define LCD1602_DB P0uchar code table=CurrentTime;uchar code table1=00:
20、00:00;uchar key1Flag = 0;uchar key2Flag = 0;uchar key3Flag = 0;uchar key4Flag = 0;uchar temp = 0;uchar sec = 0;uchar min = 0;uchar hour = 0;uchar clkHour = 0;uchar clkMin = 0;uchar clkFlag = 0;uchar beepNum = 0;uchar relayFlag = 1;sbit LCD1602_RS = P20;/数据/命令选择端(电平H/L)sbit LCD1602_RW = P21;/数据/命令选择端
21、(电平H/L)sbit LCD1602_E = P22;/使能信号sbit Key1 = P10;sbit Key2 = P11;sbit Key3 = P12;sbit Key4 = P13;sbit Led = P24;sbit Speaker = P25;sbit Relay = P23;void Delay1ms()/12.000MHzunsigned char i, j;i = 12;j = 169;dowhile (-j); while (-i);void Delay20ms()/12.000MHzunsigned char i, j, k;_nop_();_nop_();i =
22、1;j = 234;k = 113;dodowhile (-k); while (-j); while (-i);void Beep() Speaker = 0;Delay20ms();Speaker = 1;void LcdWaitReady()unsigned char sta;LCD1602_DB = 0xFF;LCD1602_RS = 0;LCD1602_RW = 1;doLCD1602_E = 1;sta = LCD1602_DB;LCD1602_E = 0;while(sta & 0x80);void LcdWriteCmd(unsigned char cmd)LcdWaitRea
23、dy();LCD1602_RS = 0;LCD1602_RW = 0;LCD1602_DB = cmd;LCD1602_E = 1;LCD1602_E = 0;void LcdWriteDat(unsigned char dat) LcdWaitReady();LCD1602_RS = 1;LCD1602_RW = 0;LCD1602_DB = dat;LCD1602_E = 1;LCD1602_E = 0;void LcdSetCursor(unsigned char x, unsigned char y) unsigned char addr;if(y = 0)addr = 0x00 +
24、x;elseaddr = 0x40 + x;LcdWriteCmd(addr | 0x80);void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str) LcdSetCursor(x, y);while(*str != 0)LcdWriteDat(*str+); void InitLcd1602() LcdWriteCmd(0x38);LcdWriteCmd(0x0C);LcdWriteCmd(0x06);LcdWriteCmd(0x01);void WriteAddress(uchar x) LcdWriteCm
25、d(0x80 + x);void DisplayMinTens() /显示分十位WriteAddress(0x49);LcdWriteDat(min / 10) + 0);Delay1ms();void DisplayMinUnits() /显示分个位WriteAddress(0x4A);LcdWriteDat(min % 10) + 0);Delay1ms();void DisplayHourTens() /显示时十位WriteAddress(0x46);LcdWriteDat(hour / 10) + 0);Delay1ms();void DisplayHourUnits() /显示时个位
26、WriteAddress(0x47);LcdWriteDat(hour % 10) + 0);Delay1ms();void DisplayClkMinTens() /显示时钟分十位WriteAddress(0x49);LcdWriteDat(clkMin / 10) + 0);Delay1ms();void DisplayClkMinUnits() /显示时钟分个位WriteAddress(0x4A);LcdWriteDat(clkMin % 10) + 0);Delay1ms();void DisplayClkHourTens() /显示时钟时十位WriteAddress(0x46);Lc
27、dWriteDat(clkHour / 10) + 0);Delay1ms();void DisplayClkHourUnits() /显示时钟时个位WriteAddress(0x47);LcdWriteDat(clkHour % 10) + 0);Delay1ms();void DisplayClkSecTens() /显示秒十位WriteAddress(0x4C);LcdWriteDat(sec / 10) + 0);Delay1ms();void DisplayClkSecUnits() /显示秒个位WriteAddress(0x4D);LcdWriteDat(sec % 10) + 0
28、);Delay1ms();void ScanKey4() if(Key4 = 0)&(clkFlag =1) Delay20ms();if(Key4 = 0)&(clkFlag =1) clkFlag = 0;beepNum = 0;key4Flag = 0;void InitTimer0() /初始化定时器0TMOD = 0x01; TH0 = (65536 - 50000) / 256;TL0 = (65536 - 50000) % 256;EA = 1;ET0 = 1;TR0 = 1;void main() InitLcd1602();LcdShowStr(0,0,table);LcdS
29、howStr(6,1,table1);InitTimer0();while(1) if(sec = 60) sec = 0;min+;if(min = 60) min = 0;hour+;if(hour = 24) hour = 0;LcdShowStr(0,0,table);DisplayHourTens();DisplayHourUnits();LcdShowStr(8,1,:);DisplayMinTens();DisplayMinUnits();LcdShowStr(11,1,:);DisplayClkSecUnits();DisplayClkSecTens();/=if(Key1 =
30、 0)&(key1Flag = 0) /设置目前时间Delay20ms();if(Key1 = 0)&(key1Flag = 0) TR0 = 0;InitLcd1602();LcdShowStr(0,0,SetCurrentTime);DisplayHourTens();DisplayHourUnits();LcdShowStr(8,1,:);DisplayMinTens();DisplayMinUnits();key1Flag = 1; while(key1Flag = 1) if(Key1 = 0) Delay20ms();if(Key1 = 0) hour+;if(hour = 24)
31、 hour = 0;DisplayHourTens();DisplayHourUnits();LcdShowStr(8,1,:);DisplayMinTens();DisplayMinUnits();if(Key2 = 0) Delay20ms();if(Key2 = 0) min+;if(min = 60) min = 0;hour+;DisplayHourTens();DisplayHourUnits();LcdShowStr(8,1,:);DisplayMinTens();DisplayMinUnits();if(Key3 = 0)&(key1Flag = 1) /退出设置目前时间Del
32、ay20ms();if(Key3 = 0)&(key1Flag = 1) InitLcd1602();LcdShowStr(0,0,table);DisplayHourTens();DisplayHourUnits();LcdShowStr(8,1,:);DisplayMinTens();DisplayMinUnits();LcdShowStr(11,1,:);DisplayClkSecUnits();DisplayClkSecTens();key1Flag = 0;TR0 = 1;/=if(Key2 = 0)&(key2Flag = 0)&(relayFlag = 1) /显示闹钟时间Del
33、ay20ms();if(Key2 = 0)&(key2Flag = 0)&(relayFlag = 1) key2Flag = 1;InitLcd1602();while(key2Flag = 1) LcdShowStr(0,0,Clock Time);DisplayClkHourTens();DisplayClkHourUnits();LcdShowStr(8,1,:);DisplayClkMinTens();DisplayClkMinUnits();if(Key2 = 0) Delay20ms();if(Key2 = 0) key2Flag = 0;InitLcd1602();Displa
34、yHourTens();DisplayHourUnits();LcdShowStr(8,1,:);DisplayMinTens();DisplayMinUnits();LcdShowStr(11,1,:);DisplayClkSecUnits();DisplayClkSecTens(); /=if(Key3 = 0)&(key3Flag = 0) /设置闹钟时间Delay20ms();if(Key3 = 0)&(key3Flag = 0) TR0 = 0;InitLcd1602();LcdShowStr(0,0,SetClockTime);DisplayClkHourTens();Displa
35、yClkHourUnits();LcdShowStr(8,1,:);DisplayClkMinTens();DisplayClkMinUnits();key3Flag = 1;while(key3Flag = 1) if(Key1 = 0) Delay20ms();if(Key1 = 0) clkHour+; if(clkHour = 24) clkHour = 0; DisplayClkHourTens(); DisplayClkHourUnits(); LcdShowStr(8,1,:); DisplayClkMinTens(); DisplayClkMinUnits();if(Key2
36、= 0) Delay20ms();if(Key2 = 0) clkMin+;if(clkMin = 60) clkHour+;clkMin = 0; DisplayClkHourTens(); DisplayClkHourUnits(); LcdShowStr(8,1,:); DisplayClkMinTens(); DisplayClkMinUnits();if(Key3 = 0) /退出设置闹钟时间Delay20ms();if(Key3 = 0) key3Flag = 0;InitLcd1602();TR0 = 1;DisplayHourTens();DisplayHourUnits();
37、LcdShowStr(8,1,:);DisplayMinTens();DisplayMinUnits();LcdShowStr(11,1,:);DisplayClkSecUnits();DisplayClkSecTens();/=if(Key4 = 0)&(key4Flag = 0) /闹钟ON/OFF位设置Delay20ms();if(Key4 = 0)&(key4Flag = 0) key4Flag = 1;InitLcd1602();LcdShowStr(0,0,Clock ON);Delay20ms();Beep();Delay20ms();Beep();Delay20ms();Bee
38、p();Delay20ms();Delay20ms();if(Key4 = 0)&(key4Flag = 1) /闹钟ON/OFF位设置Delay20ms();if(Key4 = 0)&(key4Flag = 1) key4Flag = 0;InitLcd1602(); LcdShowStr(0,0,Clock OFF);Beep();Delay20ms();Delay20ms();Delay20ms();Delay20ms();/=if(key4Flag = 1)&(hour = clkHour)&(min = clkMin) clkFlag = 1; /闹钟时间到InitLcd1602();LcdShowStr(0,0,Times up);Relay = 0;relayFlag = 0; /继电器吸合while(clkFlag = 1) Beep();ScanKey4();Delay20ms();ScanKey4();Delay20ms();ScanKey4();Delay20ms();ScanKey4();Delay20ms();ScanKey4();beepNum+;if(beepNum = 20) clkFlag = 0;beepNum = 0;key4Flag