论文题目 | 基于单片机的多路抢答器的设计 |
作者姓名 | 龙鑫 |
指导教师 | 杨(晓辉)老师 |
所在院系 | 信息工程学院 |
专业名称 | 电气卓越 |
完成时间 | 2014年6月30日 |
1.1 电路组成框图 1
1.2 电路原理图 2
2.电路硬件设计 2
2.2按键电路 6
2.3显示电路 7
2.4报警电路 8
3.系统软件的设计 9
3.1编译软件——Keil C 9
3.2仿真软件——Proteus 10
4.调试及故障分析 11
4.1程序调试 11
5.总结 12
参考文献 14
附录一 15
基于单片机的多路智能抢答器的设计
1.电路原理图的设计
根据设计功能的要求,电路应该包括控制电路,按键电路,以及用来显示裁决结果的显示电路。除了用数码管显示目前的动作情形,同时也需要用声音提醒或者警告操作人员,因此也在电路设计时加入了报警电路。
1.1 电路组成框图
抢答器电路总体设计方框图如图1所示:
图1 抢答器总体设计方框图
1.2 电路原理图
抢答器电路原理图如图2所示,控制电路以单片机ATC51为核心,按键电路采用矩阵式键盘的接法,显示电路采共阴极数码管动态显示,报警采用蜂鸣器报警电路。
图2 抢答器电路设计原理图
2.电路硬件设计
电路硬件包括:单片机最小系统(即控制电路)、按键电路、显示电路、报警电路。
2.1单片机最小系统
(1)系统结构
总线型单片机非总线应用的最小系统示意图如图3所示,只有单片机和时钟电路、复位电路构成的最简单电路,并行总线不用于外围扩展,可作为应用系统的I/O口使用。
图3 总线型单片机非总线应用的最小系统
(2)系统特点
有大量可使用的I/O口;
没有并行扩展,应用系统结构简单;
外围器件只能通过UART口的串行移位方式或虚拟串行扩展总线进行扩展。
(3)ATC51单片机
微控制器选用ATMAL公司生产的ATC51,该芯片货源充足,并且价格也比较便宜。如表1所示。
表1 器件选型方案的详细清单
器件名称 | 规格型号 | 数量 |
微处理器 | ATC51 | 1 |
芯片 | 74LS04 | 1 |
74HC30 | 1 | |
电阻 | 3WTT10K | 8 |
电容 | 20PF | 3 |
晶振 | 12MHZ | 1 |
按钮 | 11 | |
7段数码管 | 7SEG-MPX4-CA | 4 |
扬声器 | 1 |
ATC51单片机是ATMAL公司系列单片机的一种8位Flash单片机。它最大特点是片内含有Flash存储器,用途十分广泛,特别是在生产便携式商品,手提式仪器等方面,有着十分广泛的应用[6]。
ATC51单片机内部主要有以下部件:8031CPU、振荡电路、总线控制部件、中断控制部件、片内Flash存储器、片内RAM、并行I/O接口、定时器和串行I/O接口
ATC51是系列单片机的标准型,它是与MSC-51系列单片机兼容的。在内部含有4KB或8KB可重复编程的Flash存储器,可进行1000次擦写操作。全静态工作为0-24MHZ,有3级程序锁存器,内部含有128-256字节的RAM,有32条可编程I/O口线,2-3个16位定时/计数器,6-8个中断源,通用的串行接口,低电压空闲及电源下降方式。
ATC51单片机内部由CPU、4KB的FPEROM ,128B的RAM,两个16位的定时/计数器T0和T1,4个8位的I/O端P0、P1、P2、P3等组成。单片微机内部最核心的部分是CPU。CPU主要功能是产生各种控制信号,控制存储器、输入/输出端口的数据传输、数据的算术运算、逻辑运算以及位操作处理等,CPU按其功能可分为运算器和控制器两部分。控制器由程序计数器PC、指令储存器、指令译码器、实时控制与条件转移逻辑电路等组成。它的功能是对来自存储器中的指令进行译码,通过实时控制电路,在规定的时刻发出各种操作所需的内部和外部的控制信号,使各部分协调工作,完成指令所规定的操作。运算器由算术逻辑器部件ALU、累加器ACC、暂存器、程序状态字寄存器PSW,BCD码运算调整电路等组成。
图2-3 ATC51单片机的内部结构图
为了提高数据处理和位操作功能,片内增加了一个通用寄存器B和一些专用寄存器,还增加了位处理逻辑电路的功能。其内部结构如图3所示。
ATC51的主要性能包括:ATC51与MCS—51控制器系列产品兼容,片内有4K可在线重复编程闪速电擦除存储器(Flash Memory),存储器可循环写入/擦除1000次;存储器数据保存时间可达10年;工作电压范围宽:Vcc可由2.7V到6V;全静态工作可由0Hz到16MHz;程序存储器具有3级锁存保护;128*8位内部RAM;32条可编程I/O线;两个16位定时器/计数器;中断结构具有5个中断源和2个中断优先级;可编程全双工串行通信;空闲状态维持低功耗和掉电状态保存存储内容。
(4)时钟电路
时钟电路用于产生单片机工作所需要的时钟信号。设计中采用了比较典型的内部时钟方式,如图6所示:
其工作原理是:片内高增益反向放大器XTAL1、XTAL2外接作为反馈元件的晶体(呈感性)与电容组成的并联谐振回路构成一个自激振荡器向内部时钟电路提供振荡时钟。
振荡器的频率主要取决于晶体的振荡频率,一般晶体可以在1.2-12MHz之间任选。电容的大小影响振荡器电路的稳定性和快速性,其值有微调作用,通常取30pF左右。在设计电路板时,晶振和电容应尽可能的靠近芯片,以减小分布电容,保证振荡器振荡的稳定性[7]。
图6 单片机外接晶体的接法
(5)复位电路
复位是单片机的初始化操作,其主要功能是将程序计数器PC初始化为0000H,使单片机从0000H单元开始执行程序。复位操作不影响片内RAM的内容,但是对SFR中的一些寄存器有影响。
图7 各种复位电路
单片机的复位是靠外部电路复位的。其复位方式有上电复位和按键手动复位两种。复位电路中的电阻、电容数值的设置,是为了保证在RST管脚处至少保持两个机器周期(24个振荡周期)的高电平而完成复位过程的,也就是在斯密特触发器的输入端维持在最低阀值电压以上足够长时间,使斯密特触发器产生一个正脉冲。电阻值通常为1K,电容值通常为22uF。图7为几种常见的复位电路接法[8]。
2.2按键电路
(1)键盘接口和键输入软件中应解决的几个问题
消除抖动
按键的合断过程存在一个抖动的暂态过程,这种抖动的暂态过程大约经过5-10ms的时间,人的肉眼是察觉不到的,但对于高速的CPU是有反应的,可能产生误处理。为了保证键动作一次,仅作一次处理,必须采取措施以消除抖动。本设计中采用了软件消抖的方法。
软件消抖是用延时来躲过暂态抖动过程,执行一段大于10ms的延时程序后,再读取稳定的键状态。
键盘的监测方法
对于计算机应用系统,键盘扫描只是CPU工作的一部分,键盘处理只是在有键按下时才有意义。对于是否有键按下的信息输入方式有中断方式和查询方式两种。
(2)行列式键盘工作原理
行列式键盘又叫矩阵式键盘。用I/O线组成行、列结构,按键设置在行与列的交点上,这样可以节约I/O口线。4×4矩阵式键盘的示意图如图8所示:
图8 4×4矩阵式键盘的示意图
检测键盘上有无键按下可采用查询工作方式。
首先由P1口的高四位输出0电平,从P1口的低四位读取键盘的状态;再从P1口的低四位输出0电平,从P1口的高四位读取键盘状态。将两次读取的结果组合起来就可以得到一组特征编码[9],如表2所示:
表2 4×4矩阵式键盘键码表
按键名称 | K0 | K1 | K2 | K3 | K4 | K5 | K6 | K7 | K8 |
特征键码 | 77H | 7BH | 0BBH | 0DBH | 7DH | 0BDH | 0DDH | 7EH | 0BEH |
按键名称 | K9 | KA | KB | KC | KD | KE | KF | 未按 | |
特征键码 | 0DEH | 0B7H | 0D7H | 0EEH | OEDH | 0EBH | 0E7H | 0FFH |
显示电路为六位共阴极LED动态显示接口电路。
单个共阴极7段数码的段选码如表3所示:
表3 7段共阴数码管段选码表
显示字符 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
共阴极段选码 | 3FH | 06H | 5BH | 4FH | 66H | 6DH | 7DH | 07H | 7FH | 6FH |
图9 共阴极数码管管脚配置及动态显示接口电路
2.4报警电路
考虑到实验室现有的元器件,设计中采用了蜂鸣器报警电路,如果有条件还可以采用更高级的语音报警电路,那样更加直观方便。电路的接法如图10所示[10]:
图10 蜂鸣器报警电路
工作工程:蜂鸣器经过74LS04接在P3.7口,当P3.7输出为低电平“0”时,74LS04端输出为“1”,晶体管导通,蜂鸣器两端获得约+5V的电压而鸣叫;当P3.7输出为高电平“1”时,三极管截止,蜂鸣器停止鸣叫。
电路中74LS04不仅起到了反向作用,还有增大负载能力的作用。
3.系统软件的设计
众多软件的联合使用对应用系统的设计起到了很重要的作用,在实物制作之前对设计进行仿真,可以检验程序的执行结果是否与设计的功能相同,这样可以对程序进行改进。在这里用到了Keil C和Proteus。
3.1编译软件——Keil C
(1)Keil C的使用
Keil C是众多单片机应用开发软件中优秀的软件之一,它集编辑,编译,仿真等于一体,同时支持汇编和C语言的程序设计,本设计使用它作为C编译器,使用方法如下:
首先建立一个工程,然后将C程序文件添加到工程下链接编译,接着设置生成并输出HEX文件,如果程序编译后有错误就进行调试[11]。
(2)程序设计
完整的程序参见附录。
主流程
主流程图如图11所示:
图11 主流程图 图12 按键扫描流程
按键扫描流程
每一个按键都对应一个处理子程序,通过对按键扫描进行按键识别。按键识别的方法包含了行扫描法和反转法。按键扫描流程图如图12所示,包括了对矩阵键盘和调整时间按键的扫描。
中断流程图
设计采用了外部中断,中断程序流程图如图13所示:
图13 中断流程图
3.2仿真软件——Proteus
Proteus是一款常用的仿真软件,和Keil联合使用,对设计的完善起到很大的作用,也对硬件的搭建提供了连线依据。
Proteus的使用相对比较简单,在元件库中找到相应电路所要用到的元件后放置在原理图纸上,然后用导线连接起来就可以了。
在选用元件后,可以在原理图纸上双击某元件,更改它的属性,如电阻的名称、阻值等。本设计中使用了单片机,需要加载程序文件。之前已经使用Keil C生成了所需要的HEX文件,直接加载进来就可以了。
这时就可以运行仿真了。在仿真之前最好再检查一下电路的连接,确认正确之后再运行,以免粗心造成运行结果与设计的不相符合。
设计的仿真原理图如图14所示:
图14 电路仿真原理图
4.调试及故障分析
4.1程序调试
程序调试:分步骤进行调试,对每一个子程序进行编译链接后,将整个程序全部编译,生成HEX文件加载到单片机上,进行仿真。出现错误和警告时要进行分析,解决问题。
仿真分析:启动(上电)后,显示00—00。
当主持人按键,铃响,显示30秒的抢答时间,如有选手抢答,铃响,会显示选手号码以及60秒的回答时间,回答时间剩余5秒时,会响提示音。
如果第一位选手不能回答,那么主持人再次按下START键允许其他选手继续抢答,允许其他选手抢答的时间为上一次抢答的剩余时间,答题时间仍是60秒。
如果没有人抢答,抢答倒计时还有5秒的时候会响提示音,抢答时间过后抢答器会自动进入复位状态,可以进行下一轮的抢答。
如果主持人未按START键,有选手按了抢答按键,犯规抢答,显示犯规选手号并闪烁FF,直到主持人复位。
这与预期的效果是一致的。
5.总结
与普通抢答器相比,本设计有以下几方面优势:
(1)具有清零装置和抢答控制,可由主持人操纵避免有人提前抢答违反规则。(2)具有定时功能,在规定时间内无人抢答表示所有参赛选手或参赛队对本题弃权。
在以往的传统学习模式下,我们可能会记住很多书本知识,但是通过毕业设计,我们学会了如何将学到的知识化为自己的东西,学会了怎么跟好的处理只是和实践相结合的问题,把握重点,攻克难关,学到用到活学活用。在设计过程中由于时间仓促有很多地方难免存在不足之处,硬件设计已经完成,在软件设计中有些功能还尚未能开发出来。但在以后的工作中,我们会严格要求自己最求完美。
整个设计通过软件和硬件上的调试,仿真。我想这些对于自己以后的学习和工作都会有很大的帮助。在这次设计中遇到很多实际性的问题,在实际设计中才发现,书本上的理论性的东西与实际运用中的还是有一定的出入的,所以有些问题不但要深入的理解,而且要不断的更正以前的错误思维。对于单片机设计,硬件电路设计时比较简单的,主要是解决程序设计中的问题。而程序设计是一个很灵活的东西,他反应了你解决问题的逻辑思维和创新能力。它才是一个设计的灵魂所在。因此在整个设计过程中大部分时间是用在程序上面的。很多子程序是可以借签书本上的,但怎样衔接各个子程序才是关键的问题所在,这需要对单片机的结构很熟悉。因此可以说单片机的设计师软件和硬件的结合,二者是密不可分的。
但是,通过这次设计我也发现自己的很多不足之处。在设计过程中我发现自己考虑问题很不全面,自己的专业知识掌握的很不牢靠,所掌握的计算机软件还不够,我希望自己的这些不足之处能在今后的工作和靴子中得到改善。而且,通过这次设计,我懂得了学习的重要性,学会了坚持和努力,这将为以后的学习做出了最好的榜样!
参考文献
[1] 程相波, 卫安军. 基于MCS—51单片机的八路抢答器设计方法研究[J]. 北京工业职业技术学院学报, 2007, (02): 31-34.
[2] 宋春华, 刘江涛, 王贵恩, 裴小英. 基于单片机控制的数字抢答器[J]. 河南机电高等专科学校学报, 2005, (05): 28-29.
[3] 张毅刚, 彭喜元, 姜守达, 乔立岩. 新编MCS-51单片机应用设计[M]. 哈尔滨: 哈尔滨工业大学出版社, 2003: 223-231.
[4] 何立民. 单片机高级教程-应用与设计[M]. 北京: 北京航空航天大学出版社, 2000. 8: 103-109.
[5] 李建忠. 单片机原理与应用[M]. 西安: 西安电子科技大学出版社, 2002,2: 121-123.
[6] 王幸之, 钟爱琴, 王雷, 王闪. AT系列单片机原理与接口技术[M]. 北京: 北京航空航天大学出版社, 2004: 62-67.
[7] 张洪润, 易涛. 单片机应用技术教程[M]. 北京: 清华大学出版社, 2003,10: 119-122.
[8] 蔡朝洋. 单片机控制实习与专题制作[M]. 北京: 北京航空航天大学出版社, 2006,11: 317-323.
[9] 戴佳, 苗龙, 陈斌. 51单片机应用系统开发典型实例[M], 北京: 中国电力出版社, 2005,7: 121-137.
[10] 杨欣, 王玉凤, 刘湘黔. 电路设计与仿真-基于Multisim 8与 Protel 2004[M]. 北京: 清华大学出版社, 2006: 32-106.
[11] 王振宇, 李惠敏. 实验电子技术[M]. 天津: 天津大学出版社, 1998: 63-83.
附录一
#include unsigned char key; unsigned char key1; unsigned char sec; unsigned char sec2; unsigned char flag; unsigned char flag1=0; unsigned char flag2=0; unsigned char flag3=0; unsigned char i; sbit LOUDER=P3^7; sbit RED=P3^4; sbit PAUSE=P3^5; sbit RESTART=P3^6; sbit ADD=P3^0; sbit SUB=P3^1; unsigned char led[17]={0x3F,0x06,0x5B,0x4F,0x66,0x6D, 0x7D,0x07, 0x7F,0x6F,0X71}; //***************delay()延时函数***********/ void delay(int t) { unsigned char i,j; for(i=0;i } void delay1() { unsigned char i,j; for(i=0;i<8;i++) for(j=0;j<100;j++); } /********中断的初始化***************/ void init() { IT0=1; //外部中断T0,边沿触发 EX0=1; IT1=1; //外部中断T1,边沿触发 EX1=1; TMOD=0X11; //定时器T0 T1 均为模式一 PT1=1; //设定定时器T1、外部中断T0的中断优先级// PX0=1; EA=1; //CPU允许中断 } /************外部中断T0,用于复位*****************/ void Exit_int0() interrupt 0 { EA=0; sec=0; key=0; flag=0; flag1=0; flag2=0; flag3=0; RED=1; PAUSE=1; RESTART=1; TR0=0; ET0=0; TR1=0; ET1=0; IT1=1; //允许外部中断T1 EX1=1; EA=1; } /**************外部中断T1服务程序*********************/ void Exit_int2() interrupt 2 { flag3++; //flag3初始值为0,外部中断T1每中断一次flag3值加一 EX1=0; // 关掉外部中断T1 if(flag3==1) //第一次按下START键,启动定时器T0计时30秒,红灯亮 { RED=0; flag1=1; //flag1置一 TL0=0XB0; //启动定时器T0三十秒倒计时 TH0=0X3C; sec=30; ET0=1; //开启T0中断 TR0=1; //允许T0计数 } else if(flag3==2) //第二次按下START键,黄灯亮,红灯灭 { flag=0; flag1=0; flag2=0; RED=1; PAUSE=0; TR1=0; sec=sec2; key=0; } else if(flag3==3) //第三次按下START键,启动计时,并允许再次抢答,蓝灯亮,黄灯灭 { TR0=1; flag2=0; PAUSE=1; RESTART=0; flag=0; //为抢答前有选手违规 为提示声设定标志位 flag1=1; key=0; } else if(flag3==4) { flag=1; flag1=0; flag2=0; RESTART=1; RED=1; PAUSE=0; TR1=0; sec=sec2; key=0; } else if(flag3>4) { TR0=1; key=0; flag2=0; flag=0; PAUSE=1; RESTART=0; TR1=1; flag=0; flag1=1; } EX1=1; LOUDER=0; delay(250); LOUDER=1; } /*****************定时器T0,计时30秒***************/ void Timer1() interrupt 1 { static unsigned char count; TL0=0XB0; TH0=0X3C; count++; if(count==35) { count=0; sec--; if(sec==5) { LOUDER=0; delay(250); LOUDER=1; } if(sec==0) { sec=0; ET0=0; TR0=0; } } } /*****************定时器T1,计时60秒***************/ void Timer3() interrupt 3 { static unsigned char count; TL1=0XB0; TH1=0X3C; count++; if(count==35) { count=0; sec--; if(sec==5) { LOUDER=0; delay(250); LOUDER=1; } if(sec==0) { sec=0; ET1=0; TR1=0; key=0; } } } /*****************功能:键盘扫描************/ key_scan() { unsigned char k=0,p1_h=0,p1_l=0; P1=0XF0; k=P1; flag=0; if(k!=0XF0) { delay(60); k=P1; //读入行键值 flag=1; if(k!=0XF0) { p1_h=P1; //行键值给高位 P1=0X0f; //翻转后读入列的值给P1(读键值时按键还未释放) p1_l=P1; //列键值给低位 k=p1_h | p1_l; //高低位相或确定具体按键值 flag2++; //第二个人抢答无效,即锁存第一个人的号 if(flag2==1) sec2=sec; if(flag2>=2) k=0; switch(k) { case 0 : return(0) ;break; case 238: return(key=1,sec=60);break; case 237: return(key=2,sec=60);break; case 235: return(key=3,sec=60);break; case 231: return(key=4,sec=60);break; case 222: return(key=5,sec=60);break; case 221: return(key=6,sec=60);break; case 219: return(key=7,sec=60);break; case 215: return(key=8,sec=60);break; case 190: return(key=9,sec=60);break; case 1: return(key=10,sec=60);break; case 187: return(key=11,sec=60);break; case 183: return(key=12,sec=60);break; case 126: return(key=13,sec=60);break; case 125: return(key=14,sec=60);break; case 123: return(key=15,sec=60);break; case 119: return(key=16,sec=60);break; default: return(0) ;break; } } else return(0); } else return(0); } /************main() 函数***************/ void main() { init(); while(1) { key_scan(); if((flag3==2)|(flag3==4)) delay(250); if((flag3==2)|(flag3==4)) { if(ADD==0) sec++; if(SUB==0) sec--; } i=35; for(i=35;i>0;i--) { if((flag!=0)&&(flag1==1)) //在外部中断T1触发后flag1=1,flag4的初值为0,开始抢答,并且有人抢答,启动定时器T1倒计时60S// { LOUDER=0; delay(250); LOUDER=1; ET1=0; TR0=0; TL1=0XB0; TH1=0X3C; ET1=1; TR1=1; } if(flag==0) //没有选手按下按键时,此模块是在没有按键按下时flag=0;只用于显示倒计时的时间,包括30秒 和60秒两个倒计时// { P2=0xfe; P0=led[key%10]; delay1(); P2=0xff; P2=0xfd; P0=led[key/10]; delay1(); P2=0xff; P0=led[sec%10]; P2=0xbf; delay(8); P2=0xff; P0=led[sec/10]; P2=0x7f; delay(8); P2=0xff; } else if((flag!=0)&(flag1==0)) //外部中断T1 没触发一次则flag1=0;但是在又有按键按下即是有选手违规抢答时,此模块用作显示违规者的号码,同时有提示声音// { sec=sec2; P2=0xfe; P0=led[key%10]; delay1(); P2=0xff; P2=0xfd; P0=led[key/10]; delay1(); P2=0xff; P2=0xfB; P0=led[10]; delay1(); P2=0xff; P2=0xf7; P0=led[10]; delay1(); P2=0xff; LOUDER=0; delay(250); LOUDER=1; flag=0; flag1=0; } } } }