1、1课程设计定时打铃器的设计课程名称: 专业课程设计 学院名称: 南昌航空大学科技学院 专业: 电子信息工程 班级: 1482052 学号: 148205216 姓名: 彭少锟 同组人: 刘晶晶 指导教师: 评分: 20 17 年 6 月 19 日2摘 要 现代社会定时打铃器已广泛用于各种私人和公众场合,成为我们生活、工作和学习中不可缺少的好帮手,因此研究实用性更强的电子闹钟具有十分重要的意义。本设计是基于单片机的电子钟设计,不仅具有时分秒的显示功能,还具有定时打铃和倒计时的功能,实用性非常强。电子钟的计时部分采用 AT89S52 单片机内部定时器实现,而显示功能是采用液晶模块 LCD1602
2、来实现,该定时打铃器可以让使用者通过按键来轻松选择的功能菜单和调节时间,具有非常良好地人机界面。关键词:定时打铃器;倒计时;AT89S52;液晶 LCD1602;按键3目 录1 设计要求 12 方案论证 12.1 计时方案的选择 .12.2 显示方案的选择 .12.3 按键功能方案设计 .12.4 指示灯和响铃方案设计 .23 系统组成 24 硬件设计 24.1 单片机最小系统设计 .24.2 显示电路设计 .44.3 蜂鸣器电路设计 .44.4 按键电路设计 .55 软件设计 55.1 走时部分 .55.2 定时打铃检测部分 .65.3 键盘扫描部分 .65.4 液晶部分 .75.5 流程图
3、 .76 仿真设计 .117 系统调试及结果 .117.1 软件调试 117.2 硬件调试 137.3 调试结果 138 总结 .13参考文献 14附 录 1511 设计要求1.显示时钟格式:*时*分*秒。2.可任意设定时间达到定时控制,定时点至少有两个 3.可对设定的时间进行存取,实现掉电保护功能。3.定时时间到,打铃一分钟,自动关闭打铃继续计时。2 方案论证2.1 计时方案的选择1、采用专门的时钟芯片,例如美国 DALLAS 公司推出的 DS1302 实时时钟芯片,它的工作电压为 2.5V-5.5V,采用三线接口与 CPU 进行同步通信,并可采用突发式一次传送多个字节的时钟信号或 RAM
4、数据,优点是高性能、低功耗,可以对年、月、日、周日、时、分、秒进行计时,具有闰年补偿功能,但 DS1302 存在时钟精度不高,易受环境影响,出现时钟混乱等缺点,并且会增加电路硬件复杂性。2、采用 AT89S52 单片机内部定时器,51 系列单片机内部有两个 16 位定时器/ 计数器,简称定时器 0 和定时器 1,简称 T0 和 T1,设置 T0 工作在模式 0 状态下,每隔 50ms 中断一下,中断 20 次正好是 1 秒。用此方法的优点是可节少硬件设计,计时精度高,缺点是软件编程略显复杂。总结:综合两种方案的优缺点,以及此次课设的要求,选择第二种方案是用单片机内部定时器。因为使用该方案不但可
5、以节省硬件成本,还可以更锻炼自己使用单片机内部定时器和 C 语言编程的能力。2.2 显示方案的选择1、使用 LED 数码管,由多个 发光二极管封装在一起组成“8”字型的器件,引线已在内部连接完成,只需引出它们的各个笔划,公共电极。它能够在低电压、小电流的条件下驱动发光,发光响应时间极短,单色性好,亮度高,但是数码管显示内容单一,引脚与单片机I/0 连接复杂。2、使用液晶 LCD1602,液晶显示的原理是利用液晶的物理特性,通过电压对其显示区域进行控制,有电就有显示,LCD1602 是字符型液晶显示模块,它是一种专门用于显示字母、数字、符号等点阵式 LCD,并且显示质量高,功耗小。缺点是较数码管
6、成本高。总结:数码管显示内容单一,液晶则比较丰富,并且数码管消耗电力会比液晶更高,若选择数码管硬件布线会较复杂,影响美观性,而选择液晶也不会超过经费支持。综合两种方案的优缺点,选择方案二液晶显示。2.3 按键功能方案设计根据题目设计要求,定义 6 个 12*12mm 的按键来选择系统功能菜单和调节时间,分别为 K1、K2、K3、K4、K5、K6。2各个按键的具体功能如表 2.1: 表 2.1 按键功能表2.4 指示灯和响铃方案设计1、指示灯:综合设计要求和自我考虑,需要的指示灯个数为 4 个,分别为电源指示,程序运行指示和两个闹铃指示。为了加以区分可使用不同颜色的 LED。2、响铃选择:采用经
7、济适用的蜂鸣器,它是一种一体化结构的电子讯响器,采用直流电压供电,广泛应用于计算机、报警器、电子玩具、定时器等电子产品中作发声器件,而且驱动电路简单,由单片机一个 I/O 口外接一个三极管即可。3 系统组成经过以上的计时方案选择和显示方案选择,确定本设计的电子闹钟的计时方案为单片机内部定时,显示方案为液晶 LCD1602。闹铃的响铃来源选择经济适用的蜂鸣器,并用按键来选择功能菜单和调节时间,用 4 个不同颜色的发光二极管作为两个闹铃指示灯,程序运行指示灯和电源指示灯。因此系统组成框图如图 3.1:图 3.1 系统框图4 硬件设计4.1 单片机最小系统设计单片机最小系统的设计关键的就是时钟电路和
8、复位电路的设计。K1 选择调节时间菜单键及时增加键 K4 选择倒计时菜单键K2 选择调节闹铃 1 菜单键及分增加键 K5 关闭闹铃响声键K3 选择调节闹铃 2 菜单键及秒增加键 K6 确认键AT89S52 最小系统LCD1602蜂鸣器指示灯键盘31、时钟电路在这里使用单片机内部振荡电路,管脚 XTAL1、XTAL2 用来外接石英晶体和微调电容,如图 4.1 所示。晶体可在 1.212MHz 之间选择,电容可在 630pF 之间选择。图 4.1 时钟电路2、复位电路当振荡电路工作,并且在 RST 引脚加上一个至少保持两个机器周期的高电平时,就能完成一次复位。这里我使用按钮复位方式,如图 4.2,
9、利用 RC 微分电路产生正脉冲来达到复位目的,该正脉冲的持续时间大于两个机器周期。图 4.2 复位电路44.2 显示电路设计此设计的显示电路采用的是液晶模块 LCD1602,其为 5V 电压驱动,只有并行接口。其与单片机连接的硬件电路如图 4.3,其中的 D0-D7 分别连接到单片机的 P0.0-P0.7,VSS 接地, VDD 接+5V 电源,VEE 经 10K 电位器接地,用于调节背光,RS 端为向液晶控制器写数据 /写命令选择端,接单片机 P2.1 口,RW 为读 /写选择端,因为我们不从液晶读取任何数据,故接地,E 端为使能信号,接单片机 P2.2 口。图 4.3 液晶连接电路4.3
10、蜂鸣器电路设计电路设计如图 4.4,单片机的 P2.0 脚通过限流电阻 R 与三极管基极相接,集电极接蜂鸣器。当 P2.0 引脚电平为 0 是,三极管导通,蜂鸣器工作,引脚电平为 1 时,三极管截止,蜂鸣器不工作。因为单片机口输出低电平时的驱动能力比高电平强的多,故三极管采用基极低电平导通 PNP 型的三极管。5图 4.4 蜂鸣器驱动电路4.4 按键电路设计此次按键电路设计可直接将按键一端接到单片机的 I/O 口,另一端直接接地。通过单片机检测低电平判断按键按下,K1-K6 分别接至单片机的 P3.0-P3.5。按键电路如图 4.5:图 4.5 按键电路5 软件设计软件设计主要包含显示走时、闹
11、铃检测和键盘扫描三部分。5.1 走时部分走时部分主要有 3 个变量 hour、min、sec 和 deda 做为时钟的时、分、秒和定时标志位,通过单片机内部定时器定时 50ms,定时标志位 deda 加 1,此过程在中断服务程序中完成,当加满 20 次时,deda 清零并且时钟的秒 sec 加 1,从而到达计时目的。代码如下:void T0_srv(void) interrupt 1TH0=0x3C;TL0=0x0B0;deda+;void conv()6if(deda=20)sec+;deda=0;if(sec=60)min+;sec=0;ok=1;if(min=60)hour+;min=0
12、;if(hour=24)hour=0;5.2 定时打铃检测部分定时打铃检测部分主要的变量有 6 个,hh1、mm1 和 flag1 做为定时 1 的时、分和开关标志位,hh2、mm2 和 flag2 做为定时 2 的时、分和开关标志位,当hh1=hour,mm1=min 并且开关标志 flag1=1 时,定时 1 便可以执行响铃程序,当hh2=hour,mm2=min 并且开关标志 flag2=1 时,定时 2 便可以执行响铃程序,在这个子程序中为了不影响正常走时时间,故加上走时函数 time( )。代码如下:void alm_check1()while(alm_flag1=1)alm_led
13、1=0;beep=beep;delay(40);if(k5=0) alm_led1=1;beep=1;ok=0; 5.3 键盘扫描部分键盘扫面部分是该软件设计中较复杂的部分,用单片机 I/O 口检测低电平来判断是否有键按下,根据按下的键值来执行相应的子程序。在此部分增加一个标志变量 ok 做为子程序执行完毕的标志变量,在子程序执行过程中当 K6 键按下,则 ok=1,返回主程序。while(1)time();alm_check1();alm_check2();if(k1=0)set_time();7if(k2=0)set_atime1();if(k3=0)set_atime2();if(k4=
14、0)set_countdown(); 5.4 液晶部分液晶 LCD1602 做为本设计的显示元件,其初始化程序如下:void TS1602_INIT(void)RS=0;write_com(0x38); /设置 16*2 显示,5*7 点阵,8 位数据接口write_com(0x0c); /设置开显示,不显示光标write_com(0x06); /写一个字符后地址指针自动加 1write_com(0x01); /清屏5.5 流程图1、主程序流程图,如图 5.1:图 5.1 主程序流程图2、中断服务流程图: 如图 5.2:开始初始化显示时间闹铃检测键盘扫描8图 5.2 中断服务流程图2、时间流程
15、图,如图 5.3:图 5.3 时间流程图3、闹铃检测流程图,如图 5.4:d e d a = 2 0 ?d e d a = 0 , 秒 s e c 加 1s e c = 6 0 ?YS e c = 0 , 分钟 m i n 加 1m i n = 6 0 ?m i n = 0 , 小时 h o u r 加 1返回主程序YYNNN开始开始重装定时器初值D e d a 加 1中断返回9图 5.4 闹铃检测流程图4、键盘扫描流程图,如图 5.5:开始闹铃 1 时间到 ?闹铃 2 时间到 ?YNYN闹铃1 分钟到或 K 5 摁下N返回主程序Y10图 5.5 键盘扫面流程图开始K 1 是否按下 ?K 2
16、是否按下 ?K 3 是否按下 ?K 4 是否按下 ?设置走时时间设置闹铃 2设置倒计时K 1 是否按下 ?K 2 是否按下 ?K 3 是否按下 ?K 6 是否按下 ?H o u r 加 1m i n 加 1s e c 加 1确定 o k返回主程序K 1 是否按下 ?K 2 是否按下 ?K 3 是否按下 ?K 4 是否按下 ?h h 1 加 1m m 1 加 1F l a g = 1F l a g = 0K 2 是否按下 ? 确定 o k是否按下 ?是否按下 ?是否按下 ?是否按下 ?加加F l a g 1 = 1F l a g 1 = 0K 6 是否按下 ? 确定返回主程序K 1 是否按下 ?
17、K 2 是否按下 ?K 3 是否按下 ?K 4 是否按下 ?K 6 是否按下 ?h h 2 加 1m m 2 加 1F l a g 2 = 1F l a g 2 = 0确认 o k返回主程序返回主程序K 1 是否按下 ?K 2 是否按下 ?K 3 是否按下 ?K 6 是否按下 ?C _ h o u r 加 1C _ m i n 加 1C _ s e c 加 1确认 o k显示倒计时K 5 是否按下 ?返回主程序YYNNNYYYYNNNNYYYYYNNNNNYYYYNNNNYYYYYNNNNN设置闹铃 2YNYNY116 仿真设计仿真设计是设计一个系统十分重要的环节,在实际电路做好之前系统软件调
18、试最好选择。此次仿真设计采用的是英国 Labcenter electronics 公司出版的EDA 工具软件 Protues,在 PROTUES 绘制好原理图后,调入已编译好的 目标代码文件:*.HEX ,可以在 PROTUES 的原理图中看到模拟的实物运行状态和过程。仿真电路图如下,图 6.1:图 6.1 仿真电路图7 系统调试及结果7.1 软件调试此时设计的软件调试部分主要在仿真软件 Protues 中完成。首先根据硬件设计在 Protues 中完成原理图的设计,确定使用单片机的哪些I/O 口,然根据软件设计中的流程图编写单片机 C 语言程序。结合题目要求模块化地编写程序,首先编写走时程序
19、,然后编写闹铃 1、闹铃 2、的程序,最后完成倒计时设计,在分模块化编写过程中,不断地根据仿真现象调试程序来修复软件编写错误。12例如调试液晶的显示问题,写指令 write_com(0x80)将数据指针定位到第一行第一个字处,当写第二行时需要重新定位数据指针,写指令write_com(0x80+0x40)。再者,在显示倒计时时出现走时时间不准确的问题,故在倒计时变量处理的程序中要加上正计时走时时间变量处理,C_sec 、C_min、C_hour 是倒计时时间变量,sec、min、hour 是走时时间变量。程序如下: void C_conv( )if(deda=20)C_sec-;sec+;de
20、da=0;if(C_sec#define uchar unsigned char#define uint unsigned int#define TS1602_DATA P0 sbit routine_led=P10;sbit alm_led1=P11;sbit alm_led2=P12; sbit E=P22;sbit RS=P21;sbit beep=P20;sbit k1=P30;sbit k2=P31;sbit k3=P32;sbit k4=P33;sbit k5=P34;17sbit k6=P35;uchar i,j;uchar hour=0,min=0,sec=0;uchar hh
21、1=0,mm1=0,hh2=0,mm2=0;uchar alm_flag1=0,alm_flag2=0;uchar deda=0;char C_hour=0,C_min=0,C_sec=0;uchar ok=0;uchar string1=“Time: : :“;uchar string2=“ : F : F“;uchar string3=“ : N : F“;uchar string4=“ : F : N“;uchar string5=“ : N : N“;uchar string6=“Countdown_time:“;uchar string7=“ : :“;uchar code lcd_
22、code=“0123456789“;void delay(uint x) uint i,j;for(i=0;i=20)sec+;deda=0;if(sec=60)min+;sec=0;ok=1;if(min=60)hour+;min=0;if(hour=24)hour=0;/*/函数功能:显示走时时间/*void disp_time()write_com(0x80+0x05);display_num(hour);delay(1);write_com(0x80+0x08);display_num(min);delay(1);write_com(0x80+0x0B);display_num(sec
23、);delay(1);21/*/函数功能:倒计时分秒转换程序/*void C_conv()if(deda=20)C_sec-;sec+;deda=0;if(C_sec0)C_sec=59; C_min-;if(sec=60)min+;sec=0;if(C_min0)C_hour-;C_min=59;if(min=60)hour+;min=0;if(hour=24)hour=0;if(C_hour0)C_sec=0;C_min=0;C_hour=0;for(i=0;i10;i+)routine_led=routine_led;beep=beep;delay(80);ok=1;/*/函数功能:显示
24、倒计时时间/*void disp_Countdown_time()write_com(0x80+0x40);display_num(C_hour);delay(1);write_com(0x80+0x43);display_num(C_min);delay(1);write_com(0x80+0x46);22display_num(C_sec);delay(1);/*/函数功能:调用走时时间程序函数/*void time()conv();disp_time();/*/函数功能:调用倒计时时间程序函数/*void Ctime()C_conv();disp_Countdown_time();/*/
25、函数功能:显示闹铃 1 时间/*void disp_alm1()write_com(0x80+0x40);display_num(hh1);delay(1);write_com(0x80+0x43);display_num(mm1);delay(1);/*/函数功能:显示闹铃 2 时间/*void disp_alm2()23write_com(0x80+0x48);display_num(hh2);delay(1);write_com(0x80+0x4B);display_num(mm2);delay(1);/*/函数功能:调整时间/*void set_time() delay(500);TR
26、0=0;sec=0;ok=0;while(ok=0)if(k1=0)delay(100);if(k1=0)hour+;if(hour=24)hour=0;delay(5);disp_time();if(k2=0)delay(100);if(k2=0)min+;if(min=60)min=0;delay(5);disp_time();if(k3=0)delay(100);if(k3=0)sec+;if(sec=60)sec=0;delay(5);disp_time();if(k6=0)ok=1;TR0=1;24/*/函数功能:调整闹铃 1/*void set_atime1()alm_led1=0
27、;delay(500);ok=0;while(ok=0)if(k1=0)delay(100);if(k1=0)hh1+;if(hh1=24)hh1=0;delay(5);disp_alm1();if(k2=0)delay(100);if(k2=0)mm1+;if(mm1=60)mm1=0;delay(5);disp_alm1();if(k3=0)alm_flag1=1;if(alm_flag1=0) disp_alm1();disp_alm2();if(alm_flag1=1) disp_alm1();disp_alm2();if(alm_flag1=0) disp_alm1();disp_a
28、lm2();if(alm_flag1=1) disp_alm1();disp_alm2(); if(k4=0)alm_flag1=0;if(alm_flag1=0) 25disp_alm1();disp_alm2();if(alm_flag1=1) disp_alm1();disp_alm2();if(alm_flag1=0) disp_alm1();disp_alm2();if(alm_flag1=1) disp_alm1();disp_alm2(); if(k6=0) ok=1;time();alm_led1=1;/*/函数功能:调整闹铃 2/*void set_atime2()alm_l
29、ed2=0;delay(1000);ok=0;while(ok=0)if(k1=0)delay(100);if(k1=0)hh2+;if(hh2=24)hh2=0;delay(5);disp_alm2();if(k2=0)delay(100);if(k2=0)mm2+;if(mm2=60)mm2=0;delay(5);disp_alm2();if(k3=0)26alm_flag2=1;if(alm_flag1=0) disp_alm1();disp_alm2();if(alm_flag1=1) disp_alm1();disp_alm2();if(alm_flag1=0) disp_alm1(
30、);disp_alm2();if(alm_flag1=1) disp_alm1();disp_alm2(); if(k4=0)alm_flag2=0;if(alm_flag1=0) disp_alm1();disp_alm2();if(alm_flag1=1) disp_alm1();disp_alm2();if(alm_flag1=0) disp_alm1();disp_alm2();if(alm_flag1=1) disp_alm1();disp_alm2(); if(k6=0) ok=1;time();alm_led2=1;/*/函数功能:调整倒计时时间/*void set_countd
31、own()write_com(0x01);display_string1(string6);display_string2(string7);ok=0;27while(ok=0) conv();if(k1=0)delay(100);if(k1=0)C_hour+;if(C_hour=24)C_hour=0;if(k2=0)delay(100);if(k2=0)C_min+;if(C_min=60)C_min=0;delay(5);disp_Countdown_time();if(k3=0)delay(100);if(k3=0)C_sec+;if(C_sec=60)C_sec=0;delay(5);disp_Countdown_time();if(k6=0)ok=1;/*/函数功能:检查闹铃 1 时间程序/*void alm_check1()while(alm_flag1=1)alm_led1=0;beep=beep;delay(40);if(k5=0) alm_led1=1;beep=1;ok=0; /*/函数功能:检查闹铃 2 时间程序