找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 8316|回复: 1
打印 上一主题 下一主题
收起左侧

基于单片机的简易8路抢答器设计说明书(word格式可编辑文档下载)

[复制链接]
跳转到指定楼层
楼主
摘  要
ATMEl公司的8位单片机有AT89、AT90两个系列,AT89系列是8位Flash单片机,与8051系列单片机相兼容,静态时钟模式;AT90系列单片机是增强RISC结构、全静态工作方式、内载在线可编程Flash的单片机,也叫AVR单片机.
单片机具有体积小、功耗低、控制功能强、扩展灵活、微型化和使用方便等优点,采用单片机控制使得仪器仪表数字化、智能化、微型化,且功能比起采用电子或数字电路更加强大。而我正是看中单片机的这种优势,因此设计了一个由AT89C51单片机控制的八路抢答器,它具有抢答、数据显示、报警、计时的功能,系统由单片机AT89C51、数码管、蜂鸣器报警模块、按键模块所组成,能做到抢答公平、公正又准确。

目录
1. 绪论
1.1抢答器的概述
1.2设计要求及目的
2.硬件电路设计
2.1总体电路原理图
2.2 时钟振荡电路的设计
2.3复位电路的设计
2.4数码管显示电路的设计
2.5按键电路的设计
2.6蜂鸣器电路设计
2.7系统复位
3.系统软件设计
3.1系统组成方框图
3.2程序流程图
4.焊接调试过程与问题分析。
4.1 焊接
4.1.1检测各元件
4.1.2对PCB板进行排版及连线
4.1.3 焊接的问题及解决
4.1.4焊接的技巧和注意事项
4.2调试
4.2.1系统的调试
4.2.2具体调试
参考文献
致谢
附件1:基于单片机的简易抢答器系统设计实物图
附件2:基于单片机的简易抢答器系统单面PCB板图
附件3:基于单片机的简易抢答器系统设计程序
1. 绪论
1.1抢答器的概述
抢答器作为一种小型的早期电子产品,在现在的知识竞赛、文体娱乐活动(抢答赛活动)中应用十分广泛,能准确、公正、直观地判断出抢答者的座位号。传统抢答器只是大概判断出抢答成功或犯规选手台号,无法显示出每个选手的抢答时间。而今抢答器可以通过数据来说明裁决结果的准确性、公平性。使比赛大大增加了娱乐性的同时,也更加公平、公正。

1.2设计要求及目的
(1)设计一个可供8人进行的抢答器。
(2)系统设置复位按钮,按动后,重新开始抢答。
(3)抢答器开始时数码管显示序号0,选手抢答实行优先显示,优先抢答选手的编号一直保持到主持人将系统清除为止。抢答后显示优先抢答者序号,同时发出音响。,并且不出现其他抢答者的序号。
(4)抢答器具有定时抢答功能,且一次抢答的时间有主持人设定,本抢答器的时间设定为30秒,当主持人启动“开始”开关后,定时器开始减计时,同时蜂鸣器有短暂的声响。
(5)设定的抢答时间内,选手可以抢答,这时定时器停止工作,显示器上显示选手的号码和抢答时间。并保持到主持人按复位键。
(6)当设定的时间到,而无人抢答时,本次抢答无效,扬声器报警发出声音,并禁止抢答。定时器上显示00。

2.硬件电路设计
系统硬件设计
为使硬件电路设计尽可能合理,应注意以下几方面:
(1) 尽可能采用功能强的芯片,以简化电路,功能强的芯片可以代替若干普通芯片,随着生产工艺的提高,新型芯片的的价格不断下降,并不一定比若干普通芯片价格的总和高。
(2) 留有设计余地。在设计硬件电路时,要考虑到将来修改扩展的方便。因为很少有一锤定音的电路设计,如果现在不留余地,将来可能要为一点小小的修改或扩展而被迫进行全面返工。
(3) 程序空间,选用片内程序空间足够大的单片机,本设计采用AT89C51单片机。
(4)  I/O端口,在样机研制出来后进行现场试用时,往往会发现一些被忽视的问题,而这些问题不是靠单纯的软件措施来解决的。如有些新的信号需要采集,就必须增加输入检测端;有些物理量需要控制,就必须增加输出端。如果在硬件电路设计就预留出一些I/O端口,虽然当时空着没用,那么用的时候就派上用场了。
2.1总体电路原理图
                          图1 总电路图
