基于单片机的定时闹钟设计报告.docx
- 文档编号:7026642
- 上传时间:2023-01-16
- 格式:DOCX
- 页数:25
- 大小:210.81KB
基于单片机的定时闹钟设计报告.docx
《基于单片机的定时闹钟设计报告.docx》由会员分享,可在线阅读,更多相关《基于单片机的定时闹钟设计报告.docx(25页珍藏版)》请在冰豆网上搜索。
基于单片机的定时闹钟设计报告
电子系统设计(单片机)课程设计总结报告
题目:
定时闹钟
院(系)名称:
信息与通信工程学院
班级:
20130815
学生姓名:
唐学远
学生学号:
2013081520
指导教师:
蒋伊琳
哈尔滨工程大学
2016年6月
一、研究意义和实现功能指标
以单片机为核心的数字时钟是很有社会意义和社会价值的。
钟表原先的报时功能已经原不能满足人们日益增长的要求,现代的电子时钟多带有类似自动报警、按时自动打铃、时间程序自动控制、定时广播、自动起闭路灯、通断动力设备、甚至各种定时电气的自动启用等功能。
二、总体设计方案
本LCD定时闹钟,是以单片机及外围接口电路为核心硬件,辅以其他外围硬件电路,用汇编语言设计的程序来实现的。
根据C51单片机的外围接口特点扩展相应的硬件电路,然后根据单片机的指令设计出数字钟相应的软件,再利用软件执行一定的程序来实现数字钟的功能。
由于采用集成芯片性的单片机来制作电子钟,这样设计制作简单而且功能多、精确度高,也可方便扩充其他功能,实现也十分简单。
本设计是利用AT89C51单片机为主控芯片,由LCD、晶振、电阻、电容、发光二极管、开关、喇叭、被控电器等元件组成硬件电路,通过编写软件程序来实现和控制的数字定时闹钟
三、硬件实现
1、时钟电路
AT89C51系列的单片机的时钟方式分为内部方式和外部方式。
内部方式就是在单片机的XTAL1和XTAL2的两引脚外接晶振,就够成了自激振荡器在单片机内部产生时钟脉冲信号。
外部时钟方式是把外部已经有的时钟信号引入到单片机内部。
时钟电路在计算机系统中起着非常重要的作用,是保证系统正常工作的基础。
在一个单片机应用系统中,时钟有两方面的含义:
一是指为保障系统正常工作的基准振荡定时信号,主要由晶振和外围电路组成,晶振频率的大小决定了单片机系统工作的快慢;二是指系统的标准定时时钟,即定时时间。
本LCD电子闹钟设计是采用内部时钟方式,用一个10MHz晶振和两个30Pf瓷片电容组成,为单片机提供标准时钟,其中两个瓷片电容起微调作用.其电路图见图3.2。
2、lcd显示电路
本设计采用了型号为1602的LCD。
LCD有LED数码显示更好的更的直观效果,也更加经久耐用。
液晶显示模块体积小功耗低、显示内容丰富,现在字符型液晶显示模块已经是单片机应用设计中最常用的信息显示器件之一了。
本LCD是2行16列液晶可显示2行16列英文字符,有8位数据总线D0-D7,RS,R/W,EN三个控制端口(共14线),工作电压为5V。
没背光,和常用的1602B功能和引脚一样(除了调背光的二个线脚).该模块也可只用
表3.1LCD显示屏引脚说明
编号
符号
引脚说明
编号
符号
引脚说明
1
VCC
电源地
9
D2
双向数据口
2
VDD
电源正极
10
D3
双向数据口
3
VL
对比度调节
11
D4
双向数据口
4
RS
数据/命令选择
12
D5
双向数据口
5
R/W
读/写选择
13
D6
双向数据口
6
E
模块使能端
14
D7
双向数据口
7
D0
双向数据口
15
BLK
背光源地
8
D1
双向数据口
16
BLA
背光源正极
D4-D7作为四位数据分两次传送。
这样的话可以节省MCU的I/O口资源。
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背光地端。
3、按键电路
本实验用4个按键来调节设置时间,和闹钟,一个复位开关来复位程序,按下为低电平,松手时按键自动弹起,为高电平,来给单片机指令。
4、总电路图
四、软件实现
1、本LCD电子闹钟的的主程序流程图如图所示:
初始化
主程序开始
扫描按键
设置响铃方式
显示闹钟时间
设置闹钟时间
设置当前时间
显示时间
是否到闹钟时间
N
Y
响铃,打开被控电器
4键是否按下
N
Y
关闭闹铃
按下复位键
2、定时闹钟程序
#include
#defineuintunsignedint
#defineucharunsignedchar
ucharcodetable[]="NOWTIME:
";
ucharcodetable1[]="SETNOWTIME:
";
ucharcodetable2[]="SETALARMTIME:
";
ucharcodealarm[]="ALARMTIME:
";
ucharcodealarmoff[]="ALARMTIME:
OFF";
ucharcodealarmon[]="ALARMTIME:
ON";
sbitlcden=P2^4;
sbitlcdrs=P2^2;
sbitlcdrw=P2^3;
sbitK1=P1^0;
sbitK2=P1^1;
sbitK3=P1^2;
sbitK4=P1^3;
sbitbeep=P1^4;
sbitDianQi=P1^5;
sbitL1=P2^5;
ucharflag,num,count,k1num,k2num,k3num,k4num;
charmiao,shi,fen,ashi,afen;
uchari;
ucharflag1=0;
voiddelay(uintz)//延时函数
{
uintx,y;
for(x=z;x>0;x--)
for(y=100;y>0;y--);
}
voiddi()//蜂鸣器子程序
{
beep=1;
delay(100);
beep=0;
}
voidwrite_com(ucharcom)//写命令函数
{
lcdrs=0;
lcdrw=0;
lcden=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
voidwrite_date(uchardate)//写数据函数
{
lcdrs=1;
lcdrw=0;
lcden=0;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
voidwrite_sfm(ucharadd,uchardate)//写时间函数
{
ucharshi,ge;
shi=date/10;
ge=date%10;
write_com(0x80+0x40+add);
write_date(0x30+shi);
write_date(0x30+ge);
}
voidTimeInit()//显示时间初始化
{
write_com(0x01);
write_com(0x80);
for(num=0;num<9;num++)
{
write_date(table[num]);
delay(5);
}
write_com(0x80+0x40+6);
write_date(':
');
delay(5);
write_com(0x80+0x40+9);
write_date(':
');
delay(5);
write_sfm(4,shi);
write_com(0x80+0x40+4);
write_sfm(7,fen);
write_com(0x80+0x40+7);
write_sfm(10,miao);
write_com(0x80+0x40+10);
}
voidSetNowTime()//设置当前时间
{
if(K1==0)
{
delay(5);
if(K1==0)
{
while(!
K1);
di();
shi++;
if(shi==24)
shi=0;
write_sfm(4,shi);
write_com(0x80+0x40+4);
}
}
if(K2==0)
{
delay(5);
if(K2==0)
{
while(!
K2);
di();
fen++;
if(fen==60)
fen=0;
write_sfm(7,fen);
write_com(0x80+0x40+7);
}
}
if(K3==0)
{
delay(5);
if(K3==0)
{
while(!
K3);
di();
k1num=0;
TR0=1;
TimeInit();
}
}
}
voidSetAlarmTime()//设置闹钟时间函数
{
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(0x80+0x40+4);
}
}
if(K2==0)
{
delay(5);
if(K2==0)
{
while(!
K2);
di();
afen++;
if(afen==60)
afen=0;
write_sfm(7,afen);
write_com(0x80+0x40+7);
}
}
if(K3==0)
{
delay(5);
if(K3==0)
{
while(!
K3);
di();
k3num=0;
EA=1;
flag=1;
TimeInit();
}
}
}
voidDisplayAlarmTime()//显示闹钟函数
{
write_com(0x01);
write_com(0x80);
for(num=0;num<11;num++)
{
write_date(alarm[num]);
delay(5);
}
write_com(0x80+0x40+6);
write_date(':
');
delay(5);
write_sfm(4,ashi);
write_com(0x80+0x40+4);
write_sfm(7,afen);
write_com(0x80+0x40+7);
}
voidkeyscan()//键盘扫描函数
{
if(K1==0)
{
delay(5);
if(K1==0)
{
TR0=0;
while(!
K1);
di();
k1num++;
}
}
if(k1num!
=0)//如果1键按下
{
write_com(0x80);
for(num=0;num<13;num++)//显示SetNowTime
{
write_date(table1[num]);
delay(5);
}
SetNowTime();//进入SetnowTime函数
}
else
{
if(K2==0)
{
delay(5);
if(K2==0)
{
while(!
K2);
di();
k2num++;
}
}
if(k2num==1)//如果2键按下,则显示进入
显示当前时间函数
{
EA=0;
DisplayAlarmTime();
k2num=2;
}
if(k2num==3)
{
k2num=0;
EA=1;
TimeInit();
}
else
{
if(K3==0)
{
delay(5);
if(K3==0)
{
while(!
K3);
di();
k3num++;
write_com(0x01);
}
}
if(k3num==1)//如果3键按下
{
EA=0;
write_com(0x80);
for(num=0;num<15;num++)//显示SetAlarmTime
{
write_date(table2[num]);
delay(5);
}
write_com(0x80+0x40+6);//在第二行显示时间格式
write_date(':
');
delay(5);
write_sfm(4,ashi);
write_com(0x80+0x40+4);
write_sfm(7,afen);
write_com(0x80+0x40+7);
SetAlarmTime();//进入SetAlarmtimeha函数
}
else
{
if(K4==0)//设置闹钟模式,有三种模式,不响,
一秒响一声,一秒响三声
{
delay(5);
if(K4==0)
{
while(!
K4);
k4num++;
}
}
if(k4num==1)//不响
{
flag=0;
k4num=2;
}
if(k4num==3)//一秒响一声
{
beep=1;
delay(500);
beep=0;
flag=1;
flag1=0;
k4num=4;
}
if(k4num==5)
{
k4num=0;//一秒响三声
flag=1;
flag1=1;
beep=1;
delay(100);
beep=0;
delay(100);
beep=1;
delay(100);
beep=0;
delay(100);
beep=1;
delay(100);
beep=0;
delay(100);
}
}
}
}
if(flag==1&&shi==ashi&&fen==afen)
{
DianQi=1;
delay(100);
if(flag1==1)
{
beep=1;//蜂鸣器一秒连续响三声
delay(100);
beep=0;
delay(100);
beep=1;
delay(100);
beep=0;
delay(100);
beep=1;
delay(100);
beep=0;
delay(500);
if(K4==0&&flag==1)//检测4键是否被按下,按下则跳
出,蜂鸣器停止发声
{
delay(5);
if(K4==0&&flag==1)
{
while(K4=!
K4);
flag=0;
k4num=0;
}
}
}
if(flag1==0)
{
beep=!
beep;//蜂鸣器长一秒响一声
delay(500);
if(K4==0&&flag==1)//检测4键是否按下,按下则跳出,
蜂鸣器停止发声
{
delay(5);
if(K4==0&&flag==1)
{
while(K4=!
K4);
flag=0;
k4num=0;
}
}
}
}
}
voidinit()//lcd1602初始化
{
beep=0;
DianQi=0;
lcden=0;
shi=0;
fen=0;
miao=0;
ashi=0;
afen=0;
count=0;
k1num=0;
write_com(0x38);//设置16X2显示,5X7点阵,8位数据接口
write_com(0x0c);//设置开显示,不显示光标
write_com(0x06);//写一个字符后地址指针加1
write_com(0x01);//显示清0,数据指针清0
TimeInit();
TMOD=0x01;
TH0=(65536-41665)/256;
TL0=(65536-41665)%256;
EA=1;
ET0=1;
TR0=1;
}
voidmain()//主函数
{
DianQi=0;
beep=0;
init();
write_com(0x80);
flag=0;
while
(1)
{
keyscan();
}
}
voidtimer0()interrupt1//中断服务子程序
{
TH0=(65536-41667)/256;
TL0=(65536-41667)%256;
count++;
if(count==10)
{
L1=~L1;
}
if(count==20)
{
L1=~L1;
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);
}
}
五、调试过程和设计效果
按下3键,进入SetAlarmTime函数,设置闹钟时间
按下2键,进入DisplayAlarmTime函数,显示闹钟时间
按下1键,进入SetNowTime函数,设置当前时间
到闹钟时间,蜂鸣器想起,打开被控家电(这里用灯泡表示)
关闭闹钟,被控电器也处于打开状态,考虑到实际需求(比如说闹钟订到下午6:
00打开电灯,关闭闹钟后电灯也是打开状态),闹钟一直响谁也受不了,电器却需要一直工作。
我在继电器前加了一个自锁开关,这样就能控制电器是否启动。
实物图
六、元器件表和成本核算
元件名称
使用数量
市场价格(网络)
STC89C52RC
1
4.35元
LCD1602
1
5.30元
继电器
1
1.05元
按键
5
0.05元
33PF电容
2
23元/袋(1000个)
10K电阻
2
0.08元
1K电阻
2
0.02元
10u电解电容
1
0.4元
连接短线
若干
10M晶振
1
0.2元
灯泡
1
0.5元
电位器
1
0.3元
三极管
3
0.07元
蜂鸣器
1
0.26元
自锁开关
3
0.08元
万用板
1
0.28元
总价格:
13.59元
附哈尔滨工程大学电子系统设计(单片机)课程设计验收表
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 单片机 定时 闹钟 设计 报告