资源描述
课程设计—定期打铃器设计
课程名称: 专业课程设计
学院名称: 南昌航空大学科技学院
专业: 电子信息工程
班级: 1482052
学号:
姓名: 彭少锟
同组人: 刘晶晶
指引教师:
评分:
20 17 年 6 月 19 日
摘 要
当代社会定期打铃器已广泛用于各种私人和公众场合,成为咱们生活、工作和学习中不可缺少好帮手,因而研究实用性更强电子闹钟具备十分重要意义。本设计是基于单片机电子钟设计,不但具备时分秒显示功能,还具备定期打铃和倒计时功能,实用性非常强。电子钟计时某些采用AT89S52单片机内部定期器实现,而显示功能是采用液晶模块LCD1602来实现,该定期打铃器可以让使用者通过按键来轻松选取功能菜单和调节时间,具备非常良好地人机界面。
核心词:定期打铃器;倒计时;AT89S52;液晶LCD1602;按键
目 录
1 设计规定 1
2 方案论证 1
2.1 计时方案选取 1
2.2 显示方案选取 1
2.3 按键功能方案设计 1
2.4 批示灯和响铃方案设计 2
3 系统构成 2
4 硬件设计 2
4.1 单片机最小系统设计 2
4.2 显示电路设计 4
4.3 蜂鸣器电路设计 4
4.4 按键电路设计 5
5 软件设计 5
5.1 走时某些 5
5.2 定期打铃检测某些 6
5.3 键盘扫描某些 6
5.4 液晶某些 7
5.5 流程图 7
6 仿真设计 11
7 系统调试及成果 11
7.1 软件调试 11
7.2 硬件调试 13
7.3 调试成果 13
8 总结 13
参照文献 14
附 录 15
1 设计规定
1.显示时钟格式:**时**分**秒。
2.可任意设定期间达到定期控制,定期点至少有两个 3.可对设定期间进行存取,实现掉电保护功能。
3.定期时间到,打铃一分钟,自动关闭打铃继续计时。
2 方案论证
2.1 计时方案选取
1、采用专门时钟芯片,例如美国DALLAS公司推出DS1302实时时钟芯片,它工作电压为2.5V-5.5V,采用三线接口与CPU进行同步通信,并可采用突发式一次传送各种字节时钟信号或RAM数据,长处是高性能、低功耗,可以对年、月、日、周日、时、分、秒进行计时,具备闰年补偿功能,但DS1302存在时钟精度不高,易受环境影响,浮现时钟混乱等缺陷,并且会增长电路硬件复杂性。
2、采用AT89S52单片机内部定期器,51系列单片机内部有两个16位定期器/计数器,简称定期器0和定期器1,简称T0和T1,设立T0工作在模式0状态下,每隔50ms中断一下,中断20次正好是1秒。用此办法长处是可节少硬件设计,计时精度高,缺陷是软件编程略显复杂。
总结:综合两种方案优缺陷,以及本次课设规定,选取第二种方案是用单片机内部定期器。由于使用该方案不但可以节约硬件成本,还可以更锻炼自己使用单片机内部定期器和C语言编程能力。
2.2 显示方案选取
1、使用LED数码管,由各种发光二极管封装在一起构成“8”字型器件,引线已在内部连接完毕,只需引出它们各个笔划,公共电极。它可以在低电压、小电流条件下驱动发光,发光响应时间极短,单色性好,亮度高,但是数码管显示内容单一,引脚与单片机I/0连接复杂。
2、使用液晶LCD1602,液晶显示原理是运用液晶物理特性,通过电压对其显示区域进行控制,有电就有显示,LCD1602是字符型液晶显示模块,它是一种专门用于显示字母、数字、符号等点阵式LCD,并且显示质量高,功耗小。缺陷是较数码管成本高。
总结:数码管显示内容单一,液晶则比较丰富,并且数码管消耗电力会比液晶更高,若选取数码管硬件布线会较复杂,影响美观性,而选取液晶也不会超过经费支持。综合两种方案优缺陷,选取方案二液晶显示。
2.3 按键功能方案设计
依照题目设计规定,定义6个12*12mm按键来选取系统功能菜单和调节时间,分别为K1、K2、K3、K4、K5、K6。
各个按键详细功能如表2.1:
K1
选取调节时间菜单键及时增长键
K4
选取倒计时菜单键
K2
选取调节闹铃1菜单键及分增长键
K5
关闭闹铃响声键
K3
选取调节闹铃2菜单键及秒增长键
K6
确认键
表2.1 按键功能表
2.4 批示灯和响铃方案设计
1、批示灯:综合设计规定和自我考虑,需要批示灯个数为4个,分别为电源批示,程序运营批示和两个闹铃批示。为了加以区别可使用不同颜色LED。
2、响铃选取:采用经济合用蜂鸣器,它是一种一体化构造电子讯响器,采用直流电压供电,广泛应用于计算机、报警器、电子玩具、定期器等电子产品中作发声器件,并且驱动电路简朴,由单片机一种I/O口外接一种三极管即可。
3 系统构成
通过以上计时方案选取和显示方案选取,拟定本设计电子闹钟计时方案为单片机内部定期,显示方案为液晶LCD1602。闹铃响铃来源选取经济合用蜂鸣器,并用按键来选取功能菜单和调节时间,用4个不同颜色发光二极管作为两个闹铃批示灯,程序运营批示灯和电源批示灯。
因而系统构成框图如图3.1:
LCD1602
批示灯
蜂鸣器
AT89S52最小系统
键盘
图3.1 系统框图
4 硬件设计
4.1 单片机最小系统设计
单片机最小系统设计核心就是时钟电路和复位电路设计。
1、时钟电路
在这里使用单片机内部振荡电路,管脚XTAL1、XTAL2用来外接石英晶体和微调电容,如图4.1所示。晶体可在1.2—12MHz之间选取,电容可在6—30pF之间选取。
图4.1 时钟电路
2、复位电路
当振荡电路工作,并且在RST引脚加上一种至少保持两个机器周期高电平时,就能完毕一次复位。这里我使用按钮复位方式,如图4.2,运用RC微分电路产生正脉冲来达到复位目,该正脉冲持续时间不不大于两个机器周期。
图4.2 复位电路
4.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 蜂鸣器电路设计
电路设计如图4.4,单片机P2.0脚通过限流电阻R与三极管基极相接,集电极接蜂鸣器。当P2.0引脚电平为0是,三极管导通,蜂鸣器工作,引脚电平为1时,三极管截止,蜂鸣器不工作。由于单片机口输出低电平时驱动能力比高电平强多,故三极管采用基极低电平导通PNP型三极管。
图4.4 蜂鸣器驱动电路
4.4 按键电路设计
本次按键电路设计可直接将按键一端接到单片机I/O口,另一端直接接地。通过单片机检测低电平判断按键按下,K1-K6分别接至单片机P3.0-P3.5。按键电路如图4.5:
图4.5 按键电路
5 软件设计
软件设计重要包括显示走时、闹铃检测和键盘扫描三某些。
5.1 走时某些
走时某些重要有3个变量hour、min、sec和deda做为时钟时、分、秒和定期标志位,通过单片机内部定期器定期50ms,定期标志位deda加1,此过程在中断服务程序中完毕,当加满20次时,deda清零并且时钟秒sec加1,从而到达计时目。
代码如下:
void T0_srv(void) interrupt 1
{
TH0=0x3C;
TL0=0x0B0;
deda++;
}
void conv()
{
if(deda>=20){sec++;deda=0;}
if(sec==60){min++;sec=0;ok=1;}
if(min==60){hour++;min=0;}
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)&&(hour==hh1)&&(min==mm1)&&(ok==1))
{
time();
alm_led1=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();
if(k2==0)
set_atime1();
if(k3==0)
set_atime2();
if(k4==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); //写一种字符后地址指针自动加1
write_com(0x01); //清屏
}
5.5 流程图
1、主程序流程图,如图5.1:
图5.1 主程序流程图
2、中断服务流程图: 如图5.2:
图5.2 中断服务流程图
2、时间流程图,如图5.3:
图5.3 时间流程图
3、闹铃检测流程图,如图5.4:
图5.4 闹铃检测流程图
4、键盘扫描流程图,如图5.5:
图5.5 键盘扫面流程图
6 仿真设计
仿真设计是设计一种系统十分重要环节,在实际电路做好之前系统软件调试最佳选取。本次仿真设计采用是英国Labcenter electronics公司出版EDA工具软件Protues,在PROTUES绘制好原理图后,调入已编译好目的代码文献:*.HEX,可以在PROTUES原理图中看到模仿实物运营状态和过程。
仿真电路图如下,图6.1:
图6.1 仿真电路图
7 系统调试及成果
7.1 软件调试
此时设计软件调试某些重要在仿真软件Protues中完毕。
一方面依照硬件设计在Protues中完毕原理图设计,拟定使用单片机哪些I/O口,然依照软件设计中流程图编写单片机C语言程序。结合题目规定模块化地编写程序,一方面编写走时程序,然后编写闹铃1、闹铃2、程序,最后完毕倒计时设计,在分模块化编写过程中,不断地依照仿真现象调试程序来修复软件编写错误。
例如调试液晶显示问题,写指令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++;deda=0;}
if(C_sec<0){C_sec=59;C_min--;}
if(sec==60){min++;sec=0;}
if(C_min<0){C_hour--;C_min=59;}
if(min==60){hour++;min=0;}
if(hour==24){hour=0;}
if(C_hour<0)
{
C_sec=0;C_min=0;C_hour=0;
for(i=0;i<10;i++)
{
routine_led=~routine_led;
beep=~beep;
delay(80);
}ok=1;
}
最后在显示时间问题上,要将数字显示到液晶上,采用办法是将数字转化为字符串中元素然后再送往液晶显示。程序如下:其中,uchar code lcd_code[ ]=""。
void display_num(unsigned char num)
{
uchar ge,shi;
ge=num%10;
shi=num/10;
write_date(lcd_code[shi]);
write_date(lcd_code[ge]);
}
7.2 硬件调试
本次硬件设计较为简朴,重要调试某些在于液晶对比度调试,期间遇到问题是液晶对比度调节引脚所接10k电位器封装不对的,导致VCC与GND短路,还好及时发现问题,没有损坏器件。
7.3 调试成果
通过近两周软件调试和硬件调试,对比设计规定,完毕状况如下:
1、电路板大小7cm*12cm;
2、电路接通电源后,蜂鸣器持续发出2次响声,同步工作批示灯闪动,液晶第一行显示“Time:00:00:00”,代表时间,第二行显示“00:00 F 00:00 F”,代表两个闹铃,初始为关。
3、可通过按键设定走时时间、两个闹铃响时间和倒计时时间。
4、可显示两个闹钟时、分,并用2个LED灯分别批示闹钟1、闹钟2时间。
8 总结
1、通过本次课程设计,实现了基于单片机电子时钟设计,在这过程中,我学到了诸多,加深了对单片内部模块理解,进一步学习了C语言编写规则。在设计前期,我认真地复习了51单片机有关资料,掌握了单片机外部电路合理设计以及各个引脚功能。系统进行电子时钟需求分析,合理设计出了电路原理框图,依照原理框图设计出电路原理图,然后设计软件流程图,依照流程图对单片机使用C语言编程。在此过程中,我学到了诸多在课本上学不到东西,特别是在解决故障和解决问题方面考虑,受益颇多。
2、本次设计题目为基于单片机电子时钟设计,通过两周努力,可以顺利实现功能有:在液晶上显示走时时间;两个闹铃时间和与否启动以及倒计时时间;并且能通过按键实现设立时间暂停、启动、调节等控制。
3、在完毕设计后,发既有还可以改进地方,例如增长一种省电模式,即在不需要看时间时候,将液晶显示关闭,这是设计前考虑不周地方。
最后,我深刻感受到要做好一种课程设计,就必要做到:在设计程序之前,对所需资料综合整顿,有效挑选资料;要明确目的,整顿思路;合理设计出系统所必要流程图,做好充分心里准备。这次设计是对我所学单片机一书综合考验,使我能查漏补缺,复习课本知识,加深理解记忆,因此每一步我都专心去做。
参照文献
[1] 沈红卫.基于单片机智能系统设计与实现[M].北京:电子工业出版社,
[2] 王守中、聂元铭.51单片机开发入门与典型实例(第2版)[M].北京:人民邮电出版社,
[3] 白驹珩、雷晓平.单片计算机及其应用(第2版)[M].成都:电子科技大学出版社,
附 录
1、元器件清单:
《专业工程设计》元器件清单示例
学号: 姓名: 彭少锟 空
课题名称: 定期打铃器设计 空
序 号
名 称
数 量
单 价
备 注
1
单片机89C52及锁紧底座
1
2
lcd1602
1
3
4脚按键(规格12*12mm)
6
带按键帽
4
4脚按键(规格6*6mm)
1
5
发光二极管(直径3mm)
3
蓝绿黄各一种
6
发光二极管(直径5mm)
1
红
7
直插电阻360欧
4
8
直插电阻1K
1
9
直插电阻100欧
2
10
直插电阻2.7k
1
11
精密电位器10k
1
12
晶振12MHz
1
13
电解电容10u
1
14
直插电容22pF
2
15
9012三极管
1
16
蜂鸣器
1
17
排阻1K*8
1
18
1*40圆孔插座
1
1排
19
双排插针
1
1排
20
单排插针
1
1排
21
ISP下载口2*5插座
1
2、电路原理图:
3、程序代码
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
#define TS1602_DATA P0
sbit routine_led=P1^0;
sbit alm_led1=P1^1;
sbit alm_led2=P1^2;
sbit E=P2^2;
sbit RS=P2^1;
sbit beep=P2^0;
sbit k1=P3^0;
sbit k2=P3^1;
sbit k3=P3^2;
sbit k4=P3^3;
sbit k5=P3^4;
sbit k6=P3^5;
uchar i,j;
uchar hour=0,min=0,sec=0;
uchar hh1=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_code[]="";
void delay(uint x)
{
uint i,j;
for(i=0;i<x;i++)
{
for(j=0;j<121;j++)
{;}
}
}
//************************************************
//函数功能:写指令
//************************************************
void write_com(uchar com)
{
RS=0;
TS1602_DATA=com;
delay(1);
E=1;
delay(1);
E=0;
}
//***************************************************
//函数功能:写数据
//****************************************************
void write_date(uchar date)
{
RS=1;
TS1602_DATA=date;
delay(1);
E=1;
delay(1);
E=0;
}
//***************************************************
//函数功能:显示数据
//****************************************************
void display_num(unsigned char num)
{
uchar ge,shi;
ge=num%10;
shi=num/10;
write_date(lcd_code[shi]);
write_date(lcd_code[ge]);
}
//***************************************************
//函数功能:LCD初始化
//****************************************************
void TS1602_INIT(void)
{
RS=0;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01); //清屏
write_com(0x80); //光标位置
}
//***************************************************
//函数功能:显示第一行字符串
//****************************************************
void display_string1(uchar *P)
{
while(*P)
{
write_date(*P);
P++;
}
}
//***************************************************
//函数功能:显示第二行字符串
//****************************************************
void display_string2(uchar *S)
{
write_com(0x80+0x40);
while(*S)
{
write_date(*S);
S++;
}
}
//***************************************************
//函数功能:定期器初始化函数
//****************************************************
void init_timer()
{
TMOD=0x01;
TH0=0x3C;
TL0=0x0B0;
IE=0x82;
TR0=1;
}
//***************************************************
//函数功能:中断服务程序
//****************************************************
void T0_srv(void) interrupt 1
{
TH0=0x3C;
TL0=0x0B0;
deda++;
}
//***************************************************
//函数功能:时分秒转换程序
//****************************************************
void conv()
{
if(deda>=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);delay(1);
}
//***************************************************
//函数功能:倒计时分秒转换程序
//****************************************************
void C_conv()
{
if(deda>=20){C_sec--;sec++;deda=0;}
if(C_sec<0){C_sec=59;C_min--;}
if(sec==60){min++;sec=0;}
if(C_min<0){C_hour--;C_min=59;}
if(min==60){hour++;min=0;}
if(hour==24){hour=0;}
if(C_hour<0)
{
C_sec=0;C_min=0;C_hour=0;
for(i=0;i<10;i++)
{
routine_led=~routine_led;
beep=~beep;
delay(80);
}
ok=1;
}
}
//***************************************************
//函数功能:显示倒计时时间
//****************************************************
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);
display_num(C_sec);delay(1);
}
//***************************************************
//函数功能:调用走时时间程序函数
//****************************************************
void time()
{
conv();
disp_time();
}
//***************************************************
//函数功能:调用倒计时时间程序函数
//****************************************************
void Ctime()
{
C_conv();
disp_Countdown_time();
}
//***************************************************
//函数功能:显示闹铃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()
{
write_com(0x80+0x48);
display_num(hh2);delay(1);
write_com(0x80+0x4B);
display_num(mm2);delay(1);
}
//***************************************************
//函数功能:调节时间
//****************************************************
void set_time()
{
delay(500);
TR0=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;
}
}
//***************************************************
//函数功能:调节闹铃1
//****************************************************
void set_atime1()
{
alm_led1=0;
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)&&(alm_flag2==0)){display_string2(string2);disp_alm1();disp_alm2();}
if((alm_flag1==1)&&(alm_flag2==0)){display_string2(string3);disp_alm1();disp_alm2();}
if((alm_flag1==0)&&(alm_flag2==1)){display_string2(string4);disp_alm1();disp_alm2();}
if((alm_flag1==1)&&(alm_flag2==1)){display_string2(string5);disp_alm1();disp_alm2();} }
if(k4==0)
{alm_flag1=0;
if((alm_flag1==0)&&(alm_flag2==0)){display_string2(string2);disp_alm1();disp_alm2();}
if((alm_flag1==1)&&(alm_flag2==0)){display_string2(string3);disp_alm1();disp_alm2();}
if((alm_flag1==0)&&(alm_flag2==1)){display_string2(string4);disp_alm1();disp_alm2();}
if((alm_flag1==1)&&(alm_flag2==1)){display_string2(string5);disp_alm1();disp_alm2();} }
if(k6==0)
{ ok=1;}
time();
}
alm_led1=1;
}
//***************************************************
//函数功能:调节闹铃2
//****************************************************
void set_atime2()
{
alm_led2=0;
delay(1000);
ok=0;
while(ok==0)
{
if(k1==0)delay(100);
if(k1==0)hh2++;
if(hh2==24)hh2=0;
delay(5);
d
展开阅读全文