2.2 时钟振荡电路的设计
单片机必须在时钟的驱动下才能工作.在单片机内部有一个时钟振荡电路,只需要外接一个振荡源就能产生一定的时钟信号送到单片机内部的各个单元,决定单片机的工作速度。
图2  时钟振荡电路图
一般选用石英晶体振荡器。此电路在加电大约延迟10ms后振荡器起振,在XTAL2引脚产生幅度为3V左右的正弦波时钟信号,其振荡频率主要由石英晶振的频率确定。电路中两个电容 C2,C3的作用有两个:一是帮助振荡器起振;二是对振荡器的频率进行微调。C2,C3的典型值为30PF。
单片机在工作时,由内部振荡器产生或由外直接输入的送至内部控制逻辑单元的时钟信号的周期称为时钟周期。其大小是时钟信号频率的倒数,常用fosc表示。如时钟频率为12MHz,即fosc=12MHz,则时钟周期为1/12µs。
2.3复位电路的设计
单片机的第9脚RST为硬件复位端,只要将该端持续4个机器周期的高电平即可实现复位,复位后单片机的各状态都恢复到初始化状态,其电路图如图所示:
图3 复位电路图
值得注意的是,在设计当中使用到了硬件复位和软件复位两种功能,由上面的硬件复位后的各状态可知寄存器及存储器的值都恢复到了初始值,而前面的功能介绍中提到了倒计时时间的记忆功能,该功能的实现的前提条件就是不能对单片机进行硬件复位,所以设定了软复位功能。软复位实际上就是当程序执行完毕之后,将程序指针通过一条跳转指令让它跳转到程序执行的起始地址。
2.4数码管显示电路的设计
显示功能与硬件关系极大,当硬件固定后,如何在不引起操作者误解的前提下提供尽可能丰富的信息,全靠软件来解决。
     
                     图4 数码管显示电路图
2.5按键电路的设计
键盘是人与微机系统打交道的主要设备。关于键盘硬件电路的设计方法也可以在文献和书籍中找到,配合各种不同的硬件电路,这些书籍中一般也提供了相应的键盘扫描程序。站在系统监控软件设计的立场上来看,仅仅完成键盘扫描,读取当前时刻的键盘状态是不够的,还有不少问题需要妥善解决,否则,人们在操作键盘就容易引起误操作和操作失控现象。在单片机应用中键盘用得最多的形式是独立键盘及矩阵键盘。
图5 按键图
 在键盘中按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式。在矩阵式键盘中,每条水平线和垂直线在交叉处不直接连通,而是通过一个按键加以连接。这样,一个端口(如P1口)就可以构成1乘8的8个按键,比之直接将端口线用于键盘多出了一倍,而且线数越多,区别越明显,比如再多加一条线就可以构成20键的键盘,而直接用端口线则只能多出一键(9键)。由此可见,在需要的键数比较多时,采用矩阵法来做键盘是合理的。
2.6蜂鸣器电路设计
我们知道,声音的频谱范围约在几十到几千赫兹,若能利用程序来控制单片机某个口线的“高”电平或低电平,则在该口线上就能产生一定频率的矩形波,接上喇叭就能发出一定频率的声音,若再利用延时程序控制“高“”低”电平的持续时间,就能改变输出频率,从而改变音调,使喇叭发出不同的声音。
                             6 蜂鸣器电路图
