本设计是以八路抢答为基本理念。考虑到依需设定限时回答的功能,利用STC89C52单片机及外围接口实现的抢答系统,利用单片机的定时器/计数器定时和记数的原理,将软、硬件有机地结合起来,使得系统能够正确地进行计时,同时使数码管能够正确地显示时间。用开关做键盘输出,扬声器发生提示。同时系统能够实现:在抢答中,只有开始后抢答才有效,如果在开始抢答前抢答为无效;抢答限定时间为60秒,倒计时为5秒时蜂鸣器报警,选手抢答成功后显示选手编号以及剩余时间。
设计要求与指标:
11) 八个按键分别表示1至8号选手。 22) 有开始键,暂停键,复位键。 3) 当按下开始键后,从60秒开始倒计时,当倒计时为5秒时,蜂鸣器报警。 4) 有选手按下抢答按键后,液晶屏显示选手编号和剩余时间。 5) 抢答成功后按复位键从新开始。
制作出来的实物图如下:
使用说明
一、 主要功能:
1、采用4位数码管设计。
2、下排按键一一对应八位选手。
3、上排三个按键,从走到右依次为:开始、暂停、复位。
4、操作流程:上电后数码管显示“----”当主持人按下“开始”键后,倒计时60秒,开始计时,此时,八位选手就可以抢答,如有紧急情况需要停止的话,主持人按“暂停”键就可以,如果有选手抢答成功,数码管显示“1 25”,1表示是1号选手,25表示剩余还25秒,倒计时小于5秒时,蜂鸣器响,提示时间快要结束,当倒计时为0秒时,此题结束,表示没有任何选手抢答成功,主持人按“复位”键后从新开始。
5、可以设定倒计时时间,在上电后,数码管显示“----”,此时按下1号选手对应的按键,进入倒计时时间设定状态,2号选手对应的按键为时间加,3号选手对应的按键为时间减,设定完成后再按1号选手键退出。
6、供电方式,1、电池供电,2、usb供电
电池供电需3节5号电池,请尽量用新电池,已保证足够的电压。
Usb供电可以连接手机充电器,笔记本、台式电脑,如插入其他供电设备,请确保电压为5V。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include<reg51.h>
- #include<intrins.h>
- sbit smg1=P2^4; //定义数码管第一位
- sbit smg2=P2^6; //定义数码管第二位
- sbit smg3=P2^7; //定义数码管第三位
- sbit smg4=P2^5;
- sbit keyks=P2^2; //定义开始按键
- sbit keytz=P2^1; //定义停止按键
- sbit keyqc=P2^0; //定义清除按键
- sbit key1=P1^4; //定义1号抢答选手 sbit
- sbit key2=P1^5; //定义2号抢答选手
- sbit key3=P1^6; //定义3号抢答选手
- sbit key4=P1^7; //定义4号抢答选手
- sbit key5=P3^4; //定义5号抢答选手
- sbit key6=P3^5; //定义6号抢答选手
- sbit key7=P3^6; //定义7号抢答选手
- sbit key8=P3^7; //定义8号抢答选手
- sbit spk=P1^0; //定义蜂鸣器
- int djs=60,js=0; //djs和bt是初始倒计时时间,可修改
- unsigned char flag=0;
- //int table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
- int table[]={0x5f,0x44,0x9d,0xd5,0xc6,0xd3,0xdb,0x45,0xdf,0xd7,0x80};
- void delayms(int x) //延时函数
- {
- char i;
- while(x--)
- {
- for(i=500;i>0;i--);
- }
- }
-
- void Timer0_init() //定时器0初始化
- {
- js=0;
- TMOD=0x01; //T0为定时器方式1
- TH0=60;
- TL0=176;
- //TR0=1;//IT1=1;
- ET0=1;//EX1=1;
- EA=1;
- }
- void timer0() interrupt 1 using 1 //定时器0中断服务函数
- {
- TF0=0;
- TH0=60;
- TL0=176; //赋初值
- js++;
- if(flag==1)
- {
- if(js<8)
- spk=0;
- else spk=1;
- }
- if(js==20)
- { js=0;
- djs--; //产生1s的倒计时
- }
- }
- 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 djsxs30() //第二位数码管显示-
- {
- P0=0x80; //第二位数码管
- smg4=0;
- delayms(3);
- smg4=1;
- }
- void djsxs22()
- {
- P0=0x80;
- smg1=0;
- delayms(3);
- smg1=1;
- //第一位数码管显示-
- P0=0x80; //第二位数码管
- smg4=0;
- delayms(3);
- smg4=1;
-
- P0=0x80;
- smg2=0;
- delayms(3); //第三位数码管显示-
- smg2=1;
- P0=0x80;
- 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(3);
- if(key1==0)
- {
- while(!key1); //去除按键抖动后,重新在判断,是否确实按下
- djs=60;
- while(1)
- {
- TR0=0; //定时器停止
- djsxs();
- if(key2==0) //复位按下按下
- {
- delayms(8); //去除抖动
- if(key2==0) //再次判断是否按下复位按键
- {
- do
- {
- while(!key2); //如果按下复位键,则回到- --状态
- delayms(5);
- }
- while(key2!=1);
- djs++;
- djs1=djs;
- }
- }
- if(key3==0) //复位按下按下
- {
- delayms(8); //去除抖动
- if(key3==0) //再次判断是否按下复位按键
- {
- do
- {
- while(!key3); //如果按下复位键,则回到- --状态
- delayms(5);
- }
- while(key3!=1);
- djs--;
- djs1=djs;
- }
- }
- if(key1==0) //复位按下按下
- {
- delayms(3); //去除抖动
- if(key1==0) //再次判断是否按下复位按键
- {
- while(!key1); //如果按下复位键,则回到- --状态
- goto LOOP1; //goto语句,回到loop1表号处
- }
- }
- }
- }
- }
- if(keyks==0)
- {
- //spk=0;
- delayms(3); //去除按键抖动
- if(keyks==0)
- {
- while(!keyks); //以上表示按下开始按键
- //spk=1; //蜂鸣器不响
- TR0=1; //启动定时器 开始倒计时
- while(1)
- {
- djsxs();
- if(keytz==0)
- {
- delayms(3); //此处表示出去抖动, 以后不一一标出
- if(keytz==0)
- {
- while(!keytz); //以上表示按下停止按键后
- {
- TR0=0; //定时器停止
- flag=0;//
- spk=1;
- }
- }
- }
- if(keyks==0)
- {
- //spk=0;
- delayms(3);
- 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; //蜂鸣器不响
- flag=0;//清0最后五秒响蜂鸣器
- }
- while(1)
- {
- TR0=0; //定时器停止
- djsxs1(); //显示选手编号
- djsxs30(); //第二位数码管显示-
- 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;
- flag=0;//清0最后五秒响蜂鸣器
- }
- while(1)
- {
- TR0=0;
- djsxs2();
- djsxs30(); //第二位数码管显示-
- 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;
- flag=0;//清0最后五秒响蜂鸣器
- }
- while(1)
- {
- TR0=0;
- djsxs3();
- djsxs30(); //第二位数码管显示-
- 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;
- flag=0;//清0最后五秒响蜂鸣器
- }
- while(1)
- {
- TR0=0;
- djsxs4();
- djsxs30(); //第二位数码管显示-
- 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;
- flag=0;//清0最后五秒响蜂鸣器
- }
- while(1)
- {
- TR0=0;
- djsxs5();
- djsxs30(); //第二位数码管显示-
- 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;
- flag=0;//清0最后五秒响蜂鸣器
- }
- while(1)
- {
- TR0=0;
- djsxs6();
- djsxs30(); //第二位数码管显示-
- 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;
- flag=0;//清0最后五秒响蜂鸣器
- }
- while(1)
- {
- TR0=0;
- djsxs7();
- djsxs30(); //第二位数码管显示-
- djsxs();
- if(keyqc==0)
- {
- delayms(3);
- if(keyqc==0)
- {
- while(!keyqc);
- goto LOOP1;
- }
- }
- }
- }
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
基于单片机的八路智能抢答器.7z
(413.61 KB, 下载次数: 57)
|