抢答器具有数据锁存和显示功能.当某一路抢答成功时.发光二极管立即点亮.并在该电路上显示该路的号数.直到主持人按复位开关为止.此时其他人抢答无效。
抢答器具有定时抢答功能.且抢答时间可以由主持人设定(如97s).当主持人按下“开始”按钮后.要求定时器立即倒计时.并在显示器上显示时间.同时发出“滴”的声响。
在设定的时间内抢答.则抢答有效.定时器停止工作.显示器上显示选手的编号和抢答时刻的时间.并保持到主持人将系统清零
如果定时器的时间已到.却没有选手抢答.则本次抢答无效.系统会短暂的报警.并且封锁输入电路禁止选手超时抢答.时间显示器上显示00.
16路抢答器仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
压缩包里面有完整论文:
单片机源码:
- #include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
- #define DataPort P0 //定义数据端口 程序中遇到DataPort 则用P0 替换
- #define uchar unsigned char; //定义数据类型 程序中遇到unsigned char 则用uchar替换
- #define uint unsigned int; //定义数据类型 程序中遇到unsigned int 则用uint替换
- sbit add=P2^0;
- sbit jian=P2^1;
- sbit beep=P2^2; //定义报警输入端口
- sbit start=P2^3;
- sbit WEI=P2^7; //定义锁存使能端口 位锁存
- sbit DUAN=P2^6; //定义锁存使能端口 段锁存
- sbit key1=P1^0;
- sbit key2=P1^1;
- sbit key3=P1^2;
- sbit key4=P1^3;
- sbit key5=P1^4;
- sbit key6=P1^5;
- sbit key7=P1^6;
- sbit key8=P1^7;
- sbit key9=P3^0;
- sbit key10=P3^1;
- sbit key11=P3^2;
- sbit key12=P3^3;
- sbit key13=P3^4;
- sbit key14=P3^5;
- sbit key15=P3^6;
- sbit key16=P3^7;
- uchar code dofly_DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值0~9
- uchar code dofly_WeiMa[10]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码
- uchar code table[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
- uchar TempData[8]; //存储显示值的全局变量
- //函数声明
- void DelayUs2x(unsigned char t);
- void DelayMs(unsigned char t);
- void Delay(unsigned char t);
- void Display(unsigned char FirstBit,unsigned char Num);
- void check1();
- void check2();
- void keyscan();
- uchar n,m,num,t,time;
- bit flag;
- /*---------------------------------------------------
- 主函数
- ---------------------------------------------------*/
- void main (void)
- {
- EA=1;
- TMOD=0x11;
- TH0=(65536-50000)/256;//这是50ms的
- TL0=(65536-50000)%256;
- ET0=1;
- TR0=0;
- TH1=(65536-50000)/256;//这是50ms的
- TL1=(65536-50000)%256;
- ET1=1;
- TR1=1;
- time=97;
- num=0;
- flag=0;
- while (1) //主循环
- {
- TempData[2]=dofly_DuanMa[time/10];//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[3]=dofly_DuanMa[time%10];
- if(num!=0)
- m=1;
- if(start==0)
- {
- DelayMs(10);
- if(start==0)
- {
- flag=1;
- while(!start);
- }
- }
- if(add==0)
- {
- DelayMs(10);
- if(add==0)
- {
- time++;
- while(!add);
- }
- }
- if(jian==0)
- {
- DelayMs(10);
- if(jian==0)
- {
- time--;
- while(!jian);
- }
- }
- if(time>=99)
- time=99;
- if(flag==0)
- {
- if(num!=0)
- m=1;
- keyscan();
- check2();
- }
- if(flag==1)
- {
- TR0=1;
- if(num!=0)
- m=1;
- keyscan();
- check1();
- }
- //主循环中添加其他需要一直工作的程序
- }
- }
- void timer_t0() interrupt 1
- {
- TH0=(65536-50000)/256;//这是50ms的
- TL0=(65536-50000)%256;
- t++;
- beep=0;
- if(t==20)//设置为20,就是1s为高1s为低
- {
- beep=1;
- t=0;
- time--;
- TempData[2]=dofly_DuanMa[time/10];//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[3]=dofly_DuanMa[time%10];
- if(time<=0)
- {
- time=0;
- }
- }
- }
- void timer_t1() interrupt 3
- {
- TH1=(65536-50000)/256;//这是50ms的
- TL1=(65536-50000)%256;
- Display(0,8); //数码管显示函数
- }
- void check1()
- {
- if(num==1)
- {
- TempData[0]=dofly_DuanMa[num/10];//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[1]=dofly_DuanMa[num%10];
- TempData[4]=table[0];
- beep=1;
- Display(0,8); //数码管显示函数
- TR0=0;
- while(m);
- }
- if(num==2)
- {
- TempData[0]=dofly_DuanMa[num/10];//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[1]=dofly_DuanMa[num%10];
- TempData[4]=table[1];
- beep=1;
- Display(0,8); //数码管显示函数
- TR0=0;
- while(m);
- }
- if(num==3)
- {
- TempData[0]=dofly_DuanMa[num/10];//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[1]=dofly_DuanMa[num%10];
- TempData[4]=table[2];
- beep=1;
- Display(0,8); //数码管显示函数
- TR0=0;
- while(m);
- }
- if(num==4)
- {
- TempData[0]=dofly_DuanMa[num/10];//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[1]=dofly_DuanMa[num%10];
- TempData[4]=table[3];
- beep=1;
- Display(0,8); //数码管显示函数
- TR0=0;
- while(m);
- }
- if(num==5)
- {
- TempData[0]=dofly_DuanMa[num/10];//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[1]=dofly_DuanMa[num%10];
- TempData[4]=table[4];
- beep=1;
- Display(0,8); //数码管显示函数
- TR0=0;
- while(m);
- }
- if(num==6)
- {
- TempData[0]=dofly_DuanMa[num/10];//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[1]=dofly_DuanMa[num%10];
- TempData[4]=table[5];
- beep=1;
- Display(0,8); //数码管显示函数
- TR0=0;
- while(m);
- }
- if(num==7)
- {
- TempData[0]=dofly_DuanMa[num/10];//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[1]=dofly_DuanMa[num%10];
- TempData[4]=table[6];
- beep=1;
- Display(0,8); //数码管显示函数
- TR0=0;
- while(m);
- }
- if(num==8)
- {
- TempData[0]=dofly_DuanMa[num/10];//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[1]=dofly_DuanMa[num%10];
- TempData[4]=table[7];
- beep=1;
- Display(0,8); //数码管显示函数
- TR0=0;
- while(m);
- }
- if(num==9)
- {
- TempData[0]=dofly_DuanMa[num/10];//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[1]=dofly_DuanMa[num%10];
- TempData[5]=table[0];
- beep=1;
- Display(0,8); //数码管显示函数
- TR0=0;
- while(m);
- }
- if(num==10)
- {
- TempData[0]=dofly_DuanMa[num/10];//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[1]=dofly_DuanMa[num%10];
- TempData[5]=table[1];
- beep=1;
- Display(0,8); //数码管显示函数
- TR0=0;
- while(m);
- }
- if(num==11)
- {
- TempData[0]=dofly_DuanMa[num/10];//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[1]=dofly_DuanMa[num%10];
- TempData[5]=table[2];
- beep=1;
- Display(0,8); //数码管显示函数
- TR0=0;
- while(m);
- }
- if(num==12)
- {
- TempData[0]=dofly_DuanMa[num/10];//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[1]=dofly_DuanMa[num%10];
- TempData[5]=table[3];
- beep=1;
- Display(0,8); //数码管显示函数
- TR0=0;
- while(m);
- }
- if(num==13)
- {
- TempData[0]=dofly_DuanMa[num/10];//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[1]=dofly_DuanMa[num%10];
- TempData[5]=table[4];
- beep=1;
- Display(0,8); //数码管显示函数
- TR0=0;
- while(m);
- }
- if(num==14)
- {
- TempData[0]=dofly_DuanMa[num/10];//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[1]=dofly_DuanMa[num%10];
- TempData[5]=table[5];
- beep=1;
- Display(0,8); //数码管显示函数
- TR0=0;
- while(m);
- }
- if(num==15)
- {
- TempData[0]=dofly_DuanMa[num/10];//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[1]=dofly_DuanMa[num%10];
- TempData[5]=table[6];
- beep=1;
- Display(0,8); //数码管显示函数
- TR0=0;
- while(m);
- }
- if(num==16)
- {
- TempData[0]=dofly_DuanMa[num/10];//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[1]=dofly_DuanMa[num%10];
- TempData[5]=table[7];
- beep=1;
- Display(0,8); //数码管显示函数
- TR0=0;
- while(m);
- }
- }
- void check2()
- {
- if(num==1)
- {
- TempData[0]=dofly_DuanMa[num/10];//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[1]=dofly_DuanMa[num%10];
- TempData[2]=0x40;//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[3]=0x40;
- TempData[4]=table[0];
- Display(0,8); //数码管显示函数
- TR0=0;
- while(m);
- }
- if(num==2)
- {
- TempData[0]=dofly_DuanMa[num/10];//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[1]=dofly_DuanMa[num%10];
- TempData[2]=0x40;//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[3]=0x40;
- TempData[4]=table[1];
- Display(0,8); //数码管显示函数
- TR0=0;
- while(m);
- }
- if(num==3)
- {
- TempData[0]=dofly_DuanMa[num/10];//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[1]=dofly_DuanMa[num%10];
- TempData[2]=0x40;//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[3]=0x40;
- TempData[4]=table[2];
- Display(0,8); //数码管显示函数
- TR0=0;
- while(m);
- }
- if(num==4)
- {
- TempData[0]=dofly_DuanMa[num/10];//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[1]=dofly_DuanMa[num%10];
- TempData[2]=0x40;//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[3]=0x40;
- TempData[4]=table[3];
- Display(0,8); //数码管显示函数
- TR0=0;
- while(m);
- }
- if(num==5)
- {
- TempData[0]=dofly_DuanMa[num/10];//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[1]=dofly_DuanMa[num%10];
- TempData[2]=0x40;//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[3]=0x40;
- TempData[4]=table[4];
- Display(0,8); //数码管显示函数
- TR0=0;
- while(m);
- }
- if(num==6)
- {
- TempData[0]=dofly_DuanMa[num/10];//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[1]=dofly_DuanMa[num%10];
- TempData[2]=0x40;//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[3]=0x40;
- TempData[4]=table[5];
- Display(0,8); //数码管显示函数
- TR0=0;
- while(m);
- }
- if(num==7)
- {
- TempData[0]=dofly_DuanMa[num/10];//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[1]=dofly_DuanMa[num%10];
- TempData[2]=0x40;//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[3]=0x40;
- TempData[4]=table[6];
- Display(0,8); //数码管显示函数
- TR0=0;
- while(m);
- }
- if(num==8)
- {
- TempData[0]=dofly_DuanMa[num/10];//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[1]=dofly_DuanMa[num%10];
- TempData[2]=0x40;//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[3]=0x40;
- TempData[4]=table[7];
- Display(0,8); //数码管显示函数
- TR0=0;
- while(m);
- }
- if(num==9)
- {
- TempData[0]=dofly_DuanMa[num/10];//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[1]=dofly_DuanMa[num%10];
- TempData[2]=0x40;//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[3]=0x40;
- TempData[5]=table[0];
- Display(0,8); //数码管显示函数
- TR0=0;
- while(m);
- }
- if(num==10)
- {
- TempData[0]=dofly_DuanMa[num/10];//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[1]=dofly_DuanMa[num%10];
- TempData[2]=0x40;//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[3]=0x40;
- TempData[5]=table[1];
- Display(0,8); //数码管显示函数
- TR0=0;
- while(m);
- }
- if(num==11)
- {
- TempData[0]=dofly_DuanMa[num/10];//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[1]=dofly_DuanMa[num%10];
- TempData[5]=table[2];
- Display(0,8); //数码管显示函数
- TR0=0;
- while(m);
- }
- if(num==12)
- {
- TempData[0]=dofly_DuanMa[num/10];//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[1]=dofly_DuanMa[num%10];
- TempData[2]=0x40;//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[3]=0x40;
- TempData[5]=table[3];
- Display(0,8); //数码管显示函数
- TR0=0;
- while(m);
- }
- if(num==13)
- {
- TempData[0]=dofly_DuanMa[num/10];//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[1]=dofly_DuanMa[num%10];
- TempData[2]=0x40;//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[3]=0x40;
- TempData[5]=table[4];
- Display(0,8); //数码管显示函数
- TR0=0;
- while(m);
- }
- if(num==14)
- {
- TempData[0]=dofly_DuanMa[num/10];//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[1]=dofly_DuanMa[num%10];
- TempData[2]=0x40;//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[3]=0x40;
- TempData[5]=table[5];
- Display(0,8); //数码管显示函数
- TR0=0;
- while(m);
- }
- if(num==15)
- {
- TempData[0]=dofly_DuanMa[num/10];//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[1]=dofly_DuanMa[num%10];
- TempData[2]=0x40;//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[3]=0x40;
- TempData[5]=table[6];
- Display(0,8); //数码管显示函数
- TR0=0;
- while(m);
- }
- if(num==16)
- {
- TempData[0]=dofly_DuanMa[num/10];//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[1]=dofly_DuanMa[num%10];
- TempData[2]=0x40;//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[3]=0x40;
- TempData[5]=table[7];
- Display(0,8); //数码管显示函数
- TR0=0;
- while(m);
- }
- }
- void keyscan()
- {
- if(key1==0)
- {
- DelayMs(10);
- if(key1==0)
- {
- num=1;
- while(!key1);
- }
- }
- if(key2==0)
- {
- DelayMs(10);
- if(key2==0)
- {
- num=2;
- while(!key2);
- }
- }
- if(key3==0)
- {
- DelayMs(10);
- if(key3==0)
- {
- num=3;
- while(!key3);
- }
- }
- if(key4==0)
- {
- DelayMs(10);
- if(key4==0)
- {
- num=4;
- while(!key4);
- }
- }
- if(key5==0)
- {
- DelayMs(10);
- if(key5==0)
- {
- num=5;
- while(!key5);
- }
- }
- if(key6==0)
- {
- DelayMs(10);
- if(key6==0)
- {
- num=6;
- while(!key6);
- }
- }
- if(key7==0)
- {
- DelayMs(10);
- if(key7==0)
- {
- num=7;
- while(!key7);
- }
- }
- if(key8==0)
- {
- DelayMs(10);
- if(key8==0)
- {
- num=8;
- while(!key8);
- }
- }
- if(key9==0)
- {
- DelayMs(10);
- if(key9==0)
- {
- num=9;
- while(!key9);
- }
- }
- if(key10==0)
- {
- DelayMs(10);
- if(key10==0)
- {
- num=10;
- while(!key10);
- }
- }
- if(key11==0)
- {
- DelayMs(10);
- if(key11==0)
- {
- num=11;
- while(!key11);
- }
- }
- if(key12==0)
- {
- DelayMs(10);
- if(key12==0)
- {
- num=12;
- while(!key12);
- }
- }
- if(key13==0)
- {
- DelayMs(10);
- if(key13==0)
- {
- num=13;
- while(!key13);
- }
- }
- if(key14==0)
- {
- DelayMs(10);
- if(key14==0)
- {
- num=14;
- while(!key14);
- }
- }
- if(key15==0)
- {
- DelayMs(10);
- if(key15==0)
- {
- num=15;
- while(!key15);
- }
- }
- if(key16==0)
- {
- DelayMs(10);
- if(key16==0)
- {
- num=16;
- while(!key16);
- }
- }
- }
- void DelayUs2x(unsigned char t)
- {
- while(--t);
- }
- void DelayMs(unsigned char t)
- {
- while(t--)
- {
- //大致延时1mS
- DelayUs2x(245);
- DelayUs2x(245);
- }
- }
- void Delay(unsigned char t)
- {
- unsigned char x,y;
- for(x=t;x>0;x--)
- for(y=110;y>0;y--);
- }
- /*------------------------------------------------
- 显示函数,用于动态扫描数码管
- 输入参数 FirstBit 表示需要显示的第一位,如赋值2表示从第三个数码管开始显示
- 如输入0表示从第一个显示。
- Num表示需要显示的位数,如需要显示99两位数值则该值输入2
- ------------------------------------------------*/
- void Display(unsigned char FirstBit,unsigned char Num)
- {
- unsigned char i;
-
- for(i=0;i<Num;i++)
- {
- DataPort=0; //清空数据,防止有交替重影
- DUAN=1; //段锁存
- DUAN=0;
- DataPort=dofly_WeiMa[i+FirstBit]; //取位码
- WEI=1; //位锁存
- WEI=0;
- DataPort=TempData[i]; //取显示数据,段码
- DUAN=1; //段锁存
- DUAN=0;
- DelayMs(2); // 扫描间隙延时,时间太长会闪烁,太短会造成重影
- }
- }
复制代码
全部资料51hei下载地址:
16路抢答器.zip
(270.95 KB, 下载次数: 275)
|