
一、设计要求(1)抢答器同时供10名选手或10个代表队比赛。(2)设置一个系统清除和抢答控制开关S该开关由主持人控制。(3)抢答器具有锁存与显示功能。即选手按动按钮锁存相应的编号并在LED数码管上显示同时扬声器发出声响提示。选手抢答实行优先锁存优先抢答选手的编号一直保持到主持人将系统清除为止。(4)抢答器具有定时抢答功能抢答的时间由主持人设定如30秒。当主持人启动开始键后定时器进行减计时同时扬声器发出短暂的声响声响持续的时间0.5秒左右。(5)参赛选手在设定的时间内进行抢答抢答有效定时器停止工作显示器上显示选手的编号和抢答的时间并保持到主持人将系统清除为止。(6)如果定时时间已到无人抢答本次抢答无效系统报警并禁止抢答定时显示器上显示00二、设计准备Keil uVision编写代码Proteus 8 Professional仿真和调试立创EDA进行绘制PCB板封装。已经绘制的程序流程图三、绘制仿真图首先选择满足设计要求的元器件建立合适的电路图。如果先编写代码的话还不确定一些引脚、开关、晶振电路、器件参数等等的设计直接写代码不实际。笔者用到的器件有共阳极四位数码管7SEG-MPX4-CA单片机AT89C52按钮开关BUTTON有源蜂鸣器BUZZER电容CAP晶振CRYSTALNPN三极管RES电阻SW-SPST单刀单掷开关。按照如图所示在元器库里搜索所需元器件其余的电源和地线在左侧终端模型中直接选择。补充知识1、数码管原理单个数码管的内部电路图a~h每个数字代表一个发光二极管v是公共端可以接地或者电源对应共阴极和共阳极接法。a~g段数码管用来显示数字h显示小数点。为了便于封装数码管的外部一共10个引脚5和10连在一起接公共端其余各对应一个发光二极管。a~f六个数码管亮能实现显示数字0b、c两个数码管点亮实现数字1的显示。Proteus中的数码管有八个引脚输入八位的二进制数就能实现数字的显示。四位数码管的段选端口是连接在一起的。1、2、3、4是位选信号。如果我们将段选信号输入到端口那么所有的数码管显示的数字相同。为了显示不同数字每次只让一个位选信号使用其他三个就禁止虽然每个时刻只有一个数码管显示但是下一时刻就切换要显示的数字。因为肉眼捕捉的速度比较慢信号切换的速度很快这样就是看到四个数码管同时亮动。共阴极和共阳极数码管共阳数码管是指将所有发光二极管的阳极接到一起形成公共阳极(COM)的数码管当某一字段发光二极管的阴极为低电平时相应字段就点亮反之相应字段就不亮。共阴数码管是指将所有发光二极管的阴极接到一起形成公共阴极(COM)的数码管当某一字段发光二极管的阳极为高电平时相应字段就点亮反之相应字段就不亮。数码管公共极的连接不同共阳数码管在应用时应将公共极COM接到5V共阴数码管在应用时应将公共极COM接到地线GND上2.有源蜂鸣器和无源蜂鸣器在Proteus中有源蜂鸣器是下面这个。有源蜂鸣器使用简单不能设置频率只能发出单音无源可以设置频率。两者对输入信号的要求不一样有源蜂鸣器工作的理想信号是直流电通常标示为VDC、VDD等。蜂鸣器内部有一简单的振荡电路能将恒定的直流电转化成一定频率的脉冲信号从面实出磁场交变带动钼片振动发音。两者所接电路不一样。选择有源蜂鸣器时选择其电压为5V。Proteus电路图总线设置时按下英文模式键盘的快捷键a弹出窗口写入NETP0#可以依次给导线注释P1、P2……写入NETk可以给导线直接标注为k。四、编写keil代码生成hex文件五、进行Proteus仿真双击单片机把hex程序文件添加进去然后进行运行仿真。笔者做的只是简单的十路抢答器在运用单片机串口的时候整个P0口做数码管的段选码整个P2做位选码两个串口都来实现这些功能了在数码管显示的过程中P2口的状态一直在改变这样就很难再加其他功能。所以再加入控制开关的时候另辟蹊径选择带电源的单刀单掷开关加入进去后也没有影响数码管的显示。报警器的代码设置因为使用了很多其他方法诸如改变报警的条件启动开关开启和秒数减到0才报警;或者让位选码的设定这和单独的四个iO口有关或者把报警电路接到P3口再改变910号的代码显示或者用stcisp软件设置单片机的P4口做io口使用等等……控制效果都不如现在的这个电路。最后设置为当倒计时为29秒开始响到28他自然就不响了以及倒计时为00时报警但此时做不到报警响铃具体时间自动停下只能关闭启动开关再按下复位开关报警解除。其他附加功能难以实现这是笔者的本次设计的最大不足。咸鱼一条的我肝了许多也解决不了问题如果使用寄存器来节省io口的话可能就更好但实在能力有限添加锁存器时写入代码更加运行不了对电路内部原理和C语言只是略微了解。有兴趣的小伙伴可以去了解一下锁存器在数码管和单片机的使用。不过好在整个设计满足基本的设计要求。六、立创创建原理图和封装Proteus文件无法直接转化为立创图。根据Proteus的原理图用立创绘图。在元件库中找不到元件时小伙伴们可以先把Proteus上的名称百度搜索他的中文名或另外的英文名再在元件库中搜索对应的中文或英文名。单片机上没用到的io口不需要接线了在后续绘制pcb板铺铜会处理那些多余的引脚。注意根据立创使用守则说明书使用总线的原理图不能直接转换为pcb板。我已经吃过这个亏了。立创有时候连接导线会突然停下来让人误以为连上了放大检查所有线路都连接完整后转化为pcb。为了节约材料选择合适的板子大小把元件放入板子上并且按实际情况放置好开关等元件。下载好本地自动布线程序开始自动布线。布线后根据实际线路需要再设置其他属性比如连接电源的导线应该加粗。选择底层视图去掉元件显示找到一根电源线右键查找相似对象然后再后边的属性栏增加导线宽度。最后为了减小回路面积降低地线阻抗使电镀层压不变形给pcb板铺铜。点击铺铜工具分别在顶层和底层给板子内部四角依次点击 最后铺铜完成。详细的铺铜要求可以参考其他文献笔者只做了简单地线铺铜 。感谢所有读者能看到这里~o(*▽*)ブ看到周围很多同学因为课设而头疼自己做出来一个课设也希望能给其他人帮助。第一次写类似的文章我是自动化专业的还做了很多课设希望以后再发出来。最后keil软件编写的代码也全部奉献啦创作不易期待帅哥美女们一键三连(☆▽☆)也欢迎各位留言交流。#include reg52.h #define uchar unsigned char #define uint unsigned int /****************共阳极数码管9-0***************/ char code table[]{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; uchar code weima[]{0x80,0x40,0x20,0x10,0x08,0x04,0x01}; uchar disp[]{0xc0,0xb0,0xbf,0xbf}; sbit kP2^0; sbit BuzzerP2^2; uchar miao30;//设定倒计时 uchar i1,count0,scan0,shu,shu1; void keys(void); void delay(uint t) {while(t--);} void xianshi(void) { if(scan5)scan1; P2weima[scan-1]; P0disp[scan-1]; delay(200); } main() { TMOD0x01;//t0,方式1 TH00x3c;TL00x0b0; EA1; ET01; P10xff; P30xff; TR01; while(1) { if(disp[0]table[9]disp[1]table[2]) { Buzzer1; } if(miao0) {TR00; Buzzer1; delay(2000); Buzzer0; } xianshi(); if(miao!0) if(P1!0xff||P3!0xff) { delay(5); if(P1!0xff||P3!0xff) { switch(P1) { case 0xfe : shu1; shu10; break; case 0xfd : shu2; shu10; break; case 0xfb : shu3; shu10; break; case 0xf7 : shu4; shu10; break; case 0xef : shu5; shu10; break; case 0xdf : shu6; shu10; break; case 0xbf : shu7; shu10; break; case 0x7f : shu8; shu10; break; } switch(P3) { case 0xbf : shu9; shu10; break; case 0x7f : shu0; shu11; break;} } disp[2]table[shu]; disp[3]table[shu1]; TR00; //定时器停止倒计时 while(1){xianshi();} //保证第一个按键有效 } } } void Timer0Interrupt(void) interrupt 1 { if(k1) {delay(10); if(k1) { if(count20k1) {count0; miao--; disp[0]table[miao%10]; disp[1]table[miao/10]; } } } }