十四路抢答器原理图 Altium Designer画的(51hei附件中可下载工程文件):
单片机抢答器代码如下:
- #include<reg51.h>
- #define uchar unsigned char
- #define uint unsigned int
- sbit start=P3^0; //主持人按键开始
- sbit reset=P3^1; //复位
- //sbit m1=P3^1; //主持人按键答对加分,按一下加一分
- //sbit m2=P3^2; //答错减分
- sbit add1=P3^2; //抢答时间调整,加1
- sbit dec1=P3^7; //抢答时间调整,减1
- sbit add2=P3^4; //答题时间调整,加1
- sbit dec2=P3^5; //答题时间调整,减1
- sbit k1=P1^0;
- sbit k2=P1^1;
- sbit k3=P1^2;
- sbit k4=P1^3;
- sbit k5=P1^4;
- sbit k6=P1^5;
- sbit k7=P1^6;
- sbit k8=P1^7; //选手按键
- sbit beep=P3^6; //蜂鸣器
- bit qd; //抢答标志位,=1时开启抢答
- bit dt; //答题标志位,=1时开启答题
- //时间计算
- #define Imax 14000 //此处为晶振为11.0592时的取值,
- #define Imin 8000 //如用其它频率的晶振时,
- #define Inum1 1450 //要改变相应的取值。
- #define Inum2 700
- #define Inum3 3000
- //解码变量
- unsigned char Im[4]={0x00,0x00,0x00,0x00};
- //全局变量
- uchar f;
- unsigned long m,Tc;
- unsigned char IrOK;
- //uchar code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77}; //0-9代码 abcdefg dp
- unsigned char code tab[]={0x5F,0x44,0x9D,0xD5,0xC6,0xD3,0xDB,0x45,0xDF,0xD7,0xCE,0xC7,0xDC}; //数字0-9的编码 G C DP D E B F A
- uchar shiwei,gewei,xuanshou,count,p,second;
- uchar qd_time=30,dt_time=60; //抢答时间,默认30S,答题时间,默认60S
- uint t,n,a,a1,a2,a3,a4,a5,a6,a7,a8;
- void Timer()
- {
- TMOD=0x11;
- TH1=0x3C; //初值50ms
- TL1=0xB0;
- EA=1; //打开中断总开关
- ET1=1; //打开中断允许开关
- TR1=0; //打开定时开关
- IT1=1;//下降沿有效
- EX1=1;//外部中断1开
- TH0=0;//T0赋初值
- TL0=0;
- TR0=0;//t0暂时不计时,等到有红外信号时开启计时
- }
- void delay(uint z) //延时函数
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--); //约1ms
- }
- void display (void) //显示函数
- {
- unsigned char shiwei,gewei,xuanshou;//定义数据变量,用于显示时间和选手号码
- shiwei=tab[second/10]; //秒取十位数
- gewei=tab[second%10]; //取个位数
- xuanshou=tab[p]; //选手号
- P0=gewei; //个位数据显示
- P2=0x7F; //打开位选
- delay(5); //延时一会
- P2=0xFF; //关闭显示
- P0=shiwei; //显示十位
- P2=0xBF; //打开显示时间十位的位选
- delay(5); //延时一会
- P2=0xFF; //关闭显示
- P0=0x80; //显示横线
- P2=0xDF;
- delay(5);
- P2=0xFF;
-
- P0=xuanshou;
- P2=0xEF; //选手位选
- delay(5);
- P2=0xFF;
- }
- void keyscan(void) //按键函数
- {
- if(add1==0) //抢答加按键按下
- {
- display(); //显示函数当做去抖用,防止按键按下时黑屏
- if(add1==0) //再次判断抢答加按键是否按下(其他按键功能类似)
- {
- p=11; //P=11,显示q
- qd_time++; //抢答时间加
- if(qd_time>=99) //最大加到99
- qd_time=99;
- }
- second=qd_time; //将抢答时间赋值给计时变量
- do
- display(); //扫描显示
- while(add1==0);
- }
- if(dec1==0) //抢答时间减按键
- {
- display();
- if(dec1==0)
- {
- p=11; //显示q
- qd_time--; //时间减
- if(qd_time<=1) //最小减到1
- qd_time=1;
- }
- second=qd_time;
- do
- display();
- while(dec1==0);
- }
- if(add2==0)
- {
- display();
- if(add2==0)
- {
- p=12;
- dt_time++;
- if(dt_time>=99)
- dt_time=99;
- }
- second=dt_time;
- do
- display();
- while(add2==0);
- }
- if(dec2==0)
- {
- display();
- if(dec2==0)
- {
- p=12;
- dt_time--;
- if(dt_time<=1)
- dt_time=1;
- }
- second=dt_time;
- do
- display();
- while(dec2==0);
- }
- }
- void init() //初始化函数
- {
- P2=0x04;
- P0=0x3f;
- t=0;
- beep=1;
- p=10; //选手号初始为显示H,表示等待
- second=qd_time;
- }
- void main()
- {
- uchar i;
- init(); //调用初始化函数
- Timer(); //定时器设置
- while(1)
- {
- if((qd==0)&&(dt==0)) //在非抢答,非答题状态下
- keyscan(); //按键扫描函数
- display(); //显示函数
- if(start==0) //主持人按下开始键
- {
- if((qd==0)&&(dt==0)) //在非抢答,非答题状态下
- {
- p=10; //数码管显示H
- second=qd_time; //抢答时间赋值计时变量
- qd=1; //进入抢答模式
- }
- beep=0; //蜂鸣器长响一声
- for(i=0;i<20;i++) //此处用做延时
- {
- display();
- }
- beep=1; //关闭蜂鸣器
- TR1=~TR1; //定时器取反,可以开始,可以随时暂停
- do
- display(); //显示函数
- while(!start); //等待释放按键
- }
- if(reset==0) //复位键按下
- {
- display();
- if(reset==0)
- {
- second=qd_time; //将抢答时间赋值给计时变量
- t=0; //清零
- p=10; //显示H
- TR1=0; //停止计时
- beep=1; //蜂鸣器停止
- qd=0; //抢答清零
- dt=0; //答题清零
- }
- do
- display(); //显示函数
- while(!reset); //按键释放
- }
- if(qd==1) //如果是抢答模式时
- {
- {
- if(k1==0) //一号选手按下按键
- {
- display();
- if(k1==0)
- display();
- t=1; //选手号置1
- qd=0; //关闭抢答模式
- dt=1; //准备打开答题模式(其他选手注释相同)
- }
- else if(k2==0)
- {
- display();
- if(k2==0)
- display();
- t=2;
- qd=0;
- dt=1;
- }
- else if(k3==0)
- {
- display();
- if(k3==0)
- display();
- t=3;
- qd=0;
- dt=1;
- }
- else if(k4==0)
- {
- display();
- if(k4==0)
- display();
- t=4;
- qd=0;
- dt=1;
- }
- else if(k5==0)
- {
- display();
- if(k5==0)
- display();
- t=5;
- qd=0;
- dt=1;
- }
- else if(k6==0)
- {
- display();
- if(k6==0)
- display();
- t=6;
- qd=0;
- dt=1;
- }
- else if(k7==0)
- {
- display();
- if(k7==0)
- display();
- t=7;
- qd=0;
- dt=1;
- }
- else if(k8==0)
- {
- display();
- if(k8==0)
- display();
- t=8;
- qd=0;
- dt=1;
- }
- if(IrOK==1) //有红外信号时
- {
- //1键
- if(Im[2]==0x0c) //是1号按下
- {
- display();
- t=1; //选手号置1
- qd=0; //关闭抢答模式
- dt=1; //准备打开答题模式(其他选手注释相同)
- }
- //2键
- else if(Im[2]==0x18)
- {
- display();
- t=2;
- qd=0;
- dt=1;
- }
- //3键
- else if(Im[2]==0x5e)
- {
- display();
- t=3;
- qd=0;
- dt=1;
- }
- //4键
- else if(Im[2]==0x08)
- {
- display();
- t=4;
- qd=0;
- dt=1;
- }
- //5键
- else if(Im[2]==0x1c)
- {
- display();
- t=5;
- qd=0;
- dt=1;
- }
- //6键
- else if(Im[2]==0x5a)
- {
- display();
- t=6;
- qd=0;
- dt=1;
- }
- //7键
- else if(Im[2]==0x42)
- {
- display();
- t=7;
- qd=0;
- dt=1;
- }
- //8键
- else if(Im[2]==0x52)
- {
- display();
- t=8;
- qd=0;
- dt=1;
- }
- IrOK=0; //红外检测完后将变量清零
- }
- }
- if(t) //t不为0时
- {
- switch(t) //判断t的数值
- {
- case 1: //数值为1时
- {
- TR1=0; //关闭定时器
- p=1; //显示1
- second=dt_time; //答题时间赋值给计时变量
- beep=0; //蜂鸣器响
- for(i=0;i<20;i++) //延时
- {
- display();
- }
- beep=1; //蜂鸣器停止
- qd=0;break; //抢答模式关闭(其他选手注释相同)
- }
- case 2:
- {
- TR1=0;
- p=2;
- second=dt_time;
- beep=0;
- for(i=0;i<20;i++)
- {
- display();
- }
- beep=1;
- qd=0;break;
- }
- case 3:
- {
- TR1=0;
- p=3;
- second=dt_time;
- beep=0;
- for(i=0;i<20;i++)
- {
- display();
- }
- beep=1;
- qd=0;break;
- }
- case 4:
- {
- TR1=0;
- p=4;
- second=dt_time;
- beep=0;
- for(i=0;i<20;i++)
- {
- display();
- }
- beep=1;
- qd=0;break;
- }
- case 5:
- {
- TR1=0;
- p=5;
- second=dt_time;
- beep=0;
- for(i=0;i<20;i++)
- {
- display();
- }
- beep=1;
- qd=0;break;
- }
- case 6:
- {
- TR1=0;
- p=6;
- second=dt_time;
- beep=0;
- for(i=0;i<20;i++)
- {
- display();
- }
- beep=1;
- qd=0;break;
- }
- case 7:
- {
- TR1=0;
- p=7;
- second=dt_time;
- beep=0;
- for(i=0;i<20;i++)
- {
- display();
- }
- beep=1;
- qd=0;break;
- }
- case 8:
- {
- TR1=0;
- p=8;
- second=dt_time;
- beep=0;
- for(i=0;i<20;i++)
- {
- display();
- }
- beep=1;
- qd=0;break;
- }
-
- }
- }
- if(dt==1) //答题标志开启时
- {
- if(start==0) //进入答题模式后,主持人按下开始按键,则开始计时答题时间
- {
- display();
- if(start==0)
- {
- beep=0; //蜂鸣器响
- for(i=0;i<20;i++) //延时
- {
- display();
- }
- beep=1; //关闭蜂鸣器
- TR1=1; //打开定时器
- }
- }
- }
- }
- if(second==0) //计时到0时报警
- {
- beep=0; //打开蜂鸣器
- qd=0; //关闭抢答模式
- dt=0; //关闭答题模式
- }
- }
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
代码:
抢答器.zip
(52.11 KB, 下载次数: 14)
原理图:
http://www.51hei.com/bbs/dpj-87167-1.html
|