单片机课程设计闹钟Word文件下载.docx
《单片机课程设计闹钟Word文件下载.docx》由会员分享,可在线阅读,更多相关《单片机课程设计闹钟Word文件下载.docx(26页珍藏版)》请在冰点文库上搜索。
本设计是一个定时闹钟,它仅使用单片的20引脚单片机完成闹钟的全部功能。
设计目的是为了学习和巩固单片机知识,使对已学过的基础知识能有更深入的理解,学会独立思考、独立思考、独立工作,以及提高对所学应用基本理论分析和解决实际问题的能力。
1.2设计任务
本文设计的定时闹钟采用AT89C51芯片,用汇编语言进行编程,时、分、秒用6位LED数码管显示。
在电路中通过四个按键S1、S2、S3和S4来进行定时和调时,定时时间到通过喇叭发出报警声。
1.3设计系统的主要功能
·
能显示时时-分分-秒秒。
能够设置定时时间、修改定时时间。
到定时时间能发出报警声。
二、系统方案及硬件设计
2.1、LCD电子闹钟的特点和功能介绍
时钟是将小时、分钟、秒钟显示于人的肉眼的计时装置。
而单片机模块中最常见的正是数字钟,数字钟是一种用数字电路技术实现时、分、秒计时的装置,与机械式时钟相比具有更高的准确性和直观性,且无机械装置,具有更长的使用寿命,因此得到了广泛的使用。
而LCD电子定时闹钟是以单片机为基础的数字电路实现对时、分、秒的数字显示的数字计时装置,它的计时周期为24小时,另外应有校时功能和一些显示日期、闹钟等附加功能。
一个基本的数字钟电路主要由译码显示器、“时”,“分”,“秒”,“星期”计数器、校时电路、报时电路和振荡器组成。
目前电子钟广泛用于各种私人和公众场合,成为我们生活、工作和学习中不可缺少的好帮手。
由于时钟的实用性和在人们生活中的重要性,所以尝试设计以单片机为核心的数字时钟是很有意义的。
钟表原先的报时功能已经原不能满足人们日益增长的要求,现代的电子时钟多带有类似自动报警、按时自动打铃、时间程序自动控制、定时广播、自动起闭路灯、通断动力设备、甚至各种定时电气的自动启用等功能,本设计中LCD电子时钟采用LCD显示时间和日期年月,直观实用,而且可以方便的校调,附带的万年历和定时功能也是很方便和实用的。
本LCD定时闹钟,是以单片机及外围接口电路为核心硬件,辅以其他外围硬件电路,用汇编语言设计的程序来实现的。
根据C51单片机的外围接口特点扩展相应的硬件电路,然后根据单片机的指令设计出数字钟相应的软件,再利用软件执行一定的程序来实现数字钟的功能。
由于采用集成芯片性的单片机来制作电子钟,这样设计制作简单而且功能多、精确度高,也可方便扩充其他功能,实现也十分简单。
本设计是利用AT89C51单片机为主控芯片,由LCD、晶振、电阻、电容、发光二极管、开关、喇叭等元件组成硬件电路,通过编写软件程序来实现和控制的数字定时闹钟。
如图2.1所示。
图2.1
2.31定时闹钟的基本功能如下:
(a)启动仿真软件,使用LCD液晶显示器来显示现在的时间。
(b)程序执行之后显示“Time:
00:
00”;
时间显示的秒开始变化,并且LED闪烁,表示开始已经计时。
(c)由LED闪动来做秒计数表示。
(d)当设定的闹钟时间到达后,闹铃开始发出“哒哒哒”的声音。
2.32按键功能如下:
按键K1设置现在的时间和时调整;
按键K2显示闹钟设置的时间和分调整;
按键K3设置闹铃的时间和设置完成;
按键K4闹铃ON/OFF的状态设置,设置为ON时连续三次发出“哗”的一声,设置为OFF发出“哗”的一声和闹钟时间到时,发出一阵声响,按下本键可以停止声响。
2.33调整计时器时间如下:
按下K1键,然后按K1调整小时,K2调整分钟,按下K3表示时间设置完成。
2.34调整闹钟时间设置如下:
按下K3开始闹钟设置,LCD下一行显示“Alarm:
00”按下K1设置小时,按一下K2设置分钟,再次按下K3设置完成,并且设置时间消失。
三、硬件设计
3.1主控芯片AT89C51的设计
在本LCD电子闹钟设计中就是采用利用我们熟悉的AT89C51单片机为主控芯片。
AT89C51单片机由微处理器,存储器,I/O口以及特殊功能寄存器SFR等部分构成。
其存储器在物理上设计成程序存储器和数据存储器两个独立的空间,片内程序存储器的容量为4KB,片内数据存储器为128个字节。
89C51单片机有4个8位的并行I/O口:
P0口,P1口,P2口和P3口。
各个接口均由接口锁存器,输出驱动器,和输入缓冲器组成。
P1口是唯一的单功能口,仅能用作通用的数据输入/输出口。
P3口是双功能口除了具有数据输入/输出功能外,每条接口还具有不同的第二功能,如P3.0是串行输入口线,P3.1口是串行输出口线。
在需要外部程序存储器和数据存储器扩展时,P0可作为分时复用的低8位地址/数据总线,P2口可作为高8位的地址总线。
P3口也可作为AT89C51的一些特殊功能口,同时为闪烁编程和编程校验接收一些控制信号.
3.2时钟电路部分设计
图3.1
而之所以采用高性能的振荡电路,因为:
1.单片机电子钟的计时脉冲基准是由外部晶振的频率经过12分频后提供,采用内部的定时/计数器来实现计时功能。
所以,外接晶振频率精确度直接影响电子钟计时的准确性。
2.单片机电子钟利用内部定时/计数器溢出产生中断(12M晶振一般为50ms)再乘以相应的倍率来实现秒、分、时的转换。
大家都知道从定时/计数器产生中断请求到响应中断需要3-8个机器周期,定时中断子程序中的数据入栈和重装定时/计数器的初值还需要占用数个机器周期,还有从中断入口转到中断子程序也要占用一定的机器周期。
3.3LCD显示电路部分
为了获得更好的效果本设计并没有采用常见的LED,而是采用了型号为1602的LCD。
LCD有LED数码显示更好的更的直观效果,也更加经久耐用。
液晶显示模块体积小功耗低、显示内容丰富,现在字符型液晶显示模块已经是单片机应用设计中最常用的信息显示器件之一了。
本LCD是2行16列液晶可显示2行16列英文字符,有8位数据总线D0-D7,RS,R/W,EN三个控制端口(共14线),工作电压为5V。
没背光,和常用的1602B功能和引脚一样(除了调背光的二个线脚).该模块也可只用
D4-D7作为四位数据分两次传送。
这样的话可以节省MCU的I/O口资源。
引脚说明,见表3.1。
VDD:
电源正极,4.5-5.5V,通常使用5V电压;
VL:
LCD对比度调节端,电压调节范围为0-5V。
接正电源时对比度最弱,接地电源时对比度最高,但对比度过高时会产生“鬼影”,因此通常使用一个10K的电位器来调整对比度或者直接串接一个电阻到地;
RS:
MCU写入数据或者指令选择端。
MCU要写入指令时,使RS为低电平;
MCU要写入数据时,使RS为高电平;
R/W:
读写控制端。
R/W为高电平时,读取数据;
R/W为低电平时,写入数据;
E:
LCD模块使能信号控制端。
写数据时,需要下降沿触发模块。
D0-D7:
8位数据总线,三态双向。
如果MCU的I/O口资源紧张的话,该模块也可以只使用4位数据线D4-D7接口传送数据。
本充电器就是采用4位数据传送方式;
BLA:
LED背光正极。
需要背光时,BLA串接一个限流电阻接VDD,BLK接地,实测该模块的背光电流为50mA左右;
BLK:
LED背光地端.
四、软件设计
4.1软件设计概述
这里用汇编的单片机程序构成了本LCD电子闹钟的软件系统。
该程序实现时间及定时(时间以0点0分0秒为基准计算,闹铃定时以0时0分为基准计算)的显示,有外中断0和五个开关实现校时,闹钟功能。
其中程序的晶振频率为12MHz,最小计时单位为1/20秒。
主芯片p0.1-p0.7输出数据到LCD数据总线,p3.0-2.2输出LCD控制信号,P2.1输出声音信号,.P1.0-P1.3输入外部控制信号,整个软件系统也是根据这个关系连接成一个完整的系统。
4.2主函数的设计
本LCD电子闹钟的的主程序流程图如图4.1所示:
图4.1
4.3.闹钟的实现
闹钟功能的实现涉及到两个方面:
闹铃时间设定和是否闹铃判别与相应处理。
闹铃时间设定模块的设计可参照时间设定模块,这里着重阐述闹铃判别与处理模块的设计问题。
闹铃判别与.闹铃处理的关键在于判别何时要进行闹铃。
当时十位、时个位、分十位、分个位中任一位发生改变(进位)时,就必须进行闹铃判别。
程序设计思想如图4.2。
五、仿真图片与实物图片
图4.2
附录2定时闹钟的控制程序代码
#include<
reg52.h>
#defineuintunsignedint
#defineucharunsignedchar
sbitkey1=P1^0;
sbitkey2=P1^1;
sbitkey3=P1^2;
sbitkey4=P1^3;
sbitlcden=P2^2;
sbitlcdrs=P2^0;
sbitlcdrw=P2^1;
sbitjdq=P2^3;
sbitled=P2^4;
sbitsound=P2^5;
inta,b,i,min,hour,minge,minshi,hourge,hourshi,amin,ahour,aminge,aminshi,ahourge,ahourshi,sec,secshi,secge;
//unsignedcharcodex[]={0xFF,0xC7,0x83,0x01,0x00,0x00,0x00,0x01,0x03,0x07,0x0F,0x1F,0x3F,0x7F,0xFF,0xFF};
//unsignedcharcodez[]={0xFF,0xE3,0xC1,0x80,0x00,0x00,0x00,0x80,0xC0,0xE0,0xF0,0xF8,0xFC,0x7F,0xFF,0xFF};
ucharcodetable1[]={'
0'
'
1'
2'
3'
4'
5'
6'
7'
8'
9'
};
ucharcodetable2[]="
Time:
00"
;
ucharcodeAlarm_1[]="
Alarm:
;
ucharcodenul[]="
"
ucharnum1,num2;
bitflag=0;
voiddelay(unsignedintxms)//延时程序
{
uinti,j;
for(i=xms;
i>
0;
i--)
for(j=124;
j>
j--);
}
voidwrite_com(ucharcom)//LCD命令控制,写指令函数
delay(5);
lcdrs=0;
P0=com;
delay(5);
lcden=1;
lcden=0;
voidwrite_data(uchardate)//LCD数据控制,写数据函数
lcdrs=1;
P0=date;
voidtime()//设置时间函数
while
(1)
{
if(key1==0)
{
delay(10);
if(key1==0)
{
if(hour==23)//"
时"
设置
hour=0;
else
hour++;
hourge=hour%10;
hourshi=hour/10;
write_com(0x0f);
delay
(2);
write_com(0x80+6);
write_data(table1[hourge]);
//"
个位写入LCD第二行第6位
delay(5);
write_com(0x80+5);
write_data(table1[hourshi]);
十位写入LCD第二行第5位
while(!
key1);
//delay
(1);
}
}
if(key2==0)
delay(10);
if(key2==0)
if(min==59)//"
分"
min=0;
min++;
minge=min%10;
minshi=min/10;
write_com(0x80+9);
write_data(table1[minge]);
个位写入LCD第二行第9位
delay
(1);
write_com(0x80+8);
write_data(table1[minshi]);
十位写入LCD第二行第8位
key2);
if(key3==0)
{
if(key3==0)
write_com(0x0c);
//整体显示,关光标,不闪烁
TR1=1;
//定时计数器1启动
key3);
break;
//key3松开时,显示时间"
"
位均已设置完毕
}
voidalarm()//设置闹钟时间函数
if(key1==0)
if(ahour==23)//闹钟"
设置
ahour=0;
ahour++;
ahourge=ahour%10;
ahourshi=ahour/10;
//delay
(2);
write_com(0x80+0x40+8);
write_data('
:
'
);
write_com(0x80+0x40+7);
write_data(table1[ahourge]);
write_com(0x80+0x40+6);
write_data(table1[ahourshi]);
if(key2==0)//闹钟"
if(amin==59)
amin=0;
amin++;
aminge=amin%10;
aminshi=amin/10;
write_com(0x80+0x40+10);
write_data(table1[aminge]);
write_com(0x80+0x40+9);
//delay
(2);
write_data(table1[aminshi]);
{flag=~flag;
write_com(0x80+0x40);
for(i=0;
i<
11;
i++)
write_data(nul[i]);
//设置结束,此时LCD第二行无数据显示,只有第一行有时间显示
voidkeyscan()//键盘扫描
{
if(key1==0)
delay(10);
{
while(!
//key1键松开后执行下一行程序
time();
//调用time()函数,即时间设置
}
}
elseif(key2==0)
key2)
ahourge=ahour%10;
ahourshi=ahour/10;
write_com(0x80+0x40+7);
write_data(table1[ahourge]);
delay(5);
write_com(0x80+0x40+6);
delay
(2);
write_data(table1[ahourshi]);
aminge=amin%10;
aminshi=amin/10;
write_com(0x80+0x40+10);
write_data(table1[aminge]);
write_com(0x80+0x40+9);
write_data(table1[aminshi]);
write_com(0x80+0x40);
for(i=0;
++i)
write_data(Alarm_1[i]);
//显示闹钟设置的时间
write_data(nul[i]);
//key2松开后,LCD只有第一行显示时间,闹钟设置时间不显示
elseif(key3==0)
//表示闹钟时间设置退出
ahourge=ahour%10;
//显示闹钟设置时间
alarm();
//调用闹钟时间设置函数
elseif(key4==0)//以下进行闹铃开关的设置
delay(5);
if(key4==0)
key4);
a=a+1;
if(a%2==0)//闹钟"
on"
for(b=0;
b<
6;
b++)
{
sound=~sound;
//蜂鸣器发出3次"
哗"
的响声
delay(200);
}
sound=1;
elseif(a%2==1)//闹钟"
off"
sound=0;
//蜂鸣器发出1次"
delay(300);
sound=1;
voidlcd_init()//LCD初始化函数
{
lcdrw=0;
write_com(0x38);
//设置8位格式,2行,5×
7
write_com(0x0c);
write_com(0x06);
//设定输入方式,增量不转移
write_com(0x01);
//清除屏幕显示
delay
(2);
write_com(0x80);
16;
write_data(table2[i]);
//写入显示时间数据
voidjudge()
if(sec==60)
{min++;
sec=0;
if(min==60)