自动打铃最终稿023.docx
《自动打铃最终稿023.docx》由会员分享,可在线阅读,更多相关《自动打铃最终稿023.docx(22页珍藏版)》请在冰豆网上搜索。
自动打铃最终稿023
湖南人文科技学院
课程设计报告
课程名称:
单片机原理及应用课程设计
设计题目:
自动打铃系统
系别:
通信与控制工程系
专业:
自动化
班级:
二班
学生姓名:
焦凝礼李瑜
学号:
0842124308421252
起止日期:
2010年12月20日~2010年12月31日
指导教师:
方智文姚毅
教研室主任:
方智文
指导教师评语:
指导教师签名:
年月日
成绩评定
项目
权重
成绩
李瑜
焦凝礼
1、设计过程中出勤、学习态度等方面
0.2
2、课程设计质量与答辩
0.5
3、设计报告书写及图纸规范程度
0.3
总成绩
教研室审核意见:
教研室主任签字:
年月日
教学系审核意见:
主任签字:
年月日
摘要
单片机就是微控制器,是面向应用对象设计、突出控制功能的芯片。
单片机接上晶振、复位电路和相应的接口电路,装载软件后就可以构成单片机应用系统。
将它嵌入到形形色色的应用系统中,就构成了众多产品、设备的智能化核心。
本设计就是应用单片机强大的控制功能制作而成的闪烁的LED小灯,该设计包括以下几点功能:
实现24小时制电子钟,6为数码管显示,显示时分,显示格式为A/P12-00,打铃时间为早上:
7:
30,晚上:
10:
30;系统使用5只按键,一个用来调上午与下午,一个用于调整分钟,还有一个为小时调整。
本设计采用的是STC89C52单片机,该单片机采用的MCU51内核,因此具有很好的兼容性,内部带有8KB的ROM,能够存储大量的程序,最突出特点是具有ISP在系统烧写功能,使得烧写程序更加方便。
显示器件采用通用型七段共阴极数码管;键盘调整部分采用的是独立键盘。
通过此次设计能够更加牢固的掌握单片机的应用技术,增强动手能力、硬件设计能力以及软件设计能力。
关键字:
单片机;AT89C52;8255;数码显示;自动打铃系统
目录
设计要求1
1方案论证与对比1
1.1方案一:
时间采用数字电路1
1.2方案二:
时间采用单片机1
1.3方案对比与选择2
2单元电路设计2
2.1时间显示电路的设计2
2.2复位电路的设计3
2.3蜂鸣电路设计4
2.4按键电路设计5
3软件详细设计5
3.1主程序系统结构的设计5
3.2显示子程序的设计7
3.3按键扫描子程序设计8
4调试及性能分析9
4.1硬件调试9
4.2软件调试9
4.3性能分析9
5总结11
6致谢12
参考文献13
附录一:
自动打铃系统原理图14
附录二:
元件清单15
附录三:
程序16
自动打铃系统
设计要求
功能要求:
(1)基本计时和显示功能(12小时制)。
可设置当前时间(包括上下午标志,时、分的数字显示)。
(2)能实现基本打铃功能,规定:
上午7:
30早自习:
打铃5秒、停2秒、再打铃5秒。
下午10:
30熄灯铃:
打铃5秒、停2秒、再打铃5秒。
1方案论证与对比
1.1方案一:
时间采用数字电路
数字电路的组成框图如图1所示分别由显示电路,译码电路,计数器,校时电路,和脉冲产生的分频器及振荡器。
图1方案一系统方框图
1.2方案二:
时间采用单片机
单片机电路组成框图如图2所示分别由复位电路,时钟电路,按键电路,LED显示装置。
图1方案二系统方框图
1.3方案对比与选择
数字电路的制作方案比较容易实现,并且在原理方面也是较简单,但这种方式制作过程复杂,而且准确性与可靠性不高,成品面积大,安装、维护困难,在具体的应用过程中也容易出问题。
单片机的系统实用性强、判断精确、操作简单、扩展功能强。
综合考虑采用第二种方案来完成本次八路抢答器课程设计。
2单元电路设计
2.1时间显示电路的设计
显示模块主要是显示当前时间、上午与下午等,使用传统的数码管及发光二极管显示。
数码管具有:
低能耗、低损耗、低压、寿命长、耐老化、防晒、防潮、防火、防高(低)温,对外界环境要求低,易于维护,同时其具有精度高、称量快、操作简单等特点。
数码显示是采用BCD编码显示数字,程序编译容易,资源占用较少。
数码显示管用来作为时间的显示输出,一般用7段数码显示管。
本次设计中采用7段共阳数码显示管应用简单、可靠性高、成本低,作为显示输出。
连接时段选信号接在8255PB口的PB.0~PB.7八个I/O口上。
其模块接口电路如图3所示:
图3显示模块接口电路
七段LED字型码如表1所示:
表1:
七段LED字型码
显示字符
共阳极字符
显示字符
共阳极字符
0
C0H
A
88H
1
F9H
b
83H
2
A4H
C
C6H
3
B0H
d
A1H
4
99H
E
86H
5
92H
F
8EH
6
82H
P
8CH
7
F8H
H
89H
8
80H
L
C7H
9
90H
灭
FFH
2.2复位电路的设计
该复位电路采用上电自动复位和手动复位两种复位方式,要实现复位只需在,52系列单片机的RESET引脚上加上5ms的高电平就可以了。
上电复位是利用电容的充电来实现的,即上电瞬间RESET端的电位与Vcc相同,随着电容上储能增加,电容电压也逐渐增大,充电电流减小,RESET端的电位。
这样就会建立一个脉冲电压,调节电容与电阻的大小可对脉冲的持续时间进行调节。
通常若采用12MHz的晶振时,复位元件参数为22μF的电解电容和1kΩ的电阻。
按钮复位电路是通过按下复位按钮时,电源对RESET端维持两个机器周期的高电平实现复位的。
电路如图5示:
图5复位电路
2.3蜂鸣电路设计
(1)蜂鸣器的介绍
1.蜂鸣器的作用蜂鸣器是一种一体化结构的电子讯响器,采用直流电压供电,广泛应用于计算机、打印机、复印机、报警器、电子玩具、汽车电子设备、电话机、定时器等电子产品中作发声器件。
2.蜂鸣器的分类蜂鸣器主要分为压电式蜂鸣器和电磁式蜂鸣器两种类型。
(2)蜂鸣器的结构原理
1.压电式蜂鸣器压电式蜂鸣器主要由多谐振荡器、压电蜂鸣片、阻抗匹配器及共鸣箱、外壳等组成。
有的压电式蜂鸣器外壳上还装有发光二极管。
多谐振荡器由晶体管或集成电路构成。
当接通电源后(1.5~15V直流工作电压),多谐振荡器起振,输出1.5~2.5kHZ的音频信号,阻抗匹配器推动压电蜂鸣片发声。
压电蜂鸣片由锆钛酸铅或铌镁酸铅压电陶瓷材料制成。
在陶瓷片的两面镀上银电极,经极化和老化处理后,再与黄铜片或不锈钢片粘在一起。
2.电磁式蜂鸣器电磁式蜂鸣器由振荡器、电磁线圈、磁铁、振动膜片及外壳等组成。
图6蜂鸣器电路
2.4按键电路设计
时间设置按键采用4行4列矩阵式键盘,其特点是键多时占用I/O口线少,硬件资源利用合理。
矩阵式键盘电路如图7所示:
图7矩阵式按键电路接口图
3软件详细设计
3.1主程序系统结构的设计
主程序系统结构应包括系统初始化模块、按键模块、时间调整和时间显示模块,结构图如图8所示。
源程序:
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitRING=P3^3;
#defineHOR_UP0x12//定义键值意义
#defineMIN_UP0x22
#defineHOR_DOWN0X11
#defineMIN_DOWN0x21
#defineAM_PM0X18
#defineNO_KEY_DOWN0XFF
ucharxdataPA_at_0xD9FF,PB_at_0XDBFF,PC_at_0XDDFF,//定义外部变量,强制分配地址
EX_PORT_CON_at_0XDFFF;
ucharcodeLED_CODE[]={0XA0,0XBB,0X62,0X2A,0X39,0X2C,0X24,0XBA,//LED段码(0~9外加一个全灭,一个A,一个P)
0X20,0X28,0XFF,0X30,0X70};
uintcodeRING_TIME[]={450,1350};//开启时间(分)
ucharCOUNT=0,KEY=NO_KEY_DOWN,HOR=0,MIN=0,SEC=0;//软计时-光标-键值
voidDisplay();//显示
voidTime_Go();//时间进位
voidTime_Set();//时间设置
voidDelay(uintA);//简单延时
ucharKey_Scan();//键盘扫描
3.2显示子程序的设计
显示模块由6个共阳极的七段数码管组成,用来显示时间。
显示子程序的源程序:
voidDisplay()//显示程序
{
PB=0XFF;//消影
PA=0XFe;//发送位码
if(HOR>=12)PB=LED_CODE[12];//发送段码
elsePB=LED_CODE[11];
Delay(200);//延时
PB=0XFF;//消影
PA=0XFd;
if(HOR>12)//发送位码
PB=LED_CODE[(HOR-12)/10];
elsePB=LED_CODE[HOR/10];//发送段码
Delay(200);//延时
PB=0XFF;
PA=0xfb;
if(HOR>12)PB=LED_CODE[(HOR-2)%10];
elsePB=LED_CODE[HOR%10];
Delay(200);
PB=0XFF;//中间横杆
PA=0XF7;
if(COUNT>10)//在显示实时时钟时闪烁,为01秒/周期
PB=0XFF;
else
PB=0X7F;
Delay(200);
PB=0XFF;
PA=0Xef;
PB=LED_CODE[MIN/10];
Delay(200);
PB=0XFF;
PA=0XdF;
PB=LED_CODE[MIN%10];
Delay(130);
3.3按键扫描子程序设计
按键子程序的源文件如下:
ucharKey_Scan()
{ucharA=4,ROW=0x08,T=NO_KEY_DOWN;
if(PC!
=0XF0)//是否有键按下
{Delay(200);//消抖
if(PC!
=0XF0)
while(A--)//查询,逐列
{ROW<<=1;
PC=ROW;
T=(PC&0X0F);
if(T!
=0X00)//但前列是否有键被按下
{T=(T+(ROW&0XF0));//计算键值
do{Display();Time_Go();}//防止数码管在按键按下时闪烁
while((PC&0X0F)!
=0);//松手检测
break;//跳出循环
}
}PC=0xf0;//键盘初始化
}
returnT;//返回键值
}
4调试及性能分析
4.1硬件调试
硬件调试时可以检查印制板及焊接的质量情况,在检查无误的后可通点检查LED显示器的点亮状况。
若亮度不理想,可以调整P0口的电阻大小,一般情况下取200Ω
电阻即可获得满意的亮度效果。
实验室制作时,可结合示波器测试晶振及P0、P2端口的波形情况进行综合硬件测试分析。
4.2软件调试
根据上述需求分析得出的思路,进行C语言程序的编写。
C语言程序一共分为三个部分:
第一部分是SYC89C52芯片的初始化;第二部分是8255可编程定时/计数芯片的初始化;第三部分是,模块的编写。
在各模块中可编写如P1=0x55进行各模块的测试。
软件调试在Wave或KeilC51编译器下进行,源程序编译及仿真调试应分段或以子程序为单元逐个进行,最后可结合硬件实时调试。
4.3性能分析
设计之初的思路是选择将时,分分别保存在一个字节的内存单元中,这样在计时的设计上将变得简单,但这样的设计也带来一个问题,那就是在读入用户输入和将时间显示到屏幕上时的16进制转到ASCII码时,由于涉及到将一个字节内容拆分转化,灵活性受到限制,于是考虑将时,分的每一位用一个字节储存,这样在进行转化时将节省很多操作时间,设计过程中反复修改了程序的结构以达到优化目的,在时间显示出现问题后,我们进行了单元测试并最终发现了问题,在找到问题症结后,我们对显示部分代码及电路进行了完善,最终得到了正确的显示结果。
按照设计程序分析,LED显示器动态扫描的频率约为167Hz,实际使用观察时完全没有闪烁。
由于计时中断程序中加了中断延时误差处理,所以实际计时精度非常高。
可满足多种场合的应用需要。
5总结
课程设计是培养我们综合运用所学知识,发现,提出,分析和解决实际问题,锻炼实践能力的重要环节,是对我们实际工作能力的具体训练和考察过程。
回顾这次单片机课程设计,我感慨颇多。
从选题到定稿,从理论到实践,在两个星期的日子里,可以说得是苦多于甜,但是可以学到很多很多的的东西,不仅可以巩固了以前所学过的知识,而且学到了很多在书本上所没有学到过的知识。
通过这次课程设计使我懂得了理论与实际相结合的重要性,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,提高自己的实际动手能力和独立思考的能力。
在设计的过程中我遇到了很多问题,从而发现了自己的不足之处,主要是对以前所学过的理论知识掌握得不够透彻,对单片机语言掌握得不好,以及缺少实践经验。
这次课程设计使我重新了解自己的水平,从而确定了今后的努力方向。
我想这对于自己以后的学习和工作都会有很大的帮助的。
6致谢
在这次课程设计的撰写过程中,我得到了许多人的帮助。
首先我要感谢我的老师在课程设计上给予我的指导、提供给我的支持和帮助,这是我能顺利完成这次报告的主要原因,更重要的是老师帮我解决了许多技术上的难题,让我能把系统做得更加完善。
在此期间,我不仅学到了许多新的知识,而且也开阔了视野,提高了自己的设计能力。
其次,我要感谢帮助过我的同学,他们也为我解决了不少我不太明白的设计商的难题。
同时也感谢学院为我提供良好的做毕业设计的环境。
最后再一次感谢所有在设计中曾经帮助过我的良师益友和同学。
参考文献
[1]朱定华,戴汝平.单片微机原理与应用.(M)北京:
清华大学出版社,2003
[2]杨宁.单片机与控制技术[M].北京:
航空航天大学出版社,2005.
[3]周润景张丽娜.基与PROTEUS的电路及单片机仿真[M].北京:
航空航天大学出版社,2007.
[4]张万奎.模拟电子技术[M].湖南:
湖南大学出版社,2005.
[5]康华光.数字电子技术基础[M].北京:
高等教育出版社,2007
[6]蔡明文等.单片机课程设计[M].湖北:
华中科技大学出版社,2007
附录一:
自动打铃系统原理图
附录二:
元件清单
数码显示管
6片
晶振
12M
按键
5个
电阻
若干
电容
若干
三极管
若干
二极管
若干
8255
1片
附录三:
程序
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitRING=P3^3;
#defineHOR_UP0x18//定义键值意义
#defineMIN_UP0x28
#defineHOR_DOWN0X14
#defineMIN_DOWN0x24
#defineAM_PM0X48
#defineNO_KEY_DOWN0XFF
ucharxdataPA_at_0xD9FF,PB_at_0XDBFF,PC_at_0XDDFF,//定义外部变量,强制分配地址
EX_PORT_CON_at_0XDFFF;
ucharcodeLED_CODE[]={0XA0,0XBB,0X62,0X2A,0X39,0X2C,0X24,0XBA,//LED段码(0~9外加一个全灭,一个A,一个P)
0X20,0X28,0XFF,0X30,0X70};
uintcodeRING_TIME[]={450,1350};//开启时间(分)
ucharCOUNT=0,KEY=NO_KEY_DOWN,HOR=0,MIN=0,SEC=0;//软计时-光标-键值
voidDisplay();//显示
voidTime_Go();//时间进位
voidTime_Set();//时间设置
voidRing_Control();//继电器控制
voidDelay(uintA);//简单延时
ucharKey_Scan();//键盘扫描
voidmain()
{EX_PORT_CON=0X81;//8255初始化(PA,PB,PC_H输出,PC_L输入)
PC=0xF0;//键盘初始化
TH0=0X3C;//定时器初始化
TL0=0XB2;
TH1=TL1=0;
TR1=0;
TMOD=0X21;
EA=ET0=TR0=ET1=1;
while
(1)
{
Display();
Time_Go();
KEY=Key_Scan();
Ring_Control();
Time_Set();
}
}
voidDisplay()
{
PB=0XFF;//消影
PA=0XFe;//发送位码
if(HOR>=12)PB=LED_CODE[12];//发送段码
elsePB=LED_CODE[11];
Delay(200);//延时
PB=0XFF;//消影
PA=0XFd;
if(HOR>12)//发送位码
PB=LED_CODE[(HOR-12)/10];
elsePB=LED_CODE[HOR/10];//发送段码
Delay(200);//延时
PB=0XFF;
PA=0xfb;
if(HOR>12)PB=LED_CODE[(HOR-2)%10];
elsePB=LED_CODE[HOR%10];
Delay(200);
PB=0XFF;//中间横杆
PA=0XF7;
if(COUNT>10)//在显示实时时钟时闪烁,为01秒/周期
PB=0XFF;
else
PB=0X7F;
Delay(200);
PB=0XFF;
PA=0Xef;
PB=LED_CODE[MIN/10];
Delay(200);
PB=0XFF;
PA=0XdF;
PB=LED_CODE[MIN%10];
Delay(130);
}
voidTimer()interrupt1
{TH0=0X3C;//重装初值
TL0=0XB2;
COUNT++;//软计时
}
voidRing()interrupt3
{
RING=~RING;
}
voidTime_Go()//时间进位
{
if(COUNT>=20)//计数到达20次,即:
定时器50MS*20=1S
{
COUNT=0;//软计时清零
SEC+=1;//秒加1
if(SEC>=60)//秒是否到达60
{SEC=0;//清秒位
MIN+=1;//分钟加1
if(MIN>=60)//分钟是否到达60
{MIN=0;//清分位
HOR+=1;//小时加1
if(HOR>=24)//小时是否到达24
HOR=0;//清小时位
}
}
}
}
voidTime_Set()
{
if(KEY==HOR_UP){if(HOR>=23)HOR=0;elseHOR++;}
elseif(KEY==HOR_DOWN){if(HOR==0)HOR=23;elseHOR--;}
elseif(KEY==MIN_UP){if(MIN>=59)MIN=0;elseMIN++;}
elseif(KEY==MIN_DOWN){if(MIN==0)MIN=59;elseMIN--;}
elseif(KEY==AM_PM){if(HOR>=12)HOR-=12;elseHOR+=12;}
}
voidRing_Control()//继电器控制
{
uintRTC_MIN;
RTC_MIN=HOR*60+MIN;//将实时时钟化成分钟
if((RTC_MIN==RING_TIME[0])||(RTC_MIN==RING_TIME[1]))
{if(((SEC>5)&&(SEC<8))||(SEC>=13)){TR1=0;RING=1;}
elseTR1=1;
}
}
voidDelay(uintA)
{while(A--);
}
ucharKey_Scan()
{ucharA=4,ROW=0x08,T=NO_KEY_DOWN;
if(PC!
=0XF0)//是否有键按下
{Delay(200);//消抖
if(PC!
=0XF0)
while(A--)//查询,逐列
{ROW<<=1;
PC=ROW;
T=(PC&0X0F);
if(T!
=0X00)//但前列是否有键被按下
{T=(T+(ROW&0XF0));//计算键值
do{Display();Time_Go();}//防止数码管在按键按下时闪烁
while((PC&0X0F)!
=0);//松手检测
break;//跳出循环
}
}PC=0xf0;//键盘初始化
}
returnT;//返回键值
}