时间有限,用数码管显示8路抢答
用定时器进行8路扫描,间隔可以调十分小
此外,具有设置时间的功能(抢答和答题时间)
8路抢答器仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include<reg52.h>
- #include<intrins.h>
- void Setsecond();//抢答器答题和抢答时间的设置函数声明
- void delay(int k); //延时函数声明
- //数码管选管位
- sbit Sel1=P2^0;
- sbit Sel2=P2^1;
- sbit Sel3=P2^2;
- sbit Sel4=P2^3;
- sbit Sel5=P2^4;
- sbit Sel6=P2^5;
- //抢答器的状态指示灯
- sbit led=P2^6; //显示复位和设置时间的状态
- sbit Led1=P3^1; //抢答失败时,该灯会一直闪烁
- sbit Led2=P3^2; //答题完毕时,该灯会一直闪烁
- //抢答器初始化抢答和答题时间按键
- sbit Set1=P3^3; //设置抢答时间,+
- sbit Set2=P3^4; //设置抢答时间,-
- sbit Set3=P3^5; //设置答题时间,+
- sbit Set4=P3^6; //设置答题时间,-
- sbit RST=P2^7; //抢答器的复位按键
- sbit EN=P3^0; //抢答器使能和设置抢答和答题时间按键
- unsigned char Tshu1=11,Tshu2=31,shu1=11,shu2=31,shu;//抢答器抢答时间和答题时间的相关变量
- unsigned char count0=0,count1=0,roberflag=0,scond1=0,second2=0,robernum=0;//抢答者的相关变量
- unsigned char Shuma[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//数码管段码值
- bit Enflag=0; //抢答器使能的工作标志变量,0表示正常工作,1表示设置时间(抢答和答题)
- void main() //主函数
- {
- unsigned char n=0;
- TMOD=0x11;Led1=0;Led2=0;
- TH0=(2^16-50000)/2^8;TL0=(2^16-50000)%2^8;
- TH1=(2^16-50000)/2^8;TL1=(2^16-50000)%2^8;
- TR0=1;ET0=1;TR1=1;ET1=1;EA=1;
- while(1)
- {
- for(n=0;n<6;n++) //这个循环,实现数码管的动态显示
- {
- switch(n)
- {
- case 0:Sel1=1,Sel2=0,Sel3=0,Sel4=0,Sel5=0,Sel6=0;
- if(Enflag == 0)
- P0=~Shuma[shu/10];
- else
- P0=~Shuma[shu1/10];break;
- case 1:Sel1=0,Sel2=1,Sel3=0,Sel4=0,Sel5=0,Sel6=0;
- if(Enflag == 0)
- P0=~Shuma[shu%10];
- else
- P0=~Shuma[shu1%10];break;
- case 2:Sel1=0,Sel2=0,Sel3=1,Sel4=0,Sel5=0,Sel6=0;P0=0xBF;break;
- case 3:Sel1=0,Sel2=0,Sel3=0,Sel4=1,Sel5=0,Sel6=0;P0=0xBF;break;
- case 4:Sel1=0,Sel2=0,Sel3=0,Sel4=0,Sel5=1,Sel6=0;
- if(Enflag == 0)
- P0=~Shuma[robernum/10];
- else
- P0=~Shuma[shu2/10];break;
- case 5:Sel1=0,Sel2=0,Sel3=0,Sel4=0,Sel5=0,Sel6=1;
- if(Enflag == 0)
- P0=~Shuma[robernum%10];
- else
- P0=~Shuma[shu2%10];break;
- }
- delay(20);
- P0=0xff;
- }
- }
- }
- void delay(int k) //延时函数,主要是为了数码管的动态显示
- {
- while(k--);
- }
- void Timer0() interrupt 1 //定时器0,主要用于各种按键的扫描,每200ms一次
- {
- TH0=(2^16-50000)/2^8;TL0=(2^16-50000)%2^8;
- count0++;
- P1=0x00;
- if(count0 == 5)
- {
- count0=0;
- Setsecond(); //调用设置时间函数,检测是否有设置时间的动作
- if(RST == 0) //检测是否有复位动作,有动作,则实现部分变量初始化值
- {
- roberflag=0;
- robernum=0;shu=0;
- led=~led;Led1=0;Led2=0;
- shu1=Tshu1;shu2=Tshu2;
- }
- if(EN == 0)
- {
- Enflag=~Enflag;
- led=~led;Led1=0;Led2=0;
- }
- if(Enflag == 0) //正常工作时候的,抢答人号码的识别和显示(同时判断8口,不准次扫描,无优先级)
- {
- if(P1 != 0x00)
- {
- if(roberflag == 0) //只有在抢答时间才能抢答,roberflag=0表示抢答,1答题,2抢答失败,3答题完毕
- {
- roberflag++;
- switch(P1)
- {
- case 0x01:robernum=1;break;
- case 0x02:robernum=2;break;
- case 0x04:robernum=3;break;
- case 0x08:robernum=4;break;
- case 0x10:robernum=5;break;
- case 0x20:robernum=6;break;
- case 0x40:robernum=7;break;
- case 0x80:robernum=8;break;
- default:break;
- }
- }
- }
- }
- }
- }
- void Timer1() interrupt 3 //定时器1主要是用于工作时的数码显示,跑表,1一秒刷新一次
- {
- TH1=(2^16-50000)/2^8;TL1=(2^16-50000)%2^8;
- if(roberflag == 2)
- Led1=~Led1;
- if(roberflag == 3)
- Led2=~Led2;
- count1++;
- if(count1 == 20) //正常工作时候的跑表
- {
- if(Enflag == 0)
- {
- if(roberflag == 0) //抢答时间的跑表
- {
- shu1--;
- shu = shu1;
- }
- if(roberflag == 1) //答题时间的跑表
- {
- shu2--;
- shu = shu2;
- }
- if(shu1 == 0)
- roberflag=2;
- if(shu2 == 0)
- roberflag=3;
- }
- count1=0;
- }
- }
- void Setsecond() //抢答时间和答题时间设置函数,也是被T0调用,实现设置时间功效。
- {
- if(Enflag == 1)
- {
-
- if( Set1 == 0)
- {
- Tshu1++;
- }
- if(Set2 == 0)
- {
- Tshu1--;
- }
- if(Set3 == 0)
- {
- Tshu2++;
- }
- if(Set4 == 0)
- {
- Tshu2--;
- }
- shu1=Tshu1; //Tshu1,Tshu2的出现是为了实现设置的抢答和答题时间具有存储功能,不随跑表而发生变化
- shu2=Tshu2;
- }
- }
复制代码
所有资料51hei提供下载:
RoberAck.rar
(18.17 KB, 下载次数: 131)
|