2.7系统复位
使CPU进入初始状态,从0000H地址开始执行程序的过程叫系统复位。从实现系统复位的方法来看,系统复位可分为硬件复位和软件复位。硬件复位必须通过CPU外部的硬件电路给CPU的RESET端加上足够时间的高电位才能实现。上电复位,人工按钮复位和硬件看门狗复位均为硬件复位。硬件复位后,各专用寄存器的状态均被初始化,且对片内通用寄存器的内容没有影响。但是,硬件复位还能自动清除中断激活标志,使中断系统能够正常工作,这样一个事实却容易为不少编码人员所忽视。软件复位就是用一系列指令来模拟硬件复位功能,最后通过转移指令使程序从0000H地址开始执行。对各专用寄存器的复位操作是容易的,也没有必要完全模拟,可根据实际需要去主程序初始化过程中完成。而对中断激活标志的清除工作常被遗忘,因为它没有明确的位地址可供编程。有的编程人员用020000(LJMP  0000H)作为软件陷阱,认为直接转向0000H地址就完成了软件复位,就是这类错误的典型代表。软件复位是使用软件陷阱和软件看门狗后必须进行的工作,这时程序出错完全有可能发生在中断子程序中,中断激活标志已置位,它将阻止同级中断响应。由于软件看门是高级中断,它将阻止说要中断响应,由此可见清除中断激活标志的重要性。
3.系统软件设计
软件任务分析和硬件电路设计结合进行,哪些功能由硬件完成,哪些任务由软件完成,在硬件电路设计基本定型后,也就基本上决定下来了。
3.1系统组成方框图


图7 系统组成方框图
3.2程序流程图
在本设计中包括了以下八个主要的程序:主程序;非法抢答序;抢答时间调整程序;倒计时程序;正常抢答处理程序;犯规处理程序;显示及发声程序。主流程图如图所示:
     
                   8.1 定时程序流程图
图8.2 抢答程序流程图
                     8.3 按键程序流程图
