数字抢答器课程设计-毕业设计.doc
单片机技术课程设计说明书 数字抢答器 系 、 部: 电气与信息工程系 学生姓名: 黄 伟 指导教师: 王韧 职称 副教授 专 业: 电气工程及其自动化 班 级: 电气本0901班 完成时间: 2012年1月4日 摘 要智能抢答器作为一种简单通用的电子产品,现在已经广泛应用于各种智力和知识竞赛中。随着电子技术的发展,现在的抢答器功能也越来越强,可靠性和准确性也越来越高。一般能够实现抢答器功能的方案有多种。本设计采用AT89S52单片机系统以及外部设备,比如数码管显示器、独立式键盘等外部输入输出设备。分别采用了C51语言和A51语言来编写程序。晶振为12MHz。事先已经将电路实物图制作完毕。程序设计是在keil4的环境下编写的,通过JTAG接口将程序生成的16进制文件下载到单片机里面,就制作成了一个简单抢答器。关键词 :抢答器;单片机;数码管;C51语言;A51语言 ABSTRACT Intelligence is as a simple vies to answer first general electronic products, now has been widely applied in all kinds of intelligence and knowledge race. With the development of electronic technology, the function also is now vies to answer first is more and more strong, reliability and accuracy more and more is also high. General can realize the function of the plan has vies to answer first of many kinds.This design USES the AT89S52 SCM system and external devices, such as digital tube display, independent type keyboard external input and output devices. C51 are used for the language and language to write a program for a251 / A51. Crystals for 12 MHz. Beforehand will circuit physical figure the finished. The program design is in keil4 under the environment of the preparation, and through the JTAG interface will program generated hexadecimal download to single chip in, make became a simple vies to answer first device. Keywords: vies to answer first device; Single chip microcomputer; Digital tube; C51 language; A51 language目 录1.功能概述11.1课题任务与功能要求11.2方案概述12课题硬件系统设计32.1各模块电路简介32.1.1单片机最小系统32.1.2独立式键盘电路32.1.3流水灯电路42.1.4蜂鸣器电路52.1.5数码管电路52.1.6下载口电路62.1.7硬件测试63课题软件系统设计73.1单片机资源使用情况73.2主程序系统框图73.3软件各模块简要介绍73.3.1显示函数73.3.2键处理和键扫描函数83.3.3延时1ms函数93.3.4延时1s函数以及中断服务函数93.3.5主函数94设计结论114.1使用说明114.2心得体会11结束语12致 谢13参考文献14附录A:数码管系统原理图15附录B:数码管系统PCB图16附录C:数码管系统元器件布局图17附录D:数码管系统元器件清单18附录E:数码管系统实物图19附录F:C语言程序清单20附录G:汇编程序清单351. 功能概述1.1 课题任务与功能要求设计一个具有特定功能的抢答器。该抢答器上电或按键复位后能自动显示系统提示符“P.”, 进入准备工作状态。主持人按下开始按钮后,抢答开始并限定时间30S;10S内无人抢答,蜂鸣器发出音响;主持人按下开始按钮之前有人按下抢答器,抢答违规,显示器显示违规台号,违规指示灯亮,其它按钮不起作用;正常抢答,显示器显示台号,蜂鸣器发出音响,其它抢答按钮无效;正常抢答下,从按下抢答按钮开始30S内,答完按钮没按下,则作超时处理,超时处理时,违规指示灯亮,数码管显示违规台号。蜂鸣器发出音响;各台数字显示的消除,蜂鸣器音响及违规指示灯的关断,都要通过主持人按复位按钮。1.2 方案概述本设计采用AT89S52单片机以及其外部设备组成硬件电路,其中包括单片机、数码管驱动电路、数码管显示器、LED流水灯、独立式键盘和蜂鸣电路。蜂鸣电路接在P3.1口上低电平有效;数码管采用共阳数码管,P0口接段控引脚(低电平有效),P2口接位控引脚(低电平有效);8个LED指示灯接P3口(低电平有效);键盘接P1口。除此之外还有晶振电路,复位电路,电源电路和下载口电路。 程序设计采用C51和A51两种语言编写。本设计最多可以有4个人同时抢答,其中S1为系统复位键,S2为开始键,S3为停止键,S4到S7为抢答键,S8为自定义复位键。方案设计框图如图1所示:图 1 系统设计框图2 课题硬件系统设计2.1 各模块电路简介2.1.1 单片机最小系统单片机最小系统包括电源电路、时钟电路、复位电路。只有当单片机有了这些电路才会工作。电源电路给单片机供电,时钟电路给单片机提供时钟脉冲,复位电路可以实现单片机的复位。见下图2.1.1图2.1.1:单片机最小系统2.1.2 独立式键盘电路按键电路的设计就是在一段公共接地,另一端通过上拉电阻接到P1口,当有按键按下,相应的口就会变成低电平,产生一个下降沿。见下图2.1.2图2.1.2:独立式键盘电路2.1.3 流水灯电路流水灯电路直接挂接在单片机的P3口上,采用共阳接法。见下图2.1.3图2.1.3:流水灯电路2.1.4 蜂鸣器电路蜂鸣器通过三极管接单片机P3.1口。见下图2.1.4 图2.1.4蜂鸣器电路2.1.5 数码管电路数码管的段控口接在单片机的P0上,而位控口通过三极管接在单片机的P2口上。见下图2.1.5图2.1.5:数码管显示电路2.1.6 下载口电路 下载口的1脚接P1.5口,2脚悬空,3脚接单片机的复位口,4脚接P1.6口,脚接P1.7口,6脚接地,7、8、8、10脚接地。见下图2.1.6图2.1.6:下载口电路2.1.7 硬件测试板子做好后通过老师给的测试程序测得各模块的功能均正常。单片机最小系统正常工作,数码管能够正常显示,按键正常工作,流水灯电路正常点亮。3 课题软件系统设计3.1 单片机资源使用情况编写程序时,用到了单片机的定时/计数器1,并且让它都以中断方式工作。P0、P1、P2、P3、口均已用到。没有用到P3口的第二功能。3.2 主程序系统框图 图二:主程序流程框图3.3 软件各模块简要介绍3.3.1 显示函数显示函数主要完成数码管的动态显示,将相应的段控码送往P0口,相应的位控码送往P2口。实现显示需要的字符信息。图三:显示函数流程框图3.3.2 键处理和键扫描函数键处理函数主要是将从P1口取值送往单片机进行取反处理。键扫描函数主要是判断是否真的有键按下,即度过前沿抖动之后再判断是否有键按下,如果确实有键按下再判断是否释放,同样也要度过后沿抖动。最终将处理完的键值作为返回值返回。 图四:键盘扫描函数KEY流程框图 图五:数据处理函数keychuli流程框图3.3.3 延时1ms函数此函数要再显示函数中用到,由于时间比较短,就采用纯软件的方法延时。3.3.4 延时1s函数以及中断服务函数延时1s函数是作为一个子函数,当这个函数执行完后就度过了1s。在延时1s函数中开启定时器,定时器定时50ms,只需其定时20次即可。中断函数重装初值。在延时函数中时刻调用键扫描函数,当相应键按下后转到相应的键功能服务程序。图六:1S延时函数流程框图3.3.5 主函数主函数是程序的入口,在主函数中一直调用显示函数和键扫描函数,当没有键按下时一直保证显示P点,当有键按下后,如果是开始键就开始倒计时,如果是选手按下,则违规抢答。图七:主函数流程图框4 设计结论4.1 使用说明本设计的S1为系统复位键,S2为开始键,S3为停止键,S4到S7为抢答键,S8为自定义复位键。当开始键按下后才能进行抢答,抢答时间为30秒,抢答时,对应抢答台号指示灯亮,其他按键无效,答完后,答题人按下答完键,答题结束,若答题时间超过10S蜂鸣器自动鸣叫提醒,鸣叫时间为1S,若倒计时时间到,还没按下答完键则违规,违规指示灯亮,蜂鸣器报警。若没有按下开始就抢答则违规,违规指示灯亮,蜂鸣器报警,显示违规者台号。无论是正常抢答结束还是抢答违规报警只有按复位键才能重新开始。4.2 心得体会通过本次课程设计,我更深一步地掌握了单片机的接口技术以及其汇编语言和C语言的程序设计。在编写程序时,经常也碰到很多难题,程序的跳转等等。尤其是编写汇编程序的时候,程序的循环,多层循环,还有就是转移语句的跳转范围,这次编程的时候就遇到几次这样的情况,于是我就在跳转语句附近写一段跳转区程序,先让其跳到跳转区,然后通过无条件长转移指令跳到要去的程序段。结束语将本设计的程序下载到单片机中,通过测试,基本上完成了任务书的要求,并且抢答的精确度也比较高,因为在调用键扫描函数的时候是在1s函数中,每50ms就会调用一次键扫描函数。当然对于高精度的抢答比赛,本设计的精度还是不够的,还需要进一步的改进,甚至可以精度提高到微秒级。此外抢答设计抢答人数为四人,所以当有更多的人抢答时,应该把独立式键盘改接成行列式键盘。致 谢本课题在选题及进行过程中得到了王韧老师悉心的指导以及同学的热心帮助。在这里特意感谢在课程设计中帮助过我的老师和同学。在2011年暑假的培训时由于王老师的悉心指导才让我在完成本次课程感觉不那么困难。王老师尽职尽责、踏实坚韧的工作精神,将使我终生受益。再多华丽的言语也显苍白。在此谨向王老师致以诚挚的谢意和崇高的敬意。 参考文献1 李广弟.单片机技术基础M.第三版.北京:北京航空航天大学出版社,20072 马忠梅.单片机的C语言应用程序设计M.第四版.北京航空航天大学出版社,20073李光飞.单片机课程设计实例指导M.北京:北京航空航天大学出版社,2004附录A:数码管系统原理图附录B:数码管系统PCB图图B1:PCB顶层图图B2:PCB底层图附录C:数码管系统元器件布局图附录D:数码管系统元器件清单Part TypeDesignatorFootprintPart TypeDesignatorFootprint1KRX2AXIAL0.4LEDD2SIP-21KR12AXIAL0.4LEDD3SIP-21KR13AXIAL0.4LEDD7SIP-24.7KRKAXIAL0.4LEDD9SIP-210KJ2SIP9LEDD8SIP-210KJ5SIP9LEDD5SIP-212MHzY1JZLEDD6SIP-222uFC3SIP2LEDD4SIP-233pFC2SIP2PNPQ0TO92A33pFC1SIP2PNPQ3TO92A200RX1AXIAL0.4PNPQ2TO92A470RP0AXIAL0.4PNPQ1TO92A470R20AXIAL0.4PNPQ7TO92A470R00AXIAL0.4PNPQ8TO92AAT89S52U1DIP40PNPQ6TO92ABELLLS1AXIAL-0.3PNPQ4TO92ACON2J1SIP2PNPQ5TO92ACON2JX1SIP2RES2RP5AXIAL0.4CON2JX2SIP2RES2RP6AXIAL0.4CON2JP5SIP2RES2RP7AXIAL0.4CON8JP3SIP8RES2RP4AXIAL0.4CON8JP1SIP8RES2RP1AXIAL0.4CON8JP4SIP8RES2RP2AXIAL0.4CON8JP2SIP8RES2RP3AXIAL0.4USBJ3USBCK附录E:数码管系统实物图图E1:抢答器启动图E2:抢答器正常抢答附录F:C语言程序清单/* 项目名称:四位数字抢答器* 设 计 者:黄伟 * 时 间:2011年12月31日 * 项目功能:该抢答器上电或按键复位后能自动显示系统提示符"P.", 进入准备工作状态。主持人按下开始按钮后,抢答开始并 限定时间30S;10S内无人抢答,蜂鸣器发出音响;主持人 按下开始按钮之前有人按下抢答器,抢答违规,显示器显 示违规台号,违规指示灯亮,其它按钮不起作用;正常抢 答,显示器显示台号,蜂鸣器发出音响,其它抢答按钮无 效;正常抢答下,从按下抢答按钮开始30S内,答完按钮没 按下,则作超时处理,超时处理时,违规指示灯亮,数码 管显示违规台号,蜂鸣器发出音响;各台数字显示的消除, 蜂鸣器音响及违规指示灯的关断,都要通过主持人按复位 按钮*/#include"reg52.h"#include<intrins.h>#define uchar unsigned char#define uint unsigned int/S2=P1.0 开始键 /S3=P1.1 停止键 /S4=P1.2 一号台抢答键/s5=p1.3 二号台抢答键/s6=p1.4 三号台抢答键/S7=P1.5 四号台抢答键/S8=P1.6 复位键 /char z,n,m,i,S;bit b,c,d,e,f,g,x,y,l,h;/* 共阳数码管字型码* 0,1,2,3,4,5,6,7,8,9,p.,p,灭*/char code dis_code=0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x0c,0xbf,0xff;/* 位控码 */char code wei_code=0xf7,0xfb,0xfd,0xfe,0x7f,0xbf,0xdf,0xef;/* 数字显示代码序号*/ char data find_code8=10,12,12,12,12,12,12,12;/* 延时1ms函数*/void DelayX1ms(uint count) uint j; while(count-!=0) for(j=0;j<80;j+); /* 显示函数*/void disp() uint k,i; for(i=0;i<8;i+) P2=wei_codei; k=find_codei; P0=dis_codek; DelayX1ms(1); P2=0xff; /* 函数原型:keychuli();* 功 能:处理与键盘相连的P1口的内容,作为键值。*/uchar keychuli() uchar k; k=P1; /P1口内容送K k=k; /取反 return(k); /返回键值 /* 函数原型:key();* 功 能:键盘扫描函数,函数返回值即键值。*/uchar key() uchar keyzhi,keyzhii; /电子钟键盘按键键值临时存放/ keyzhi=keychuli(); /调P1口处理函数/ if(keyzhi!=0) /有键动作延时去抖动,否则函数返回/ disp(); disp(); keyzhi=keychuli(); /再次调P1口处理函数/ if(keyzhi!=0) /真正有键按下,取键值并暂存/ keyzhii=keyzhi;while(keyzhi!=0)/判按键是否释放,没有释放延时去抖动等待释放 / disp(); disp(); keyzhi=keychuli(); keyzhi=keyzhii; /按键释放后恢复按键键值 / return(keyzhi); /返回按键键值/ /* P.显示函数*/void disp1() find_code0=10;find_code1=12;find_code2=12;find_code3=12;find_code4=12;find_code5=12;find_code6=12;find_code7=12;disp(); /* 灭的显示函数 */void disp2() find_code0=12;find_code1=12;find_code2=12;find_code3=12;find_code4=12;find_code5=12;find_code6=12;find_code7=12;disp(); /* 定时器1中断服务函数*/void t1(void) interrupt 3 using 3 S+; TH1=(65536-50000)/256; / 装载计数器初值 / TL1=(65536-50000)%256; /* 定时器1定时1s函数*/void DlayX1s() S=0; TH1=(65536-50000)/256; / 装载计数器初值 / TL1=(65536-50000)%256; TR1=1; / 启动 T/C1 / do disp(); z=key(); switch(z) case 0x02: b=1;goto A;break; case 0x04: if(l=0&&y=0&&h=0) c=1;goto A;break; case 0x08: if(x=0&&l=0&&h=0) d=1;goto A;break; case 0x10: if(x=0&&y=0&&h=0) e=1;goto A;break; case 0x20: if(x=0&&y=0&&l=0) f=1;goto A;break; case 0x40: g=1;goto A;break; while(S<20); / 查询等待TF0置位 / A: TR1=0;/* 主函数*/ void main() while(1) ST:EA=1; ET1=1; TMOD=0x10; P3=0xFF; disp1();P1=0xFF;z=key();switch(z) case 0x01: /抢答开始键/ P3=0xFE;disp2(); for(n=30;n>=0;n-) find_code6=n/10; find_code7=n%10; DlayX1s(); if(b=1) /停止键按下/ b=0; P3=0xFD; disp2(); while(1) z=key(); if(z=0X40) goto ST; if(c=1) /一号台正常抢答/ c=0; x=1; P3=0xEF; find_code3=1; for(n=30;n>=0;n-) find_code6=n/10; find_code7=n%10; DlayX1s(); if(b=1) b=0; P3=0xFD; x=0; while(1) z=key(); if(z=0x40) goto ST; if(g=1) g=0; x=0; goto ST; if(c=1) /一号台抢答结束/ c=0; disp2(); find_code3=1; P3=0xF9; DlayX1s(); x=0; while(1) disp(); P3=0xFB; z=key(); if(z=0x40) goto ST; disp2(); find_code3=1; /一号台抢答超时/ P3=0xFD; x=0; while(1) disp(); z=key(); if(z=0x40) goto ST; if(d=1) /二号台正常抢答/ d=0; y=1; P3=0xDF; find_code3=2; for(n=30;n>=0;n-) find_code6=n/10; find_code7=n%10; disp(); DlayX1s(); if(b=1) b=0; P3=0xFD; y=0; while(1) z=key(); if(z=0x40) goto ST; if(g=1) g=0; y=0; goto ST; if(d=1) /二号台抢答结束/ d=0; disp2(); find_code3=2; P3=0xF9; DlayX1s(); y=0; while(1) disp(); P3=0xFB; z=key(); if(z=0x40) goto ST; disp2();/二号台抢答超时/ find_code3=2; P3=0xFD; y=0; while(1) disp(); z=key(); if(