基于51单片机的8路抢答器.doc
基于51单片机的8路抢答器摘 要此次设计提出了用AT89S52单片机为核心控制元件,设计一个简易的抢答器,本方案以AT89S52单片机作为主控核心,与晶振、数码管、蜂鸣器等构成八路抢答器,利用了单片机的延时电路、按键复位电路、时钟电路、定时/中断等电路,设计的八路抢答器具有实时显示抢答选手的号码和抢答时间的特点,还有复位电路,使其再开始新的一轮的答题和比赛,同时还利用C51语言编程,使其实现一些基本的功能。本设计的系统实用性强、判断精确、操作简单、扩展功能强。它的功能实现是比赛开始,主持人读完题之后按下总开关,即计时开始,此时数码管开始进行20s的倒计时,直到有一个选手抢答时,对应的会在数码管上显示出该选手的编号和抢答所用的时间,如果在规定的20s时间内没有做出抢答,则此题作废,即开始重新一轮的抢答。在抢答和回答时间的最后5s,蜂鸣器都会给予报警提示。关键词:单片机、AT89S52、抢答器第一章 前 言单片机又称单片微控制器,它不是完成某一个逻辑功能的芯片,而是把一个计算机系统集成到一个芯片上。 单片机按其内部中央处理器CPU(CentralProcessingUnit)的字长分为1位机、4位机、8位机、16位机等。从1976年8位单片机诞生以来,单片机领域中一直是以8位机为主流机型,预计这种情况还将继续下去。因此我们以Intel公司的8位机为例来谈谈单片机的发展历史。1第一阶段单片机阶段(1976年1978年)。这阶段的任务是探索计算机的单芯片集成。以Intel公司的MCS-48为代表,其CPU、存储器、定时器计数器、中断系统、I/O端口、时钟以及指令系统都是按嵌入式系统要求专门设计的。 参与这阶段探索的公司还有Motorola、Zilog等。2第二阶段单片机的完善阶段(1978年一1982年)。计算机的单芯片集成探索取得成功后,随后的任务就是要完善单片机的体系结构。作为这一阶段的典型代表是Inlel公司将MCS48向MCS5l系列的过渡。它在以下几个重要方面奠定了单片机的体系结构。1.完善的外部总线。有8位数据总线、16位地址总线、控制总线及具有多机通信功能的串行通信接口。2.CPU外围功能单元的集中管理模式。3.设置面向工控的位地址空间及位操作方式。4.指令系统突出控制功能。 3第三阶段微控制器形成阶段(1983年一1990年)。这一阶段单片机的主要技术发展方向是满足测控对象要求的外围电路的增强,如AD转换、DA转换、高速IO口、WDT(程序监视定时器)、DMA(高速数据传输)等,强化了智能控制的特征。 4第四阶段微控制器全面发展阶段(1990年以后)。即当前的单片机时代,其显著特点是百花齐放、技术创新。单片机正在满足各个方面的需求从玩具、小家电、工业控制单元到机器人、智能仪表,过程控制,个人信息终端等无所不能。随着微电子技术、电力电子技术、传感器技术、永磁材料技术、自动控制技术、微机应用技术的发展,使单片微型计算机也得到迅速的发展,单片机微型计算机是微型计算机的一个重要分支,也是颇具生命力的机种。单片机微型计算机简称单片机,特别适用于控制领域故又称为微控制器。 第二章 各模块的选择和论证2.1抢答器显示模块选择显示模块主要是显示抢答的时间,组别号码等。在使用传统的数码管显示。数码管具有:低能耗、低损耗、低压、寿命长、耐老化、防晒、防潮、防火、防高(低)温,对外界环境要求低,易于维护,同时其精度高,称量快,精确可靠,操作简单。数码显示是采用BCD编码显示数字,程序编译容易,资源占用较少。显示功能与硬件关系极大,当硬件固定后,如何在不引起操作者误解的前提下提供尽可能丰富的信息,全靠软件来解决。在这里我们使用的是七段数码管显示,通常在显示上我们采用的方法一般包括两种:一种是静态显示,一种是动态显示。其中静态显示的特点是显示稳定不闪烁,程序编写简单,但占用端口资源多;动态显示的特点是:显示稳定性没静态好,程序编写复杂,但是相对静态显示而言占用端口资源少。在本设计中根据实际情况采用的是动态显示方法。4位七段数码管显示电路如下图所示。图 2-1 4位七段数码管显示电路图上图中数码管采用的是4位一体七段共阳数码管,其中AH段分别接到单片机的P0口,由单片机输出的P0口数据来决定段码值,位选码COM1, COM2,COM3,COM4分别接到单片机的P2.0,P2.1,P2.2 ,P2.,3,由单片机来决定当前该显示的是哪一位。在图中还有一个排阻,连接在P0口上,用作P0口的上拉电阻,保证P0口没有数据输出时候处于高电平状态。通过查表法,将其在数码管上显示出来,其中P0口为字型码输入端,P2口低4位为字选段输入段。在这里我们通过查表将字型码送给7段数码管显示的数字。2.2 控制器选择控制器主要用于对显示、抢答、音乐、计分等模块进行控制。采用ATMEL公司的AT89S51作为系统控制器的CPU方案。单片机算术运算功能强,软件编程灵活、自由度大,可以用软件编程实现各种算法和逻辑控制,并且由于其功耗低、体积小、技术成熟和成本低等优点,使其在各个领域应用广泛。2.3 键盘选择键盘是单片机不可缺少的输入设备,是实现人机对话的纽带。键盘按结构形式可以分为非编码键盘和编码键盘,前者用软件方法产生键码,而后者则用硬件方法来产生键码。在单片机中使用的都是非编码键盘,因为非编码键盘结构简单,成本低廉,非编码键盘的类型很多,常用的有独立式键盘,行列式键盘等。本设计采用独立式键盘键盘接口中使用多少根I/O线,键盘中就有几个按键,键盘接口使用了8根I/O口线,该键盘就有8个按键,这种类型的键盘,其按键比较少,且键盘中各按键的工作互不干扰。因此可以根据实际需要对键盘中的按键灵活的编码。如图2-2。最简单的编码方式就是根据I/O输入口所直接反映的相应按键,按下的状态进行编码,称按键直接状态码,对于这样编码的独立式键盘,CPU可以通过直接读取I/O口的状态来获取按键的直接状态编码值,根据这个值直接进行按键识别,这样形式的键盘结构简单,按键识别容易。独立式键盘的缺点是需要占用比较多的I/O口线,当单片机应用系统键盘中需要的按键比较少或I/O口线比较富余时,可以采用这样类型的键盘。 P112345678 图2-2 独立式键盘 图 2-4 抢答按键及调整按键2.4 时钟频率电路的设计单片机必须在时钟的驱动下才能工作。在单片机内部有一个时钟振荡电路,只需要外接一个振荡源就能产生一定的时钟信号送到单片机内部的各个单元,决定单片机的工作速度。时钟电路如下图所示。图 2-5 外部振荡源电路一般选用石英晶体振荡器。此电路在加电大约延迟10ms后振荡器起振,在XTAL2引脚产生幅度为3V左右的正弦波时钟信号,其振荡频率主要由石英晶振的频率确定。电路中两个电容C1,C2的作用有两个:一是帮助振荡器起振;二是对振荡器的频率进行微调。单片机在工作时,由内部振荡器产生或由外直接输入的送至内部控制逻辑单元的时钟信号的周期称为时钟周期。其大小是时钟信号频率的倒数。图中时钟频率为12MHz。2.5 复位电路的设计 单片机的第9脚RST为硬件复位端,只要将该端持续4个机器周期的高电平即可实现复位,复位后单片机的各状态都恢复到初始化状态,其电路图如下所示:2.6 报警电路 我们知道,声音的频谱范围约在几十到几千赫兹,若能利用程序来控制单片机某个口线的“高”电平或低电平,则在该口线上就能产生一定频率的巨型波,接上喇叭就能发出一定频率的声音,若再利用延时程序控制“高”“低”电平的持续时间,就能改变输出频率,从而改变音调,使喇叭发出不同的声音。本文设计如下图所示。图中单片机的14脚输出具有复合功能,此处用到了单片机14脚的IO端口功能,单片机通过内部定时器的操作实现交替变换的波形输出驱动扬声器发声。 图 2-7 发声电路2.7 AT89S52单片机简单概述2.7.1 AT89S52单片机的结构AT89S52单片机是美国Atmel公司生产低电压,高性能CMOS 8位单片机,片内含4k bytes的可反复擦写的只读程序存储器(EPROM)和128 bytes的随机存取数据存储器(RAM),器件采用Atmel公司的高密度、非易失性存取技术生产,兼容标准MCS-51指令系统,片内置通用8位中央处理器(CPU)和Flash 存储单元,功能强大。AT89S52单片机可提供许多高性价比的应用场合,可灵活应用于各种控制领域。图2-8为AT89S52单片机的基本组成功能方块图。由图可见,在这一块芯片上,集成了一台微型计算机的主要组成部分,其中包括CPU、存储器、可编程I/O口、定时器/计数器、串行口等,各部分通过内部总线相连。下面介绍几个主要部分。振荡器和时序OSC程序存储器4 KB ROM数据存储器256 B RAM/SFR定时器/计数器 2 ×16 AT89S51CPU64 KB总线 扩展控制器可编程 I/O可编程全双工串行口内中断图 2-8 单片机结构框图2.7.2 AT89S52单片机管脚说明图 2-9 AT89S52单片机管脚图ATMEL公司的AT89S52是一种高效微控制器。采用40引脚双列直插封装形式。AT89S52单片机是高性能单片机,因为受引脚数目的限制,所以有不少引脚具有第二功能。VCC:供电电压。GND:接地。P0口:P0口为一个8位漏级开路双向I/O口,每脚可吸收8TTL门电流。当P1口的管脚第一次写1时,被定义为高阻输入。P0能够用于外部程序数据存储器,它可以被定义为数据/地址的第八位。在FLASH编程时,P0 口作为原码输入口,当FLASH进行校验时,P0输出原码,此时P0外部必须被拉高。P1口:P1口是一个内部提供上拉电阻的8位双向I/O口,P1口缓冲器能接收输出4TTL门电流。P1口管脚写入1后,被内部上拉为高,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是由于内部上拉的缘故。在FLASH编程和校验时,P1口作为第八位地址接收。 P2口:P2口为一个内部上拉电阻的8位双向I/O口,P2口缓冲器可接收,输出4个TTL门电流,当P2口被写1时,其管脚被内部上拉电阻拉高,且作为输入。并因此作为输入时,P2口的管脚被外部拉低,将输出电流。这是由于内部上拉的缘故。P2口当用于外部程序存储器或16位地址外部数据存储器进行存取时,P2口输出地址的高八位。在给出地址1时,它利用内部上拉优势,当对外部八位地址数据存储器进行读写时,P2口输出其特殊功能寄存器的内容。P2口在FLASH编程和校验时接收高八位地址信号和控制信号。P3口:P3口管脚是8个带内部上拉电阻的双向I/O口,可接收输出4个TTL门电流。当P3口写入1后,它们被内部上拉为高电平,并用作输入。作为输入,由于外部下拉为低电平,P3口将输出电流。P3口也可作为AT89S51的一些特殊功能口,如下表所示:P3口管脚 备选功能P3.0 RXD(串行输入口)P3.1 TXD(串行输出口)P3.2 INT0(外部中断0)P3.3 INT1(外部中断1)P3.4 T0(记时器0外部输入)P3.5 T1(记时器1外部输入)P3.6 (外部数据存储器写选通)P3.7 (外部数据存储器读选通)P3口同时为闪烁编程和编程校验接收一些控制信号。ALE/:当访问外部存储器时,地址锁存允许端的输出电平用于锁存地址的地址字节。在FLASH编程期间,此引脚用于输入编程脉冲。在平时,ALE端以不变的频率周期输出正脉冲信号,此频率为振荡器频率的1/6。因此它可用作对外部输出的脉冲或用于定时目的。然而要注意的是:每当用作外部数据存储器时,将跳过一个ALE脉冲。如想禁止ALE的输出可在SFR8EH地址上置0。此时, ALE只有在执行MOVX,MOVC指令是ALE才起作用。PSEN:外部程序存储器的选通信号端。在由外部程序存储器取指期间,每个机器周期两次PSEN有效。但在访问外部数据存储器时,这两次有效的/PSEN信号将不出现。/VP:当保持低电平时,则在此期间外部程序存储器(0000H-FFFFH),不管是否有内部程序存储器。注意加密方式1时,将内部锁定为RESET;当端保持高电平时,此间内部程序存储器。在FLASH编程期间,此引脚也用于施加12V编程电源。XTAL1:反向振荡放大器的输入及内部时钟工作电路的输入。XTAL2:反向振荡器的输出,如采用外部时钟源驱动器件,应不接。第三章 模块最终方案的设计3.1总体设计思路主控制器模块:采用AT89S52单片机控制抢答器显示模块:数码管显示电源方案的选择:采用4.5V电源供电3.2 功能介绍主持人按“抢答开始”键,立刻进入抢答倒计时(预设20S抢答时间),如有选手抢答,会有提示,并会显示其号数,不进行抢答查询,所以第一个按抢答的选手有效。倒数时间到小于5S会每秒响一下提示音。 如倒计时期间,主持人想停止倒计时可以随时按“停止”按键,系统会自动进入准备状态,等待主持人按“抢答开始”进入下次抢答计时。如果主持人未按“抢答开始”键,则无法按抢答按键。3.3 抢答器的软件设计 系统软件由主程序和INT0中断服务组成。主程序由验键,违规显示,倒计时等功能子程序组成,系统完成初始化后循环检查各个功能当用户使用某个功能时,按下相应的按钮(或开关)单片机进入相应的功能处理。INT0中断服务程序完成抢答信号采样和识别处理。该智能抢答器以AT89S52单片机为控制核心,控制精度较高,操作误差主要来自晶振自身所造成的误差。其他外围电路包括复位电路、时钟电路、报警电路、LED显示电路、抢答按键等。该智能抢答器具有计时记忆功能,一次时间设置完,复位后不需重新进行时间设定;通过按键扫描输出按键信息,并通过单片机将它转化为在七段数码管上显示的字形符。单片机的P1口为8组抢答按键的输入口,P0.0P0.7为数码管的段选口,P2.0P2.2为数码管的片选口。P3.4为报警电路的控制口,P3.5为暂停按钮的控制口,P3.6为开始按钮的控制口,P3.7为复位按钮的控制口。 3.4 数码显示数码显示管用来作为时间的显示输出,一般用7段数码显示管。本次设计中采用7段共阳数码显示管应用简单、可靠性高、成本低,作为显示输出。连接时段选信号接在P0口的P0.0P0.7七个I/O口上,P1口是准双向I/O接口在输出驱动部分具有驱动4个TTL负载的能力,即输出电流不大于400A,所以在接电阻时选择接10K限流电阻。而在位选方面采用P2口的P2.0P2.3用单片机四个I/O口作为位选信号的输出口。第四章 系统调试与仿真 系统调试包括硬件调试和软件调试,而且两者是密不可分的。我们设计好的硬件电路和软件程序,只有经过联合调试,才能验证其正确性;软硬件的配人情况以及是否达到设计任务的要求,也只有经过调试,才能发现问题并加以解决、完善,最终开发成实用产品。硬件调试分单元电路调试和联机调试,单元电路试验在硬件电路设计时已经进行,这里的调试只是将其制成印刷电路板后试验电路是否正确,并排除一些加工工艺性错误(如错线、开路、短路等)。这种调试可单独模拟进行,也可通过开发装置由软件配合进行,硬件联机调试则必须在系统软件的配合下进行。软件调试一般包括分块调试和联机调试两个阶段。程序的分块调试一般在单片机开发装置上进行,可根据所调程序功能块的入口参量初值编制一个特殊的程序段,并连同被调程序功能块一起在开发装置上运行;也可配合对应硬件电路单独运行某程序功能块,然后检查是否正确,如果执行结果与预想的不一致,可以通过单步运行或设置断点的方法,查出原因并加以改正,直到运行结果正确为止。这时该 程序功能块已调试完毕,可去掉附加程序段。其它程序功能块可按此法进行调试。程序联机调试就是将已调试好的各程序功能块按总体结构联成一个完整程序,在所研制的硬件电路上运行。从而试验程序整体运行的完整性、正确性和与硬件电路的配合情况。在联调中可能会有某些支路上的程序、功能块因受条件制约而得不到相应的输入参数,这时,调试人员应创造条件进行模拟调试。在联调中如发现硬件问题也应及时修正,直到单片机系统的软件、硬件全部调试成功为止。系统调试完成后,还要进行一段时间的试运行,从而检验系统的稳定性和抗干扰能力,验证系统功能是否达到设计要求,是否达到预期的效果。4.1 软件调试问题分析数码管显示问题:本次设计的最终方案是采用数码管显示屏实现显示功能,最初数码管显示不正常,出现闪烁现象。通过调试发现这是由于延时时间选择不当会使人眼产生视觉暂留效果,每一次显示时都必须加入适当的时间延时。由于一开始所选用的延时时间太短因此出现闪烁现象,在增加显示延时之后,数码管显示正常。蜂鸣器异常启动问题:蜂鸣器的启动/关闭是通过单片机输出的控制信号来实现的,当前时间与闹钟设置时间比较吻合时,单片机将对闹铃控制口执行取反命令,从而启动蜂鸣器发声。一开始编写程序时,没有对控制口的最初状态作正确设置,由于系统开机复位后,闹铃控制口处于高电平状态,因此出现一开机蜂鸣器就处于启动状态的情况。通过在主程序最开始加入对闹铃控制口取零命令后,蜂鸣器启动/关闭控制恢复正常。4.2 Proteus 仿真Proteus软件是来自英国Labcenter Electronics公司的EDA工具软件,Proteus软件除了其具有和其它EDA工具一样的原理布图,PCB自动或人工布线及电路仿真的功能外, 其革命性的功能是,他的电路仿真是互动的,针对微处理器的应用,还可以直接在基于原理图的虚拟原型上编程,并实现软件源码级的实时调试,如有显示及输出, 还能看到运行后输入输出的效果,配合系统配置的虚拟仪器如示波器,逻辑分析仪等,您不需要别的,Proteus为您建立了完备的电子设计开发环境!PROTUES的ISIS是一款Labcenter出品的电路分析实物仿真系统,可仿真各种电路和IC,并支持单片机,元件库齐全,使用方便,是不可多得的专业的单片机软件仿真系统。该软件的特点:1. 全部满足我们提出的单片机软件仿真系统的标准,并在同类产品中具有明显的优势。2.具有模拟电路仿真、数字电路仿真、单片机及其外围电路组成的系统的仿真、RS-232动态仿真、C调试器、SPI调试器、键盘和LCD系统仿真的功能;有各种虚拟仪器,如示波器、逻辑分析仪、信号发生器等。3. 目前支持的单片机类型有:68000系列、8051系列、AVR系列、PIC12系列、PIC16系列、PIC18系列、Z80系列、HC11系列以及各种外围芯片。4. 支持大量的存储器和外围芯片。总之该软件是一款集单片机和SPICE分析于一身的仿真软件,功能极其强大 ,可仿真51、AVR、PIC。第五章 电路板的制作与检查考虑到本系统所用元器件较少,大部分功能都是通过软件编程来实现,同时也出于对毕业设计成本的考虑,因此所用到的板子是自己手工制作的PCB板。在电路板的制作中,首先要进行线路的排布。利用PROTEL软件模拟实际电路板的线路走向,尽量避免线路出现交叉短路,电源线路尽量安排在电路板的最外圈。PCB板刻录完成之后,开始进行焊接工作。焊接完后进行电路板检查,将原线路图与实际焊接的电路板进行对比,由于线路不多,所以用万用表的欧姆档或是短路声响指示功能来做焊点的检测,如此可以避免焊接时漏焊、虚焊和配线错误的问题,同时保证了所制作出来的线路与原设计线路的一致性。一般来说,造成硬件问题的首要问题就是焊接了,也就是说焊接的好与坏直接响产品的正常运行。造成焊接质量不高的常见原因是:1. 焊锡用量过多,形成焊点的锡堆积;焊锡过少,不足以包裹焊点。2.冷焊。焊接时烙铁温度过低或加热时间不足,焊锡未完全熔化、浸润、焊锡表面不光亮(不光滑),有细小裂纹。3.夹松香焊接,焊锡与元器件或印刷板之间夹杂着一层松香,造成电连接不良。若夹杂加热不足的松香,则焊点下有一层黄褐色松香膜;若加热温度太高,则焊点下有一层碳化松香的黑色膜。对于有加热不足的松香膜的情况,可以用烙铁进行补焊。对于已形成黑膜的,则要"吃"净焊锡,清洁被焊元器件或印刷板表面,重新进行焊接才行。4.焊锡连桥。指焊锡量过多,造成元器件的焊点之间短路。这在对超小元器件及细小印刷电路板进行焊接时要尤为注意。5.焊剂过量,焊点明围松香残渣很多。当少量松香残留时,可以用电烙铁再轻轻加热一下,让松香挥发掉,也可以用蘸有无水酒精的棉球,擦去多余的松香或焊剂。6.焊点表面的焊锡形成尖锐的突尖。这多是由于加热温度不足或焊剂过少,以及烙铁离开焊点时角度不当浩成的内。最小系统的电路不工作,首先应该确认电源电压是否正常。用电压表测量接地引脚跟电源引脚之间的电压,看是否符合电源电压,常用的是5V左右。接下来就是检测复位引脚的电压是否正常,EA引脚的电压要正常为5V左右。第六章 总结通过这次毕业设计,我才明白学习是一个长期积累的过程,在以后的工作、生活中都应该不断的学习,努力提高自己知识和综合素质。总之,不管学会的还是学不会的的确觉得困难比较多,真是万事开头难,不知道如何入手。最后终于做完了有种如释重负的感觉。此外,还得出一个结论:知识必须通过应用才能实现其价值!有些东西以为学会了,但真正到用的时候才发现是两回事,所以我认为只有到真正会用的时候才是真的学会了。通过这次课程设计懂得了很多,我们自己去图书馆,上网查资料然后自己和我们这组的成员一起合作商讨完成的,原以为会很简单的,但无论在制作与写作过程中我们都遇到了理论课上所不曾遇到的问题,第一是综合性太强,这次制作与论文不仅涉及到我们以前所学到的单片机,模拟电子技术,数字电子技术,高等数学等课程的知识还涉及到很多我们的选修及课外的知识像实训课上学到的手工焊接技术等等知识。第二是理论联系实际性太强,把所学的搜集到得知识运用的实际中不是一件容易的事,不仅由元件从课本上的符号到实物的认识还是理论的测量结果与实际值的误差。在不断的努力下我们组的课程设计终于完成了。在没有做课程设计以前觉得课程设计只是对这几年来所学知识的大概总结,但是真的面对课程设计时发现自己的想法基本是错误的。课程设计不仅是对前面所学知识的一种检验,而且也是对自己能力的一种提高。课程设计是我们对所学知识理论的检验与总结,能够培养和提高设计者独立分析和解决问题的能力;课程设计提高了我们理论联系实际的能力更在知识的巩固与实际的操作上的衔接提高了我们的能力,课程设计中遇到的困难与挫折以及解决这些问题的思路与方法更增加了我们对以后工作中遇到困难克服解决的信心,也让我们积累了经验,为以后的工作打下了良好的基础,同时也培养了我们遇到突发状况要稳定冷静的精神,也培养了我们学会怎么与别人合作的方法,怎么解决与合作的伙伴意见不同一时状况,为以后怎么和同事相处好奠定了基础。这次课程设计业也让我们懂得了分析问题,才能解决问题的道理,通过了这次更增加了我们以后能够干好自己工作的信心。参考文献、资料索引文献、资料名称编著者出版单位Protel DXP电路设计与制版使用教程单片机技术任务驱动式教程单片机技术课程设计与项目实例单片机原理与应用教程单片机基础基于Proteus的单片机可视软硬件仿真还有很多的网上资料等李小坚徐进强 左翠红李海滨刘瑞新李广弟 朱月秀 冷祖祁李全利 迟荣强人民邮电出版社天津大学出版社中国电力出版社机械工业出版社冶金工业出版社北京航空航天大学出版社附 录 三 Proteus仿真原理图图1 Proteus仿真原理#include <reg52.h>#define uint unsigned int#define uchar unsigned char/*-共阴极数码管编码表 0 - f显示-*/unsigned char code table=0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0x08,0x03,0x46,0x21,0x06,0x0e;/*-变量定义-*/sbit start= P36;sbit stop=P35;sbit reset = P37;sbit key1 = P10;sbit key2 = P11;sbit key3 = P12;sbit key4 = P13;sbit key5 = P14;sbit key6 = P15;sbit key7 = P16;sbit key8 = P17;sbit buzzer = P34;bit start_flag = 0;bit stop_flag=0;bit key1_flag = 0;bit key2_flag = 0;bit key3_flag = 0;bit key4_flag = 0;bit key5_flag = 0;bit key6_flag = 0;bit key7_flag = 0;bit key8_flag = 0;bit reset_flag = 0;bit action = 0;uchar second = 20;uchar timer0_count = 0;uchar number = 0;uchar number_display = 0;/*-延时函数-*/void delay(uint z)uint x,y;for(x=z;x>0;x-)for(y=110;y>0;y-);/*-数码管显示驱动函数-*/void display(uchar number,uchar second)uchar second_first,second_second;second_first = second / 10;second_second = second % 10;P2 = 0xfe;P0 = tablenumber;delay(2);P2 = 0xfd;P0 = 0x3f;delay(2);P2 = 0xfb;P0 = tablesecond_first;delay(2);P2 = 0xf7;P0 = tablesecond_second;delay(2);/*-开始键扫描函数-*/void start_keyscan()if(start = 0)delay(8);if(start = 0)&&(!start_flag)start_flag = 1;action = 1;TR0 = 1;elsestart_flag = 0;/*-八位抢答键扫描函数-*/uchar key_scan8()if(key1 = 0)delay(8);if(key1 = 0)&&(!key1_flag)key1_flag = 1;number = 1;number_display = number;elsekey1_flag = 0;number = 0;if(key2 = 0)delay(8);if(key2 = 0)&&(!key2_flag)key2_flag = 1;number = 2;number_display = number;elsekey2_flag = 0;number = 0;if(key3 = 0)delay(8);if(key3 = 0)&&(!key3_flag)key3_flag = 1;number = 3;number_display = number;elsekey3_flag = 0;number = 0;if(key4 = 0)delay(8);if(key4 = 0)&&(!key4_flag)key4_flag = 1;number = 4;number_display = number;elsekey4_flag = 0;number = 0;if(key5 = 0)delay(8);if(key5 = 0)&&(!key5_flag)key5_flag = 1;number = 5;number_display = number;elsekey5_flag = 0;number = 0;if(key6 = 0)delay(8);if(key6 = 0)&&(!key6_flag)key6_flag = 1;number = 6;number_display = number;elsekey6_flag = 0;number = 0;if(key7 = 0)delay(8);if(key7 = 0)&&(!key7_flag)key7_flag = 1;number = 7;number_display = number;elsekey7_flag = 0;number = 0;if(key8 = 0)delay(8);if(key8 = 0)&&(!key8_flag)key8_flag = 1;number = 8;number_display = number;elsekey8_flag = 0;number = 0;if(number_display != 0)return 1;elsereturn 0;/*-复位键扫描函数-*/void reset_keyscan()if(reset = 0)delay(8);if(reset = 0)&&(!reset_flag)reset_flag = 1;number_display = 0; second=20;elsereset_flag = 0;void fengming() /蜂鸣函数,脉宽t = 1ms 周期T = 2ms 频率f = 0.5khz 实际发现延时1ms的时候效果最好 /延时1ms buzzer = 0; /给P3.7口送高电平 delay(100); /延时1ms buzzer = 1;delay(100);/*-主函数-*/void main()TMOD=0x01;TH0=(65536-50000)/256;TL0=(65536-50000)%256;EA=1;ET0=1;TR0=0;while(1) start_keyscan(); reset_keyscan();while(action=1)if(second<=5&&second>0) fengming() ; wh