4.焊接调试过程与问题分析。4.1 焊接
1.检测各元件
2.对PCB板进行排版及              布线
3.焊接
4.1.1检测各元件
用万用表检查、了解元件;
(1)一般电阻
电阻的阻值是可以根据电阻上的色环判断:
四环电阻阻值等于前两位对应的数值乘上第三位对应的倍率,第四位为误差范围;五环电阻阻值等于前三位对应的数值乘上第四位对应的倍率,第五位为误差范围。电阻R0为五环型,色环颜色:棕 黑 黑 棕 棕,阻值=100×10=1000Ω,误差为±1%,实测阻值为992Ω,本实验R1用两个R0的电阻并联成,电阻R2为四环型,色环颜色 :绿 棕 红 金,阻值=51×10² =5100Ω=5.1kΩ,误差为±5%,实测阻值为5.02kΩ;光敏电阻:A.在光照情况下,测量光敏电阻的阻值,即为光敏电阻的亮阻;B.在遮光情况下,测量光敏电阻的阻值,即为光敏电阻的暗阻。
(2)发光二极管
发光二极管有两个接线柱,一个长的一个短的,长端为正极,短端为负极。可以利用万用表测量两种接法时的电阻值,可知道当正极接到长端,负极接到短端的时候,发光二极管的阻值比较小,此即是二极管的单向导通特性。
(3可变电阻
可变电阻有三个引脚,它的接法和滑动变阻器的接法一样,有三端接入式和两端接入式,本实验采用两端接入式比较简单。采用两端接入时,其中一端必须接在中间的那个引脚上,另外一个在剩余的两个引脚中,可以任选一个(两者的区别是,滑动头的转动方向不一样)。选择好引脚后,可以将其接在万用表上,测其阻值的大小,转动滑动头,看顺时针转动时阻值是增加还是减小,这样做对调试电路时有好处,可以知道自己旋转的方向是增加电阻还是减小电阻。
(4)蜂鸣器
本实验所用的蜂鸣器和平时看到的扬声器、耳机等发声器件有微小的差别,它里边多了一个振荡器,输入电流时振荡器产生的音频信号电流通过电磁线圈,使电磁线圈产生磁场。振动膜片在电磁线圈和磁铁的相互作用下,周期性地振动发声。可以尝试的将其正负极接上电源,可看到只有正负极接入正确时,蜂鸣器才会发声。也可根据蜂鸣器上的引线长度按来判断正负极(长正短负)。所以在实验室中要把蜂鸣器的正负极接正确。
(5)三极管
三极管有两种,一种是PNP管,一种是NPN管,本实验用的是PNP管。
三极管有三个引脚,分别是基极(b),发射极(e),集电极(c)。本实验所用的三极管判断极点的方法是,面对有型号标记的一面,然后看着三个引脚,从左到右依次是,发射极(e),基极(b),集电极(c)。接线时三个极端不能接错,否则三极管就没有起到作用。                        
9  三极管符号、管脚排列图
集电极和基极之间形成集电结,发射极和基极之间形成发射结,三极管起放大作用的条件,发射结正向偏置,集电结反向偏置。正向偏置时必须达到正向偏置电压,即为导通,否则,为截止状态。
4.1.2PCB板进行排版及连线                                          
本实验所用的面包板的内部链接在破坏背面的绝缘胶带的情况下,可以揭开胶带看其内部线路的构造,以防不知道内部线路差错电路。当然最好的办法是:用测试电路在插孔上来回实验,猜想验证其内部构造。                                                        
(1)首先了解面包板在连线和焊接的注意事项。
(2)了解实验原件及器材后,按照原理图在面包板上连接电路。
(3)焊接要注意,电子电路在焊接时,应遵循的规则。
4.1.3 焊接的问题及解决
一般来说,造成硬件问题的首要问题就是焊接了,也就是说焊接的好与坏直接响产品的正常运行。造成焊接质量不高的常见原因是:①焊锡用量过多,形成焊点的锡堆积;焊锡过少,不足以包裹焊点。②冷焊。焊接时烙铁温度过低或加热时间不足,焊锡未完全熔化、浸润、焊锡表面不光亮(不光滑),有细小裂纹(如同豆腐渣一样!)。③夹松香焊接,焊锡与元器件或印刷板之间夹杂着一层松香,造成电连接不良。若夹杂加热不足的松香,则焊点下有一层黄褐色松香膜;若加热温度太高,则焊点下有一层碳化松香的黑色膜。对于有加热不足的松香膜的情况,可以用烙铁进行补焊。对于已形成黑膜的,则要"吃"净焊锡,清洁被焊元器件或印刷板表面,重新进行焊接才行。④焊锡连桥。指焊锡量过多,造成元器件的焊点之间短路。这在对超小元器件及细小印刷电路板进行焊接时要尤为注意。⑤焊剂过量,焊点明围松香残渣很多。当少量松香残留时,可以用电烙铁再轻轻加热一下,让松香挥发掉,也可以用蘸有无水酒精的棉球,擦去多余的松香或焊剂。⑥焊点表面的焊锡形成尖锐的突尖。这多是由于加热温度不足或焊剂过少,以及烙铁离开焊点时角度不当浩成的内。
  最小系统的电路不工作,首先应该确认电源电压是否正常。用电压表测量接地引脚跟电源引脚之间的电压,看是否符合电源电压,常用的是5V左右。接下来就是检测复位引脚的电压是否正常,EA引脚的电压要正常为5V左右。
4.1.4焊接的技巧和注意事项
1、焊锡之前应该先插上电烙铁的插头,给电烙铁加热。  
2、焊接时,焊锡与电路板、电烙铁与电路板的夹角最好成45度,这样焊锡与电烙铁夹角成90度。
3、焊接时,焊锡与电烙铁接触时间不要太长,以免焊锡过多或是造成漏锡;也不要过短,以免造成虚焊。
4、元件的腿尽量要直,而且不要伸出太长,以1毫米为好,多余的可以剪掉。
5、焊完时,焊锡最好呈圆滑的圆锥状,而且还要有金属光泽。
4.2调试4.2.1系统的调试
系统调试包括硬件调试和软件调试,而且两者是密不可分的。我们设计好的硬件电路和软件程序,只有经过联合调试,才能验证其正确性;软硬件的配人情况以及是否达到设计任务的要求,也只有经过调试,才能发现问题并加以解决、完善,最终开发成实用产品。
  硬件调试分单元电路调试和联机调试,单元电路试验在硬件电路设计时已经进行,这里的调试只是将其制成印刷电路板后试验电路是否正确,并排除一些加工工艺性错误(如错线、开路、短路等)。这种调试可单独模拟进行,也可通过开发装置由软件配合进行,硬件联机调试则必须在系统软件的配合下进行。
  软件调试一般包括分块调试和联机调试两个阶段。程序的分块调试一般在单片机开发装置上进行,可根据所调程序功能块的入口参量初值编制一个特殊的程序段,并连同被调程序功能块一起在开发装置上运行;也可配合对应硬件电路单独运行某程序功能块,然后检查是否正确,如果执行结果与预想的不一致,可以通过单步运行或设置断点的方法,查出原因并加以改正,直到运行结果正确为止。这时该 程序功能块已调试完毕,可去掉附加程序段。其它程序功能块可按此法进行调试。程序联机调试就是将已调试好的各程序功能块按总体结构联成一个完整程序,在所研制的硬件电路上运行。从而试验程序整体运行的完整性、正确性和与硬件电路的配合情况。在联调中可能会有某些支路上的程序、功能块因受条件制约而得不到相应的输入参数,这时,调试人员应创造条件进行模拟调试。在联调中如发现硬件问题也应及时修正,直到单片机系统的软件、硬件全部调试成功为止。系统调试完成后,还要进行一段时间的试运行,从而检验系统的稳定性和抗干扰能力,验证系统功能是否达到设计要求,是否达到预期的效果。
4.2.2具体调试
1、具有清零装置和抢答控制,可由主持人操纵避免有人在主持人说
“开始”前提前抢答违反规则。
2、具有定时功能,在60秒内无人抢答表示所有参赛选手获参赛队对本题弃权。
3、60秒时仍无人抢答其报警电路工作表示抢答时间耗尽并禁止抢答。
4、 显示抢答时间, 按一下减一秒,按一下"-1s"键,时间LED上会显示改变后的时间,调整范围为0s~60s。                        
5、主持人按"抢答开始"键,会有提示音,并立刻进入抢答倒计时(预设60s抢答时间),如有选手抢答,会有提示音,并会显示其号数,只有第一个按抢答的选手有效。                                                                                             
6、如倒计时期间,主持人想停止倒计时可以随时按"停止"按键,系统会自动进入准备状态,等待主持人按"抢答开始"进入下次抢答计时。                                                                                                      
致谢
经过近一个月的努力,在老师和同学的讨论和帮助下,我成功地完成了基于单片机的简易抢答器系统的设计,通过此次毕业设计,所学过得知识再次被我拾起,使我重新认识到了对书本上的知识要独立运用的道理。在抢答器设计过程中,发现了很多细节性的问题,也出现了很多错误,通过此次的抢答器的设计,让我重新拾起了以前所学习的电子知识和单片机语言的编程,也使我加深了对单片机及接口技术的理解和应用,由于知识水平的局限,设中可能会存在着一些不足,我真诚的接受老师的批评和指正,也非常感谢老师们的一路陪伴和细心教授,因为有你们,我才能完成这次毕业设计,真诚的希望你们在以后的生活里更加美好,培养出一代又一代优秀学子。
附件1:基于单片机的简易抢答器系统设计实物图





附件2:基于单片机的简易抢答器系统单面PCB板图

附件3:基于单片机的简易抢答器系统设计程序
  1. #include <reg52.h>                       //调用单片机头文件
  2. #define uchar unsigned char  //无符号字符型 宏定义              变量范围0~255
  3. #define uint  unsigned int              //无符号整型 宏定义              变量范围0~65535
  4. //数码管段选定义 0     1    2    3                 4                 5              6              7                8                 9            
  5. uchar code shumaguan_du[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
  6. //                                                                         A              B              C                D                 E   F              不显示
  7.                                                                       0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff};              //断码            
  8. sbit shumaguan_wei1 = P3^3;                //数码管位选定义8
  9. sbit shumaguan_wei2 = P3^4;
  10. sbit shumaguan_wei3 = P3^5;
  11. sbit shumaguan_wei4 = P3^6;
  12. sbit beep = P3^7;      //蜂鸣器IO口定义

  13. uchar xuanshou_start;         //开始抢答标志位
  14. uchar xuanshou_weigui;        //抢答违规标志位

  15. uchar shumaguan[4] = {0xc0,0xbf,0xa4,0xb0};              //数码管显示缓冲区
  16. uchar shumaguan_i = 4;          //显示数码管的个位数
  17. uchar miao,s_time=30;        //时间
  18. uchar xuanshou_num;           //号码
  19. uchar menu_1 ;            //菜单设置变量
  20. bit xuanshou_200ms = 1;       //200ms的标志位
  21. uchar xuanshou_kd_en;          //抢答
  22. uchar i;


  23. /**************************数码管位选函数****************************/
  24. void shumaguan_wei_switch(uchar i)
  25. {
  26.               switch(i)
  27.               {
  28.                             case 0: shumaguan_wei1 = 0;  shumaguan_wei2 = 1; shumaguan_wei3 = 1;  shumaguan_wei4 = 1; break;
  29.                             case 1: shumaguan_wei1 = 1;  shumaguan_wei2 = 0; shumaguan_wei3 = 1;  shumaguan_wei4 = 1; break;
  30.                             case 2: shumaguan_wei1 = 1;  shumaguan_wei2 = 1; shumaguan_wei3 = 0;  shumaguan_wei4 = 1; break;
  31.                             case 3: shumaguan_wei1 = 1;  shumaguan_wei2 = 1; shumaguan_wei3 = 1;  shumaguan_wei4 = 0; break;
  32.               }            
  33. void delay_1ms(uint k)              //延时1ms函数
  34. {
  35.               uint i,j;
  36.               for(i=0;i<k;i++)
  37.                             for(j=0;j<120;j++);
  38. }


  39. /********************独立按键程序*****************/
  40. uchar key_on;              //按键值
  41. void key()              //独立按键程序
  42. {
  43.               static uchar key_new;
  44.               key_on = 20;
  45.               P2 = 0xff;
  46.               if((P2 & 0xff) != 0xff)                            //按键按下
  47.               {
  48.                             delay_1ms(1);                                 //按键消抖动
  49.                             if(((P2 & 0xff) != 0xff) && (key_new == 1))
  50.                             {                                                                                    //确认是按键按下
  51.                                           key_new = 0;
  52.                                           switch(P2 & 0xff)
  53.                                           {
  54.                                                         case 0xfe:  key_on = 1;  break;              //得到按键值
  55.                                                         case 0xfd:  key_on = 2;  break;              //得到按键值
  56.                                                         case 0xfb:  key_on = 3;  break;              //得到按键值
  57.                                                         case 0xf7:  key_on = 4;  break;              //得到按键值
  58.                                                         case 0xef:  key_on = 5;  break;              //得到按键值
  59.                                                         case 0xdf:  key_on = 6;  break;              //得到按键值
  60.                                                         case 0xbf:  key_on = 7;  break;              //得到按键值
  61.                                                         case 0x7f:  key_on = 8;  break;              //得到按键值
  62.                                           }
  63. //                                          shumaguan[0] = shumaguan_du[key_on];                                                        //显示按键值
  64.                             }                                         
  65.               }
  66.               else
  67.                             key_new = 1;            
  68. }


  69. /********************独立按键程序*****************/
  70. uchar key_on1;              //按键值
  71. void key_1()                //主持人独立按键程序
  72. {
  73.               static uchar key_new;
  74.               key_on1 = 20;
  75.               P3 |= 0x03;
  76.               if((P3 & 0x03) != 0x03)                            //按键按下
  77.               {
  78.                             delay_1ms(1);                                 //按键消抖动
  79.                             if(((P3 & 0x03) != 0x03) && (key_new == 1))
  80.                             {                                                                                    //确认是按键按下
  81.                                           key_new = 0;
  82.                                           switch(P3 & 0x03)
  83.                                           {
  84.                                                         case 0x01:  key_on1 = 9;   break;              //得到按键值
  85.                                                         case 0x02:  key_on1 = 10;  break;              //得到按键值
  86.                                           }
  87. //                                          shumaguan[0] = shumaguan_du[key_on1];                                                        //显示按键值
  88.                             }                                         
  89.               }
  90.               else
  91.                             key_new = 1;            
  92. }

  93. /******************按键处理函数*****************/
  94. void key_with()                //按键处理函数
  95. {
  96.               if(key_on1 == 10)    //设置按键
  97.               {
  98.                             menu_1 ++;
  99.                             if(menu_1 == 1)
  100.                             {
  101.                                           shumaguan[0] = shumaguan_du[s_time % 10];                  //显示设置值
  102.                                           shumaguan[1] = shumaguan_du[s_time / 10 % 10];              //显示设置值
  103.                                           shumaguan[2] = 0xbf;
  104.                                           shumaguan[3] = shumaguan_du[10];                          //显示A
  105.                             }
  106.                             if(menu_1 > 1)
  107.                                           menu_1 = 0;
  108.               }
  109.               if(key_on1 == 9)        //开始抢答键
  110.               {
  111.                             xuanshou_start = 1;
  112.                             for(i=0;i<2;i++)
  113.                             {
  114.                                           beep = ~beep;
  115.                                           delay_1ms(20);            
  116.                             }
  117.               }
  118.               if(key_on < 9)
  119.               if(menu_1 == 0)
  120.               {
  121.                             if(xuanshou_kd_en == 0)                   //没有抢答                           
  122.                             {
  123.                                           if(key_on == 1)
  124.                                                         xuanshou_num = 1;    //1号选手
  125.                                           if(key_on == 2)
  126.                                                         xuanshou_num = 2;    //2号选手
  127.                                           if(key_on == 3)
  128.                                                         xuanshou_num = 3;    //3号选手
  129.                                           if(key_on == 4)
  130.                                                         xuanshou_num = 4;    //4号选手
  131.                                           if(key_on == 5)
  132.                                                         xuanshou_num = 5;    //5号选手
  133.                                           if(key_on == 6)
  134.                                                         xuanshou_num = 6;    //6号选手
  135.                                           if(key_on == 7)
  136.                                                         xuanshou_num = 7;    //7号选手
  137.                                           if(key_on == 8)
  138.                                                         xuanshou_num = 8;    //8号选手
  139.                             }
  140.                             if(xuanshou_start == 1)                              //开始抢答
  141.                             {
  142.                                           xuanshou_weigui = 0;               
  143.                                           xuanshou_kd_en = 1;       //已经抢答                                                                     
  144.                             }
  145.                             else
  146.                             {
  147.                                           xuanshou_weigui = 1;   //违规了
  148.                             }                           
  149.               }
  150.               if(menu_1 == 1)
  151.               {
  152.                             if(key_on == 8)   //加键
  153.                             {
  154.                                           s_time ++;     //设置倒计时加1            
  155.                                           if(s_time >= 99)
  156.                                                         s_time = 99;
  157.                                           shumaguan[0] = shumaguan_du[s_time % 10];              //显示设置值
  158.                                           shumaguan[1] = shumaguan_du[s_time / 10 % 10];              //显示设置值
  159.                             }
  160.                             if(key_on == 7)
  161.                             {
  162.                                           if(s_time > 3)
  163.                                                         s_time -- ;              //设置倒计时减1            
  164.                                           shumaguan[0] = shumaguan_du[s_time % 10];                  //显示设置值
  165.                                           shumaguan[1] = shumaguan_du[s_time / 10 % 10];              //显示设置值
  166.                             }
  167.               }            
  168. }

  169. /******************倒计时处理*****************/
  170. void daojishi_dis()                 //倒计时处理
  171. {
  172.               static uchar j;
  173.               if((xuanshou_start == 1) && (xuanshou_weigui == 0))
  174.               {
  175.                             j ++;
  176.                             if(j >= 5)     //1s
  177.                             {
  178.                                           j = 0;
  179.                                           if(miao != 0)
  180.                                                         miao --;              //倒计时减一
  181.                             }                                         
  182.                             if(miao <= 5)
  183.                             {
  184.                                           beep = ~beep; //蜂鸣器提示报警
  185.                             }
  186.                             if(miao == 0)
  187.                             {
  188.                                           beep = 1;     //关闭蜂鸣器
  189.                                           xuanshou_start = 0;
  190.                             }
  191.               }                           
  192. }

  193. /********************************************************************
  194. * 名称 : display()
  195. * 功能 : 数码管显示
  196. * 输入 : 无
  197. * 输出 : 无
  198. ***********************************************************************/
  199. void display()                 //数码管显示
  200. {
  201.               static uchar i;
  202.               i++;
  203.               if(i >= shumaguan_i)
  204.                             i = 0;            
  205.               P1 = 0xff;                      //消隐
  206.               shumaguan_wei_switch(i);              //位选
  207.               P1 = shumaguan[i];              //
  208.             
  209. }



  210. /*************定时器0初始化程序***************/
  211. void time_init()              //  定时器0初始化程序
  212. {
  213.               EA   = 1;                              //开总中断
  214.               TMOD = 0X01;                //定时器0、工作方式1
  215.               ET0  = 1;                              //开定时器0中断
  216.               TR0  = 1;                              //允许定时器0定时
  217. }

  218. /******************主程序**********************/               
  219. void main()
  220. {
  221.               static uchar j;
  222.               time_init();                   //  定时器0初始化程序
  223.               while(1)
  224.               {
  225.                             if(xuanshou_weigui == 0)
  226.                             {
  227.                                           key();                     //独立按键程序
  228.                                           key_1();                   //主持人独立按键程序
  229.                             if((key_on < 20) || (key_on1 < 20))
  230.                                           key_with();                 //按键处理函数
  231.                             }
  232.                             if(xuanshou_200ms == 1)
  233.                             {
  234.                                           xuanshou_200ms = 0;
  235.                                           if(menu_1 == 0)
  236.                                           {
  237.                                                       
  238.                                           shumaguan[3] = shumaguan_du[miao / 10 % 10];              //显示设置值
  239.                                           shumaguan[2] = shumaguan_du[miao % 10];              //显示设置值
  240.                                           shumaguan[1] = 0xbf;
  241.                                           shumaguan[0] = shumaguan_du[xuanshou_num];              //显示选手号码            
  242.                                           if(xuanshou_weigui == 1)  //违规了显示FF
  243.                                                         {
  244.                                                                       shumaguan[3] = shumaguan_du[15];              //显示设置值
  245. ……………………

  246. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

完整的Word格式文档51黑下载地址:
简易抢答器设计说明书.doc (2.8 MB, 下载次数: 61)


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:357323 发表于 2018-12-25 01:53 | 只看该作者
写的不错,精彩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表