自动打铃系统 3.docx
《自动打铃系统 3.docx》由会员分享,可在线阅读,更多相关《自动打铃系统 3.docx(24页珍藏版)》请在冰点文库上搜索。
自动打铃系统3
课程设计报告
课程名称:
单片机原理及应用课程设计
设计题目:
简易自动打铃系统
系别:
专业:
班级:
学生姓名:
学号:
起止日期年月日~年月日
指导教师:
教研室主任:
指导教师评语:
指导教师签名:
年月日
成绩评定
项目
权重
成绩
1、设计过程中出勤、学习态度等方面
0.2
2、课程设计质量与答辩
0.5
3、设计报告书写及图纸规范程度
0.3
总成绩
教研室审核意见:
教研室主任签字:
年月日
教学系审核意见:
主任签字:
年月日
摘要
随着科学技术的飞速发展,单片机应用的范围越来越广,本设计正是基于STC89C52型单片机为核心,加上适当的外围部件,设计而成的简易自动打铃系统。
简易自动打铃系统的设计以STC89C52单片机芯片和8255芯片的拓展I/0引脚为核心部件,用定时器中断系统进行计时、数码管显示当前时间、蜂鸣器实现打铃功能、中断0、1按钮调整显示时间、电源电路为整个系统提供5V工作电压,由以上模块构成了本系统。
根据设计要求,该简易自动打铃系统可以进行计时和显示,设置当前时间,实现定点打铃等功能。
该设计简单、实用、操作便捷。
关键字:
单片机;自动定点打铃;设置时间;中断
目录
设计要求1
1.方案论证与对比1
1.1方案一采用时钟芯片和键盘实现功能1
1.2方案二:
采用中断定时实现功能2
1.3方案比较2
2.单元电路设计与论证2
2.1单片机、I/O拓展3
2.2打铃电路设计4
2.3时间设置电路设计4
2.4数码管电路设计5
3系统软件工作流程图5
3.1主程序工作流程5
3.2定时器中断显示子程序6
3.3中断服务子程序6
3.4时间设定子程序7
4.系统功能实际测试8
4.1程序实际编译测试8
4.2系统实际测试8
4.3软件调试步骤8
4.4子程序调试步骤9
4.5调试结果9
4.6系统误差及性能分析10
5.设计总结10
6.详细仪器清单11
7.致谢11
参考文献12
附录13
附录1.整体电路图13
附录2.详细程序14
简易自动打铃系统设计
设计要求
1.基本计时和显示功能(12小时制)。
2.可设置当前时间(包括上下午标志,时、分的数字显示)。
3.能在上午7:
30(早自习)和下午10:
30(晚熄灯)定点打铃,且每次打铃均为响铃5s,停2s,再响5s。
1.方案论证与对比
1.1方案一采用时钟芯片和键盘实现功能
方案一原理框图如图1-1所示:
图1-1采用时钟芯片和键盘实现功能
该系统用DS1302对时、分、秒计时和设置打铃时间,采用三线串行数据传输接口与STC89C52进行同步通信,用矩阵键盘来设置时间值,并通过8255芯片读入设置值,最后通过89C52单片机芯片综合控制[1],把当前时间送到数码管显示,到点把信号送入蜂鸣器,实现打铃。
1.2方案二:
采用中断定时实现功能
方案二原理框图如图1-2所示:
图1-2采用中断定时实现功能
该系统以STC89C52单片机为核心控制部件。
用8255做I/O拓展芯片,数码管接8255的PA、PB引脚,用动态扫描的方式显示当前时间。
蜂鸣器与单片机的P2.0口相连,当打铃时间到时,由STC89C52发出打铃指令。
以外部INT0和INT1中断按钮实现调时功能。
1.3方案比较
本设计要求能实现基本计时和打铃功能。
计时和打铃时间设计,方案一中用到了DS1302时钟芯片计时和打铃时间设置;方案二中采用定时器中断来计时并结合软件设置打铃时间。
上述两种方案中:
方案一的外围硬件电路设计复杂,而且时钟芯片没有得到充分利用,而方案二的软件计时具有硬件开销小,成本低,外围电路设计简单等优点。
调时设计,方案一中用矩阵键盘实现调时功能;方案二中采用外部中断0和1的两个按钮来实现调时。
上述两种方案中:
方案一的软件设计比方案二的难度系数大,使程序易读性不强。
综合对计时的精密程度要求不高的本系统,本设计采用方案一来实现功能。
2.单元电路设计与论证
本设计主要由STC89C52单片机芯片与8255芯片组成的模块为控制核心、蜂鸣器电路模块实现打铃功能、中断0、1按钮模块调整当前时间、数码管显示模块显示时间,由以上四大模块构成了本系统,详细电路图见附录一,硬件设计总框图如图2-1:
图2-1硬件设计总框图
2.1单片机、I/O拓展
图2-2主控电路框图
STC89C52RC是一个低功耗,高性能CMOS8位单片机,片内含8kBytesISP的可反复擦写1000次的Flash只读程序存储器,器件采用ATMEL公司的高密度、非易失性存储技术制造,兼容标准MCS-51指令系统及80C51引脚结构,芯片内集成了通用8位中央处理器和ISPFlash存储单元,功能强大的微型计算机的STC89C52可为许多嵌入式控制应用系统提供高性价比的解决方案。
STC89C52具有如下特点:
40个引脚,8kBytesFlash片内程序存储器,256bytes的随机存取数据存储器(RAM),32个外部双向输入/输出(I/O)口,5个中断优先级2层中断嵌套中断,2个16位可编程定时/计数器,2个全双工串行通信口,看门狗(WDT)电路,片内时钟振荡器。
其主要特性[1]如有:
与MCS-51兼容;8k可反复擦写(>1000次)FlashROM;全静态工作:
0Hz~24MHz;三级程序存储器锁定;256*8位内部RAM;32可编程I/O线;2个16位可编程定时/计数器;5个中断源;可编程串行通道;低功耗的空闲和掉电模式。
I/O拓展采用8255芯片,单片机用89C52,电路框图如图2-2所示。
2.2打铃电路设计
采用P型三极管为蜂鸣器提供5V电源,并把STC89C52的P2.0口与三极管的基极相连接,当P2.0口有低电平输入出时,三极管导通[2],蜂鸣器响应,从而实现打铃功能。
电路框图如图2-3所示:
图2-3打铃电路框图
2.3时间设置电路设计
用中断0开关作为移位开关并接入SCT89C52芯片的P3.2口,设置所需调节的显示位;用中断1开关作为加一开关并接入SCT89C52芯片的P3.3口,对所选调节位进行加一操作。
利用中断按键实现时间设置的电路框图如图2-4所示:
图2-4时间设置电路框图
2.4数码管电路设计
8255的PA口控制数码管的位选,低电平有效;PB口做为段选输出,接1K欧姆的限流电阻[3]。
如图2-5所示:
图2-5数码管显示电路框图
3系统软件工作流程图
3.1主程序工作流程
图3-1主程序流程图
主程序首先设置8255模式,并打开中断0,设置中断为边沿触发模式;其次在死循环中执行读秒显示子程序,当定时器满一秒时,在显示缓冲区中时间加一,等待送入数码管显示;再次按键扫描子程序,如果有中断0或中断1按钮被按下时,则转入相应功能的子程序中;最后如果当前显示时间满足预设打铃条件,通过打铃判断子程序跳入对应的打铃方式中执行[4]。
详细主程序见附录二,主程序流程图如图3-1。
3.2定时器中断显示子程序
此子程序为本设计的核心之一,首先初始化定时器T0,设置T0为工作方式1,其初始值为3CB0H(既每次溢出定时50ms),并对其循环20次,然后把时间加1s,并送入显示缓冲区等待显示[5]。
显示时,先取出内存地址中的数据,然后查得对应的显示用段码从PB口输出,PA口将对应的数码管选中供电,就能显示缓冲区中的数据值。
为了显示秒位和上下午标志在数码管显示上特加了“—”、“A”、“P”这三个特殊字符子。
程序流程图如图3-2:
图3-2定时器中断显示子程序流程图
3.3中断服务子程序
此子程序是为调时时服务的,首先初始化定时器T1,设置T1为工作方式1,其初始值为3CB0H(既每次溢出定时50ms)[1],并对其循环8次,然后使数码管被选中的调时位闪烁,子程序流程图如图3-3所示:
图3-3T1中断服务程序流程图
3.4时间设定子程序
时间设定模块的设计要点是按键的去抖处理与“一键多态”[5]的处理。
即只涉及2个键完成了6位时间参数的设定。
“一键多态”即多种功能的实现思想史,根据按键时刻的系统状态,决定按键采取何种动作,即何种功能。
图3-4键盘扫描子程序流程图
4.系统功能实际测试
4.1程序实际编译测试
在KeilC51编译环境下编译过程中所产生的误差主要是在重装初值的过程中大约需要8个机器周期,本设计采用在程序开始时对定时器赋初值多加8个机器周期来消除此误差。
最后在KeilC51编译环境下编译通过,0警告,0错误。
4.2系统实际测试
实际效果如图4-2所示,达到设计要求。
图4-2实物图
4.3软件调试步骤
1、打开软件后,在Project菜单中选择NewProject命令,打开一个新项目。
保存此项目,输入工程文件名后,并保存工程文件的目录。
2、为项目文件选择一个目标器件,即选择8051的类型。
在Database列表框中选择“ATML89C52”,确定。
3、上述设置好后,创建源程序文件并输入程序代码。
输入好代码后点击“文件/保存”。
4、把源文件添加到项目中,用鼠标指在目标工作区的目标1,点击右键在弹出的菜单中选择添加文件到源代码组,在弹出的添加文件框中,选择需要添加到项目中的文件。
5、开始编译,对项目文件进行编译。
若没有错误后进行硬件调试。
4.4子程序调试步骤
子程序调试应一个模块一个模块地进行,首先单独调试各功能子程序,检查程序是否能够实现预期的功能,接口电路的控制是否正常等;最后逐步将各子程序连接起来进行总调试。
故调试步骤[6]如下:
A、蜂鸣器的调试
调试方法:
先把打铃程序下载到单片机,让蜂鸣器发声,看是否在正确的时间内实现打铃。
B、数码管程序调试
正确的显示时间是整个程序的关键之一。
调试方法:
先把程序下载到单片机,让数码管显示,是否正确的显示时间的变化。
C、键盘调时序
正确的显示所调的时间是整个程序的关键之一。
调试方法:
先把键盘程序和显示程序下载到单片机,让数码管显示,是否正确的所调时间的变化。
4.5调试结果
实现计时和显示功能(12小时制),可设置当前时间(包括上下午标志,时、分的数字显示),能在上午7:
30和下午10:
30定点打铃,且每次打铃均为响铃5s,停2s,再响5s。
4.6系统误差及性能分析
经测试该简易自动打铃系统在一天内会出现时间误差,该误差主要是由于晶振自身的误差所造成的。
另外在中断的过程中,只会在第一次计时时产生时间的偏移,而它所产生累积误差很小,可以忽略。
5.设计总结
通过这次课程设计,我们得到了很多收获和体会,懂得了团队合作的重要性和必要性,以及工程设计的大体过程。
第一,巩固和加深了对单片机基本知识和理解,提高了综合运用所学知识的能力。
第二,增强了根据课程需要选学参考资料,查阅手册,图表和文献资料的自学能力。
通过独立思考,深入研究有关问题,学会自己分析解决问题的方法。
第三,通过实际方案的分析比较,设计计算,安装调试等环节,初步掌握了简单使用电路的分析方法和工程设计方法。
第四,在这次课程设计过程中,光有理论知识是不够的,还必须懂一些实践中的知识。
所以在课程设计的实践中,我们应将实验课与课堂教学结合起来,锻炼自己的理论联系实际的能力与实际动手能力。
第五,掌握了比较常用的仪器的使用方法,提高了动手能力。
第六,培养了严谨的工作作风和科学态度。
总之这次课程设计,培养了我们综合应用单片机原理及应用的理论知识和理论联系实际的能力;在设计的过程中还培养了我们的团队精神,同学共同协作,一齐商量讨论,解决了许多问题。
这一切都令我们受益匪浅,在今后的学习工作中我们会一如既往,不断努力。
6.详细仪器清单
类型
规格
数量
备注
5V直流电源
ZH-6003
1
USB232converter
U232-P9
1
电阻
1k
13个
芯片
8255
1片
扩展I/O
芯片
STC89C52
1片
晶振
12M
1个
蜂鸣器
无源
1个
数码管
3位共阳极
2个
极性电容
0.1UF
1个
非极性电容
30pf
2个
LED
2个
工作指示灯
按键开关
3个
单刀双掷开关
1个
三极管
7个
7.致谢
经过近几天的课程设计,我们组的成员都充分认识到理论知识和实践结合的重要性。
经过两年多的理论基础的学习,我们成功的将理论运用如实践,并成功的运用单片机,以前只是在路上看见那些交通灯,但是并没有认真的研究交通灯的内部控制原理,还有单片机上那些芯片的功能和引脚图平常也不是常接触,通过这次城市道口交通灯控制系统设计让我清楚如果想做一个产品该怎样思考。
此次课程设计持续的时间较长,对组员的耐心是一种极大的考验,同时学校的支持力度也应该加强,而不应该对学生的提问表示不解,对有些程序的编写要及时的给予指导,当然学生也要积极的配合老师的工作,努力将自己所学的知识尽可能的运用到对方案的设计中去。
感谢老师的细心指导、和伙伴之间的配合。
参考文献
[1]张鑫.单片机原理及应用[M].北京:
电子工业出版社,2005.8.
[2]康光华.电子技术基础.模拟部分[M].北京:
高等教育出版社,2006.1.
[3]康光华.电子技术基础.数字部分[M].北京:
高等教育出版社,2006.1.
[4]祁伟,杨亭.单片机C51程序设计教程与实验[M].北京:
北京航空航天大学出版社,2006.
[5]楼然苗.李光飞.单片机课程设计指导[M].北京:
北京航空航天大学出版社,2007.4
[6]单片机学习网
附录
附录1.整体电路图
附录2.详细程序
#include"reg52.h"
#include
#definePAXBYTE[0xD1FF]/*PA口地址*/
#definePBXBYTE[0xD2FF]/*PB口地址*/
#definePCXBYTE[0xD5FF]/*PC口地址*/
#defineCONXBYTE[0xD7FF]/*控制字地址*/
#defineucharunsignedchar
CodeChardis_7[14]={0xA0,0xBB,0x62,0x2A,0x39,0x2C,0x24,0xBA,0x20,0x28,0xff,0x7f,0x30,0x70};
/*共阳LED段码表"0""1""2""3""4""5""6""7""8""9""不亮""-""A""P"*/
codecharscan_con[8]={0xDF,0xEF,0xF7,0xFB,0xFD,0xFE,0xBF,0x7f};//列扫描控制字
datachardisdata[8]={0x08,0x05,0x09,0x02,0x0b,0x00,0x01,0x0d};//计时单元数据初值,共6个
datachardis[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x0a,0x00};//显示单元数据,共6个数据
datacharcon1s=0x00,con04s=0x00,con=0x00,con05s=0x00,d=0x00;//1秒定时用
sbitkey0=P3^2;//移位键
sbitkey1=P3^3;//加一
sbitBEEP=P2^0;//蜂鸣器接口
/****************/
//1毫秒延时程序//
/***************/
delay1ms(intt)
{
inti,j;
for(i=0;ifor(j=0;j<120;j++);
}
/***********/
//扫描程序//
/**********/
scan()
{
chark;
for(k=0;k<6;k++)
{
CON=0X89;
PB=dis_7[dis[k]];PA=scan_con[k];delay1ms
(1);PA=0xff;
}
}
/*****************/
//键盘调时程序//
/******************/
keyscan()
{
EA=0;
if(key0==0)
{
delay1ms(10);
while(key0==0);
if(dis[con]==10)
{dis[7]=dis[con];dis[con]=dis[6];dis[6]=dis[7];}
con++;TR0=0;ET0=0;TR1=1;ET1=1;
if(con>=6)
{con=0;TR1=0;ET1=0;TR0=1;ET0=1;}
}
if(con>=0)
{
if(key1==0)
{
delay1ms(10);
while(key1==0);
d=con+2;
disdata[d]++;
if(disdata[d]>=14)
{disdata[d]=0;}
dis[con]=disdata[d];dis[6]=0x0a;
}
}
EA=1;
}
/************/
//打铃程序/
/*************/
Play1()
{
uchari,t;
for(i=0;i<100;i++)
{
BEEP=~BEEP;
delay1ms(t);
}
BEEP=1;
}
Play2()
{BEEP=1;}
bell()
{if((disdata[0]==0x00||disdata[0]==0x01||disdata[0]==0x02||disdata[0]==0x03||disdata[0]==0x04)&&disdata[1]==0x00&&disdata[2]==0x00&&disdata[3]==0x03&&disdata[5]==0x07&&disdata[6]==0x00&&disdata[7]==0x0c||(disdata[0]==0x00||disdata[0]==0x01||disdata[0]==0x02||disdata[0]==0x03||disdata[0]==0x04)&&disdata[1]==0x00&&disdata[2]==0x00&&disdata[3]==0x03&&disdata[5]==0x00&&disdata[6]==0x01&&disdata[7]==0x0d)
{Play1();}
if((disdata[0]==0x05||disdata[0]==0x06)&&disdata[1]==0x00&&disdata[2]==0x00&&disdata[3]==0x03&&disdata[5]==0x07&&disdata[6]==0x00&&disdata[7]==0x0c||(disdata[0]==0x05||disdata[0]==0x06)&&disdata[1]==0x00&&disdata[2]==0x00&&disdata[3]==0x03&&disdata[5]==0x00&&disdata[6]==0x01&&disdata[7]==0x0d)
{Play2();}
if(((disdata[0]==0x07||disdata[0]==0x08||disdata[0]==0x09)&&disdata[1]==0x00||(disdata[0]==0x00||disdata[0]==0x01)&&disdata[1]==0x01)&&disdata[2]==0x00&&disdata[3]==0x03&&disdata[5]==0x07&&disdata[6]==0x00&&disdata[7]==0x0c||((disdata[0]==0x07||disdata[0]==0x08||disdata[0]==0x09)&&disdata[1]==0x00||(disdata[0]==0x00||disdata[0]==0x01)&&disdata[1]==0x01)&&disdata[2]==0x00&&disdata[3]==0x03&&disdata[5]==0x00&&disdata[6]==0x01&&disdata[7]==0x0d)
{Play1();}
}
/************/
//初始化程序//
/*************/
clearmen()
{
inti;
for(i=0;i<6;i++)
{
dis[i]=disdata[i];
}
TH0=0x3C;TL0=0xB0;//;50MS定时初值(T0计时用)
TH1=0x3C;TL1=0xB0;//;50MS定时初值(T1计时用)
TMOD=0X01;ET0=1;ET1=1;TR1=0;TR0=1;EA=1;
}
/**********/
//主程序//
/*********/
main()
{
clearmen();
while
(1)
{
scan();
keyscan();
bell();
}
}
/********************/
//1秒中断处理程序//
/*******************/
voidtime_intt0(void)interrupt1
{
ET0=0;TR0=0;TH0=0x3C;TL0=0xB0;TR0=1;
con1s++;
con05s=con1s%10;
if(con05s==0)
{
disdata[4]--;
if(disdata[4]==9)
{disdata[4]=11;}
if(con1s==20)
{
con1s=0x00;
disdata[0]++;
if(disdata[0]>=10)
{
disdata[0]=0;disdata[1]++;
if(disdata[1]>=6)
{
disdata[1]=0;disdata[2]++;
if(disdata[2]>=10)
{
disdata[2]=0;disdata[3]++;
if(disdata[3]>=6)
{
disdata[3]=0;disdata[5]++;
if(disdata[5]>=10)
{
disdata[5]=0;disdata[6]++;
}
if(disdata[6]==1)
{
if(disdata[5]==2)
{
disdata[5]=0;disdata[6]=0;disdata[7]++;
if(disdata[7]==14)
{disdata[7]=