毕业综合训练 (毕业论文/设计形式用) 课题名称 单片机打铃系统设计 学 院 信息工程学院 专 业 电子信息工程设计 班 级 13专电子1班 姓 名 李跃 学号 2013242638 指导老师 何健 江西科技学院 毕业综合训练任务书 学院 信息工程学院 专业 电子信息工程技术 年级 13 班级 电子专1班 姓名 李跃 起止日期 题目 单片机打铃设计 1.毕业综合训练任务及要求(根据题目性质对学生提出具体要求) 设计基于单片机的打铃装置,用DS1302对时、分、秒计时和设置打铃时间,采 用三线串行数据传输接口与STC89C52进行同步通信,用矩阵键盘来设置时间值, 并通过8255芯片读入设置值,最后通过89C52单片机芯片综合控制[1],把当前 时间送到数码管显示,到点把信号送入蜂鸣器,实现打铃,撰写毕业论文。 2.毕业综合训练的原始资料及依据(包括做调研的背景,研究条件、 应用环境等) 3.主要参考资料、文献 [1] 张鑫. 单片机原理及应用[M].北京:电子工业出版社,. [2] 康光华. 电子技术基础. 模拟部分[M].北京:高等教育出版社,. [3] 康光华. 电子技术基础. 数字部分[M].北京:高等教育出版社,. [4] 祁伟, 杨亭. 单片机C51程序设计教程与实验[M].北京:北京航空航天大学出版社, 2006. [5] 楼然苗. 李光飞. 单片机课程设计指导[M].北京:北京航空航天大学出版社, [6] 单片机学习网 指导教师 年 月 日 摘 要 随着科学技术的飞速发展,单片机应用的范围越来越广,本设计正是基于STC89C52型单片机为核心,加上适当的外围部件,设计而成的简易自动打铃系统。 简易自动打铃系统的设计以STC89C52单片机芯片和8255芯片的拓展I/0引脚为核心部件,用定时器中断系统进行计时、数码管显示当前时间、蜂鸣器实现打铃功能、矩阵键盘调整显示时间、电源电路为整个系统提供5V 工作电压,由以上模块构成了本系统。根据设计要求,该简易自动打铃系统可以进行计时和显示,设置当前时间,实现定点打铃等功能。该设计简单、实用、操作便捷。 关键字:单片机;自动定点打铃;设置时间;中断;矩阵键盘;I/O扩展; 目录 摘 要............................................................................................................................ I 第一章 方案论证与对比.............................................................................................. 1 方案一 采用时钟芯片和键盘实现功能 .............................................................. 1 方案二:采用中断定时实现功能 ........................................................................ 1 方案比较 ................................................................................................................ 2 第二章 单元电路设计与论证...................................................................................... 3 单片机、I/O拓展 . ..................................................................................................... 3 打铃电路设计 . ............................................................................................................ 4 数码管电路设计 . ........................................................................................................ 4 第三章 程序设定.......................................................................................................... 5 主程序工作流程..................................................................................................... 5 定时器中断子程序 ................................................................................................ 5 时间设定子程序 . ........................................................................................................ 6 第四章 系统功能实际测试 ......................................................................................... 7 程序实际编译测试 . .................................................................................................... 7 系统实际测试 . ............................................................................................................ 7 软件调试步骤 ............................................................................................................ 7 子程序调试步骤 . ........................................................................................................ 7 调试结果 . .................................................................................................................... 8 系统误差及性能分析 . ................................................................................................ 8 第五章 设计总结 ......................................................................................................... 9 第六章 详细仪器清单 ............................................................................................... 10 参考文献 ..................................................................................................................... 11 附录1 详细程序......................................................................................................... 12 第一章 方案论证与对比 方案一 采用时钟芯片和键盘实现功能 方案一原理框图如图所示: 图 采用时钟芯片定时实现功能 该系统用DS1302对时、分、秒计时和设置打铃时间,采用三线串行数据传输接口与STC89C52进行同步通信,用矩阵键盘来设置时间值,并通过8255芯片读入设置值,最后通过89C52单片机芯片综合控制[1],把当前时间送到数码管显示,到点把信号送入蜂鸣器,实现打铃。 方案二:采用中断定时实现功能 方案二原理框图如图 所示: 图 采用中断定时实现功能 该系统以STC89C52单片机为核心控制部件。用8255做I/O拓展芯片,数码管接8255的PA 、PB 引脚,用动态扫描的方式显示当前时间。蜂鸣器与单片机的口相连,当打铃时间到时,由STC89C52发出打铃指令。以外部INT0和INT1中断按钮实现调时功能。 方案比较 本设计要求能实现基本计时和打铃功能。计时和打铃时间设计,方案一中用到了DS1302时钟芯片计时和打铃时间设置;方案二中采用定时器中断来计时并结合软件设置打铃时间。上述两种方案中:方案一的外围硬件电路设计复杂,而且时钟芯片没有得到充分利用,而方案二的软件计时具有硬件开销小,成本低,外围电路设计简单等优点。上述两种方案中:方案一的软件设计比方案二的难度系数大,使程序易读性不强。综合对计时的精密程度要求不高的本系统,本设计采用方案一来实现功能。 第二章 单元电路设计与论证 硬件设计总框图 本设计主要由STC89C52单片机芯片与8255芯片组成的模块为控制核心、蜂鸣器电路模块实现打铃功能、矩阵键盘模块调整当前时间、数码管显示模块显示时间,由以上四大模块构成了本系统,详细电路图见附录一,硬件设计总框图如图: 图硬件设计总框图 单片机、I/O拓展 图 主控电路框图 STC89C52RC 是一个低功耗,高性能CMOS 8位单片机,片内含8k Bytes ISP的可反复擦写1000次的Flash 只读程序存储器,器件采用ATMEL 公司的高密度、非易失性存储技术制造,兼容标准MCS-51指令系统及80C51引脚结构,芯片内集成了通用8位中央处理器和ISP Flash存储单元,功能强大的微型计算机的STC89C52可为许多嵌入式控制应用系统提供高性价比的解决方案。STC89C52具有如下特点:40个引脚,8k Bytes Flash片内程序存储器,256 bytes的随机存取数据存储器(RAM ),32个外部双向输入/输出(I/O)口,5个中断优先级2层中断嵌套中断,2个16位可编程定时/计数器,2个全双工串行通信口,看门狗 (WDT )电路,片内时钟振荡器。其主要特性[1]如有:与MCS-51 兼容;8k 可反复擦写(>1000次)Flash ROM;全静态工作:0Hz~24MHz;三级程序存储器锁定;256*8位内部RAM ;32可编程I/O线;2个16位可编程定时/计数器;5个中断源;可编程串行通道;低功耗的空闲和掉电模式。I/O拓展采用8255芯片,单片机用89C52,电路框图如图2-2所示。 打铃电路设计 采用P 型三极管为蜂鸣器提供5V 电源,并把STC89C52的口与三极管的基极相连接,当口有低电平输入出时,三极管导通[2],蜂鸣器响应,从而实现打铃功能。电路框图如图所示: 图打铃电路框图 数码管电路设计 8255的PA 口控制数码管的位选,低电平有效;PB 口做为段选输出,接1K 欧姆的限流电阻[3]。如图所示: 图数码管显示电路框图 第三章 程序设定 主程序工作流程 主程序首先设置8255模式,并打开中断0,设置中断为边沿触发模式;其次在死循环中执行读秒显示子程序,当定时器满一秒时,在显示缓冲区中时间加一,等待送入数码管显示;再次按键扫描子程序,如果有中断0或中断1按钮被按下时,则转入相应功能的子程序中;最后如果当前显示时间满足预设打铃条件,通过打铃判断子程序跳入对应的打铃方式中执行[4]。详细主程序见附录二,主程序流程图如图。 图 主程序流程图 定时器中断子程序 此子程序为本设计的核心之一,首先初始化定时器T0,设置T0为工作方式1,其初始值为3CB0H (既每次溢出定时50ms ),并对其循环20次,然后把时间加1s ,并送入显示缓冲区等待显示[5]。显示时,先取出内存地址中的数据,然后查得对应的显示用段码从PB 口输出,PA 口将对应的数码管选中供电,就能显示缓冲区中的数据值。为了显示秒位和上下午标志在数码管显示上特加了“—”、“A ”、“P ”这三个特殊字符子。程序流程图如图: 图 定时器中断显示子程序流程图 时间设定子程序 时间设定模块的设计要点是按键的去抖处理与“一键多态” [5] 的处理。即 只涉及2个键完成了6位时间参数的设定。“一键多态”即多种功能的实现思想史,根据按键时刻的系统状态,决定按键采取何种动作,即何种功能。 图 键盘扫描子程序流程图 第四章 系统功能实际测试 程序实际编译测试 在Keil C51编译环境下编译过程中所产生的误差主要是在重装初值的过程中大约需要8个机器周期,本设计采用在程序开始时对定时器赋初值多加8个机器周期来消除此误差。 最后在Keil C51编译环境下编译通过,0警告,0错误。 系统实际测试 通过实验测试,数码管显示,按键调时,定时打铃均符合预期,测试成功。 软件调试步骤 1、打开软件后, 在Project 菜单中选择New Project命令,打开一个新项目。保存此项目,输入工程文件名后,并保存工程文件的目录。 2、为项目文件选择一个目标器件,即选择8051的类型。在Data base 列表框中选择“ATML 89C52”,确定。 3、上述设置好后,创建源程序文件并输入程序代码。输入好代码后点击“文件/保存”。 4、把源文件添加到项目中,用鼠标指在目标工作区的目标1,点击右键在弹出的菜单中选择添加文件到源代码组,在弹出的添加文件框中,选择需要添加到项目中的文件。 5、开始编译,对项目文件进行编译。若没有错误后进行硬件调试。 子程序调试步骤 子程序调试应一个模块一个模块地进行,首先单独调试各功能子程序,检查程序是否能够实现预期的功能,接口电路的控制是否正常等;最后逐步将各子程序连接起来进行总调试。故调试步骤[6]如下: A 、蜂鸣器的调试 调试方法:先把打铃程序下载到单片机,让蜂鸣器发声,看是否在正确的时间内实现打铃。 B 、数码管程序调试 正确的显示时间是整个程序的关键之一。调试方法:先把程序下载到单片机,让数码管显示,是否正确的显示时间的变化。 C 、键盘调时序 正确的显示所调的时间是整个程序的关键之一。调试方法:先把键盘程序和显示程序下载到单片机,让数码管显示,是否正确的所调时间的变化。 调试结果 实现计时和显示功能(12小时制),可设置当前时间(包括上下午标志,时、分的数字显示),能在上午7:45和下午10:00定点打铃,且每次打铃均为响铃3s ,停1s ,再响3s 。 系统误差及性能分析 经测试该简易自动打铃系统在一天内会出现时间误差,该误差主要是由于晶振自身的误差所造成的。另外在中断的过程中,只会在第一次计时时产生时间的偏移,而它所产生累积误差很小,可以忽略。 第五章 设计总结 通过这次课程设计,我们得到了很多收获和体会,懂得了团队合作的重要性和必要性,以及工程设计的大体过程。第一,巩固和加深了对单片机基本知识和理解,提高了综合运用所学知识的能力。第二,增强了根据课程需要选学参考资料,查阅手册,图表和文献资料的自学能力。通过独立思考,深入研究有关问题,学会自己分析解决问题的方法。第三,通过实际方案的分析比较,设计计算,安装调试等环节,初步掌握了简单使用电路的分析方法和工程设计方法。第四,在这次课程设计过程中,光有理论知识是不够的,还必须懂一些实践中的知识。所以在课程设计的实践中,我们应将实验课与课堂教学结合起来,锻炼自己的理论联系实际的能力与实际动手能力。第五,掌握了比较常用的仪器的使用方法,提高了动手能力。第六,培养了严谨的工作作风和科学态度。 总之这次课程设计,培养了我们综合应用单片机原理及应用的理论知识和理论联系实际的能力;在设计的过程中还培养了我们的团队精神,同学共同协作,一齐商量讨论,解决了许多问题。这一切都令我们受益匪浅,在今后的学习工作中我们会一如既往,不断努力。 第六章 详细仪器清单 图详细仪器清单 参考文献 [1] 张鑫. 单片机原理及应用[M].北京:电子工业出版社,. [2] 康光华. 电子技术基础. 模拟部分[M].北京:高等教育出版社,. [3] 康光华. 电子技术基础. 数字部分[M].北京:高等教育出版社,. [4] 祁伟, 杨亭. 单片机C51程序设计教程与实验[M].北京:北京航空航天大学出版社,2006. [5] 楼然苗. 李光飞. 单片机课程设计指导[M].北京:北京航空航天大学出版社, [6] 单片机学习网 附录1 详细程序 #include #include #define uchar unsigned char #define uint unsigned int sbit RING=P3^3; #define HOR_UP 0x18 //定义键值意义 #define MIN_UP 0x28 #define HOR_DOWN 0X14 #define MIN_DOWN 0x24 #define AM_PM 0X48 #define NO_KEY_DOWN 0XFF uchar xdata PA _at_ 0xD9FF, PB _at_ 0XDBFF, PC _at_ 0XDDFF, //定义外部变量,强制分配地址 EX_PORT_CON _at_ 0XDFFF; uchar code LED_CODE[]={0XA0,0XBB,0X62,0X2A,0X39,0X2C,0X24,0XBA, //LED段码(0~9外加一个全灭, 一个A ,一个P) 0X20,0X28,0XFF,0X30,0X70}; uint code RING_TIME[]={465,1320}; //开启时间(分) uchar COUNT=0,KEY=NO_KEY_DOWN,HOR=0,MIN=0,SEC=0; //软计时-光标-键值 void Display(); //显示 void Time_Go(); //时间进位 void Time_Set(); //时间设置 void Ring_Control(); //继电器控制 void Delay(uint A); //简单延时 uchar Key_Scan(); //键盘扫描 void main() { EX_PORT_CON=0X81; //8255初始化(PA,PB ,PC_H输出,PC_L输入) PC=0xF0; //键盘初始化 TH0=0X3C; //定时器初始化 TH1=TL1=0; TR1=0; TMOD=0X21; EA=ET0=TR0=ET1=1; while(1) { Display(); Time_Go(); KEY=Key_Scan(); Ring_Control(); Time_Set(); } } void Display() { PB=0XFF; //消影 PA=0XFe; //发送位码 if(HOR>=12)PB=LED_CODE[12]; //发送段码 else PB=LED_CODE[11]; Delay(200); //延时 PB=0XFF; //消影 PA=0XFd; if(HOR>12) //发送位码 PB=LED_CODE[(HOR-12)/10]; else PB=LED_CODE[HOR/10]; //发送段码 Delay(200); //延时 PB=0XFF; PA=0xfb; if(HOR>12)PB=LED_CODE[(HOR-2)%10]; else PB=LED_CODE[HOR%10]; Delay(200); PB=0XFF; //中间横杆 PA=0XF7; if(COUNT>10)//在显示实时时钟时闪烁,为01秒/周期 PB=0XFF; else Delay(200); PB=0XFF; PA=0Xef; PB=LED_CODE[MIN/10]; Delay(200); PB=0XFF; PA=0XdF; PB=LED_CODE[MIN%10]; Delay(130); } void Timer() interrupt 1 { TH0=0X3C; //重装初值 TL0=0XB2; COUNT++; //软计时 } void Ring() interrupt 3 { RING=~RING; } void Time_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; //清小时位 } } } } void Time_Set() { if(KEY==HOR_UP){if(HOR>=23)HOR=0;else HOR++;} else if(KEY==HOR_DOWN){if(HOR==0)HOR=23;else HOR--;} else if(KEY==MIN_UP){if(MIN>=59)MIN=0;else MIN++;} else if(KEY==MIN_DOWN){if(MIN==0)MIN=59;else MIN--;} else if(KEY==AM_PM){if(HOR>=12)HOR-=12;else HOR+=12;} } void Ring_Control() //继电器控制 { uint RTC_MIN; RTC_MIN=HOR*60+MIN; //将实时时钟 化成 分钟 if((RTC_MIN==RING_TIME[0])||(RTC_MIN==RING_TIME[1])) { if(((SEC>=3)&&(SEC=7)){TR1=0;RING=1;} else TR1=1; } } void Delay(uint A) { while(A--); } uchar Key_Scan() { uchar A=4,ROW=0x08,T=NO_KEY_DOWN; if(PC!=0XF0) //是否有键按下 {Delay(200); //消抖 if(PC!=0XF0) while(A--) //查询,逐列 { ROW if(T!=0X00) //但前列是否有键被按下 { T=(T+(ROW&0XF0)); //计算键值 do {Display();Time_Go();} //防止数码管在按键按下时闪烁 while((PC&0X0F)!=0); //松手检测 peak; //跳出循环 } } PC=0xf0; //键盘初始化 } return T; } //返回键值 16