制作出来的实物图如下:
八路抢答器元件清单
1) 9*15万用板
2) 四位一体共阴数码管
3) STC89C51单片机
4) 40P芯片座
5) 12M晶振
6) 30P瓷片电容 *2
7) 10K电阻
8) 10uF电解电容
9) 2.2K电阻
10) 102排阻
11) PNP三极管9012
12) 5v有源蜂鸣器
13) 按键*11
14) 4P下载排针
15) DC座(电源插座)
16) 自锁开关
17) 细导线
18) 焊锡
19) USB电源线或电池盒+DC插头
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
采用单片机作为整个控制核心,控制系统主要由:显示模块、控制模块、报警模块、抢答模块组成。抢答模块可以采用独立按键或矩阵键盘,显示模块可以采用数码管的动态扫描或LCD1602液晶显示屏。
八路抢答器需要按钮不是太多,独立按键相比于矩阵键盘,可以直接读取,检测占用时间少,程序简单,能使抢答器更加快捷,简单。选手抢答更方便,所以选用独立按键。对于显示模块而言,数码管便宜,利用动态扫描完全可以实现多位数字,LCD1602液晶显示屏,液晶显示屏显示的功能强大,可显示大量文字、图形,虽然LCD1602液晶屏进行显示可以显示32个字符,但本设计用不到那么多显示,而数码管满足需求,且性价比更好,所以选择数码管。
抢答器的工作原理是采用单片机最小系统,用程序查询方式采用动态显示组号。主持人按下开始抢答键才可以抢答。主持人按下开始抢答按纽(P3.0),数码管60秒倒计时开始(60秒内必须回答完问题),选手准备抢答,60秒内有人抢答则蜂鸣器响声提示并在数码管显示他的组号及剩余时间,60秒内无选手抢答,则在最后五秒倒计时发出警报。答题结束,需主持人复位还原。单片机最小系统、抢答按键模块(四位并行数码显示)、显示模块、显示驱动模块、抢答开关模块、蜂鸣器音频输出模块。
单片机复位电路通常采用上电自动复位和按钮复位两种方式。本次设计的复位电路是通过外部电路的电容充放电来实现的。只要Vcc的上升时间不超过1ms,就可以实现自动上电复位。
电路中当一个问题结束主持人后按下复位开关后进行下一题的准备。
选手抢答键
89C51的P1口做一个为选手抢答的输入按键引脚,P1.0至P1.7轮流输出低电位,给每一个选手编号1至8,当选手按下按钮时,P1口个端口的电平变化从P1口输入,经单片机处理后从P0输出由数码管显示抢答者编号。
显示与显示驱动电路包括显示和驱动,显示采用数码管,驱动用P2口,抢答成功者编号和回答问题时间60秒倒计时所剩时间均在数码管上显示,数码管采用动态显示。驱动电路P2口,查询显示程序利用P0口做段选码口输出P2低3位做位选码输出,当为低电平则能驱动数码管使其显示数字。在+5V电压下接1k的电阻,保证正常压降。
蜂鸣器输出电路
通过控制不同频率的矩形脉冲来控制蜂鸣器发声。此次设计中只需要一些简单的提示声音,抢答成功、抢答时间用完后,得到提示声。
显示初始界面,如需要调整倒计时时间,按下按钮进入倒计时设置界面,设置成功返回到主界面,抢答开始,主持人按下开始按钮,进入主程序,数码管开始倒计时,有选手抢答,则跳入抢答子程序,显示选手序号及倒计时所剩时间。若无选手抢答,则程序一直执行,在最后5秒发出警报直到倒计时结束。待到下一次使用,按下复位键就可以执行上述操作。
选手抢答成功,发出警报提示,告知其他选手已有选手抢答成功,数码管显示选手序号和倒计时所剩时间,在选手答题完毕后,主持人按下复位按钮。继续下一轮抢答。
测试结果和分析
软件调试中的模块包括显示功能模块,调整时间功能模块,抢答功能模块以及报警功能模块。各个独立模块功能调试成功后,将这些模块程序通过主程序合并在一起,最后再对合并后的总程序进行调试。仿真和实物实现功能一致。数码管上选手序号显示正确,蜂鸣器在规定范围内发出报警。
当主持人按下开始键时,向单片机P3.0引脚输入一个低电平信号,表示整个电路开始工作,此时数码管前两位显示选手编号(无人抢答显示00),后两位显示倒计时剩余时间。若在60秒内仍然无人抢答,蜂鸣器在最后5秒发出连续报警,提示抢答时间快要结束;若在60秒内有人抢答,并且抢答成功,则将选手编号显示在数码管前两位上,后两位显示抢答剩余时间,同时蜂鸣器发出一声报警,提示其他没有抢答的选手此题已被人抢答成功。若在抢答过程中遇见特殊情况,主持人则可以通过时间加,时间减按键来进行时间调节。若要开始新的一轮抢答,主持人按下复位键再按开始键即可。
单片机源程序如下:
- #include<reg51.h>
- #include<intrins.h>
- sbit smg1=P2^0; //定义数码管第一位
- sbit smg2=P2^1; //定义数码管第二位
- sbit smg3=P2^2; //定义数码管第三位
- sbit keyks=P3^0; //定义开始按键
- sbit keytz=P3^1; //定义停止按键
- sbit keyqc=P3^2; //定义清除按键
- sbit key1=P1^0; //定义1号抢答选手
- sbit key2=P1^1; //定义2号抢答选手
- sbit key3=P1^2; //定义3号抢答选手
- sbit key4=P1^3; //定义4号抢答选手
- sbit key5=P1^4; //定义5号抢答选手
- sbit key6=P1^5; //定义6号抢答选手
- sbit key7=P1^6; //定义7号抢答选手
- sbit key8=P1^7; //定义8号抢答选手
- sbit spk=P3^7; //定义蜂鸣器
- int djs=30,js=0; //djs和bt是初始倒计时时间,可修改
- //int table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
- int table[]={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x40};
- void delayms(int x) //延时函数
- {
- unsigned int i;
- while(x--)
- {
- for(i=20;i>0;i--);
- }
- }
- void Timer0_init() //定时器0初始化
- {
- js=0;
- TMOD=0x01; //T0为定时器方式1
- TH0=0x3c;
- TL0=0xb0;
- //TR0=1;//IT1=1;
- ET0=1;//EX1=1;
- EA=1;
- }
- void timer0() interrupt 1 using 1 //定时器0中断服务函数
- {
- // TF0=0;
- TH0=0x3c;
- TL0=0xb0; //赋初值
- js++;
- if(js>=20)
- { js=0;
- djs--; //产生1s的倒计时
- //led1=~led1;
- }
- }
- void djsxs() //显示倒计时函数
- { int b1,b2;
- b1=djs/10;
- b2=djs%10; // 将倒计时时间分成高低位
- P0=table[b1];
- smg2=0;
- delayms(3);
- smg2=1; //显示十位数字
- P0=table[b2];
- smg3=0;
- delayms(3); //显示个位数字
- smg3=1;
- }
- void djsxs22()
- {
- P0=0x40;
- smg1=0;
- delayms(3);
- smg1=1; //第一位数码管显示-
- P0=0x40;
- smg2=0;
- delayms(3); //第三位数码管显示-
- smg2=1;
- P0=0x40;
- smg3=0;
- delayms(3);
- smg3=1; //第四位数码管显示-
- }
- void djsxs1()
- {
- P0=table[1];
- smg1=0;
- delayms(3);
- smg1=1; //第一位数码管显示1
- }
- void djsxs2()
- {
- P0=table[2];
- smg1=0;
- delayms(3);
- smg1=1; //第一位数码管显示2
- }
- void djsxs3()
- {
- P0=table[3];
- smg1=0;
- delayms(3);
- smg1=1; //第一位数码管显示3
- }
- void djsxs4()
- {
- P0=table[4];
- smg1=0;
- delayms(3);
- smg1=1; //第一位数码管显示4
- }
- void djsxs5()
- {
- P0=table[5];
- smg1=0;
- delayms(3);
- smg1=1; //第一位数码管显示5
- }
- void djsxs6()
- {
- P0=table[6];
- smg1=0;
- delayms(3);
- smg1=1; //第一位数码管显示6
- }
- void djsxs7()
- {
- P0=table[7];
- smg1=0;
- delayms(3);
- smg1=1; //第一位数码管显示7
- }
- void djsxs8()
- {
- P0=table[8];
- smg1=0;
- delayms(3);
- smg1=1; //第一位数码管显示8
- }
- void main()
- {
- int djs1=60;
- Timer0_init(); //初始化定时器中断
- spk=1; //蜂鸣器不响
- djs=60; //倒计时赋值
- while(1)
- {
-
- LOOP1: djs=djs1;
- djsxs22(); //LOOP1是标号,显示 - --
-
- if(key1==0) //在定时器运行状态下,key1==0 则说明1号选手按下按键
- {
- delayms(300);
- if(key1==0)
- {
- while(!key1); //去除按键抖动后,重新在判断,是否确实按下
- djs=60;
- while(1)
- {
- TR0=0; //定时器停止
- djsxs();
- if(key2==0)
- {
- delayms(300); //去除抖动
- if(key2==0) //再次判断是否按下
- {
- while(!key2); //如果按下
- djs++;
- djs1=djs;
- }
- }
- if(key3==0)
- {
- delayms(300); //去除抖动
- if(key3==0) //再次判断是否按下
- {
- while(!key3); //如果按下
- djs--;
- djs1=djs;
- }
- }
- if(key1==0)
- {
- delayms(100); //去除抖动
- if(key1==0) //再次判断是否按下
- {
- while(!key1); //如果按下
- goto LOOP1; //goto语句,回到loop1表号处
- }
- }
- }
- }
- }
- if(keyks==0)
- {
- //spk=0;
- delayms(300); //去除按键抖动
- if(keyks==0)
- {
- while(!keyks); //以上表示按下开始按键
- //spk=1; //蜂鸣器不响
- TR0=1; //启动定时器 开始倒计时
- while(1)
- {
- djsxs();
- if(keytz==0)
- {
- delayms(300); //此处表示出去抖动, 以后不一一标出
- if(keytz==0)
- {
- while(!keytz); //以上表示按下停止按键后
- TR0=0; //定时器停止
- }
- }
- if(keyks==0)
- {
- //spk=0;
- delayms(300);
- if(keyks==0)
- {
- while(!keyks); //以上表示按下清楚按键后
- //spk=1; //蜂鸣器不响
- TR0=1; //定时器启动
- }
- }
- /***************************以下是八个选手抢答,key1表示1号选手,依次类推,注释只写第一位选手,其他和第一个完全一致,************************************/
- if((key1==0)&&(TR0==1)) //在定时器运行状态下,key1==0 则说明1号选手按下按键
- {
- spk=0; //蜂鸣器响
- delayms(3);
- if(key1==0)
- {
- while(!key1); //去除按键抖动后,重新在判断,是否确实按下
- spk=1; //蜂鸣器不响
- while(1)
- {
- TR0=0; //定时器停止
- djsxs1(); //显示选手编号
- djsxs(); //显示剩余倒计时时间
- if(keyqc==0)
- {
- delayms(3); //去除抖动
- if(keyqc==0)
- {
- while(!keyqc); //如果按下清楚键,则回到- --状态
- goto LOOP1; //goto语句,回到loop1表号处
- }
- }
- }
- }
- }
- if((key2==0)&&(TR0==1))
- {
- spk=0;
- delayms(3);
- if(key2==0)
- {
- while(!key2);
- spk=1;
- while(1)
- {
- TR0=0;
- djsxs2();
- djsxs();
- if(keyqc==0)
- {
- delayms(3);
- if(keyqc==0)
- {
- while(!keyqc);
- goto LOOP1;
- }
- }
- }
- }
- }
- if((key3==0)&&(TR0==1))
- {
- spk=0;
- delayms(3);
- if(key3==0)
- {
- while(!key3);
- spk=1;
- while(1)
- {
- TR0=0;
- djsxs3();
- djsxs();
- if(keyqc==0)
- {
- delayms(3);
- if(keyqc==0)
- {
- while(!keyqc);
- goto LOOP1;
- }
- }
- }
- }
- }
- if((key4==0)&&(TR0==1))
- {
- spk=0;
- delayms(3);
- if(key4==0)
- {
- while(!key4);
- spk=1;
- while(1)
- {
- TR0=0;
- djsxs4();
- djsxs();
- if(keyqc==0)
- {
- delayms(3);
- if(keyqc==0)
- {
- while(!keyqc);
- goto LOOP1;
- }
- }
- }
- }
- }
- if((key5==0)&&(TR0==1))
- {
- spk=0;
- delayms(3);
- if(key5==0)
- {
- while(!key5);
- spk=1;
- while(1)
- {
- TR0=0;
- djsxs5();
- djsxs();
- if(keyqc==0)
- {
- delayms(3);
- if(keyqc==0)
- {
- while(!keyqc);
- goto LOOP1;
- }
- }
- }
- }
- }
- if((key6==0)&&(TR0==1))
- {
- spk=0;
- delayms(3);
- if(key6==0)
- {
- while(!key6);
- spk=1;
- while(1)
- {
- TR0=0;
- djsxs6();
- djsxs();
- if(keyqc==0)
- {
- delayms(3);
- if(keyqc==0)
- {
- while(!keyqc);
- goto LOOP1;
- }
- }
- }
- }
- }
- if((key7==0)&&(TR0==1))
- {
- spk=0;
- delayms(3);
- if(key7==0)
- {
- while(!key7);
- spk=1;
- while(1)
- {
- TR0=0;
- djsxs7();
- djsxs();
- if(keyqc==0)
- {
- delayms(3);
- if(keyqc==0)
- {
- while(!keyqc);
- goto LOOP1;
- }
- }
- }
- }
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
仿真代码51hei附件下载:
仿真程序.7z
(1.29 MB, 下载次数: 34)
|