用八路抢答器实现 1、4、6按下后,裁判键按下不能复位。 1、4、6的复位需要关断电源开关后约20秒 少于20秒重新开电源时,仍显示146 2、3、5、8、0正常 7无法自锁。
单片机源程序如下:
- #include <reg51.h>
- #define LED P2 //宏定义,使用LED代替P3口(相当于LED=P3)
- #define uchar unsigned char //用uchar代替unsigned char方便操作
- #define uint unsigned int
- sbit beep=P2^7;//蜂鸣器
- sbit BG=P3^7;//指示灯
- sbit key4=P1^0;//按键D
- sbit key2=P1^1;//按键B
- sbit key1=P1^2;//按键A
- sbit key3=P1^3;//按键C
- bit time_over=0;//倒计时结束标记
- bit WARNING=0;//倒数十秒控制变量
- bit INT_ON=0;//中断标记
- bit key_down=0;//键盘辅助变量
- uchar RIGHT=0xff;//按键暂存器
- uchar CONT=0; //定时器辅助变量
- uchar res_time=0;//时间
- uchar set_time=30;
- uchar leds[17]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,
- 0x90,0x88,0x83,0xa7,0xa1,0x86,0x8e,0xff};
- /*------------------time ms延时函数-----------------*/
- void delay_ms(uint time)
- {
- uchar tres;
- for(;time>0;time--)
- {
- tres=150;
- while(tres--);
- }
- }
- //外部中断1初始化程序
- void Init_Sys() //中断初始化函数
- {
- TCON=0x00; //外部中断1低电平触发
- TMOD=0X01; //定时器0方式1
- IE=0x86; //开启外部中断1,定时器中断0,及总中断 10000110B
- IP=0X04; //外部中断优先级高于定时器
- CONT=0; //时间清零
- res_time=0;
- }
- //外部中断1处理程序
- void exint1_int() interrupt 2 using 0
- {
- uchar t=200;
- EA=0;//关中断
- TR0=0;//关定时器
- WARNING=0;//关警告
- while(t--)beep=0;//软件延时,消除抖动
- RIGHT=P0; //获得按键值
- INT_ON=1; //标记中断
- }
- //定时器0中断处理程序
- void count_int() interrupt 1 using 1
- {
- TH0=0X4C;//重新装载
- TL0=0X00;
- CONT++;
- if(CONT==20)
- {
- CONT=0;
- if(res_time==0)time_over=1;
- res_time--;
- }
- }
- //遥控按键扫描程序
- uchar key_scan(void)
- {
- P1=0xff;
- if(key1==1||key2==1||key3==1||key4==1)
- {
- if(!key_down)
- {
- delay_ms(10); //延时
- key_down=1; //限制
- if(key1==1)return 1;//按键A
- if(key2==1)return 2;//按键B
- if(key3==1)return 3;//按键C
- if(key4==1)return 4;//按键D
- }
- else return 0;
- }
- else if(key_down)key_down=0;//消除限制
- return 0; //未获得任何按键
- }
- uchar juder(void)
- {
- switch(RIGHT)
- {
- case 0xff:return 0;
- case 0xfe:return 1;
- case 0xfd:return 2;
- case 0xfb:return 3;
- case 0xf7:return 4;
- case 0xef:return 5;
- case 0xdf:return 6;
- case 0xbf:return 7;
- case 0x7f:return 8;
- default:return 14;//E,错误
- }
- }
- //显示答案
- void show_answer(void)
- {
- uchar ti=0;
- uchar key=0;
- while(1)
- {
- key=key_scan();
- if(ti==100){BG=!BG;ti=0;}
- if(key!=0)
- {
- LED=leds[key+9];//显示答案
- BG=1;//灭灯
- break;
- }
- ti++;
- delay_ms(1);
- }
- }
- void BELL(uchar times)
- {
- while(times--)
- {
- beep=0;
- delay_ms(100);
- beep=1;
- delay_ms(100);
- }
- }
- //清除显示
- void clear(void)
- {
- EA=0; //关掉计时器
- beep=0; //开蜂鸣器
- WARNING=0; //清警告标记
- time_over=0;//清溢出标记
- TR0=0; //关定时器
- INT_ON=0;//清除中断标记
- TL0=0X00;//初始值设置
- TH0=0X4C;
- CONT=0;
- res_time=set_time;//赋初始值
- delay_ms(100);
- LED=leds[16];//清屏,同时关蜂鸣器
- BG=1;//关灯
- }
- void debug(void)//处理犯规队,显示犯规队队号
- {
- RIGHT=P0;//获得犯规队的地址
- LED=leds[juder()];//显示队号
- BELL(4);
- }
- //开启抢答器
- //1普通模式
- //0倒计时模式
- void start(uchar type)
- {
- bit alarm=1;//提示音
- uchar key=0;
- res_time=set_time;//获取初始值
- while(1)
- {
- key=key_scan();//扫描键盘
- if(key!=0)
- {
- switch(key)
- {
- case 1://显示答案
- {
- clear();//清除
- show_answer();
- break;
- }
- case 2://开始抢答
- {
- if(P0!=0XFF)
- {
- debug();//处理犯规
- break;
- }
- if(!type)TR0=1; //倒计时方式
- else //普通方式
- {
- clear();
- BG=0;//开灯指示
- }
- EA=1;//使能中断
- break;
- }
- case 3:clear();break;//清除
- case 4:return;//返回
- }
- }
- if(TR0==1)//倒计时
- {
- if(CONT==0&&BG)
- {
- if(res_time>=10)LED=leds[res_time/10];
- BG=0;//每秒钟闪烁一次
- if(WARNING)alarm=0;//最后十秒
- }
- if(CONT==10&&!BG)
- {
- BG=1;
- if(WARNING)alarm=1;//最后十秒
- else LED=leds[res_time%10];//显示个位数据;
- }
- if(res_time<10)//最后十秒标记
- {
- WARNING=1;
- LED=leds[res_time];
- }
- beep=alarm;
- delay_ms(5);
- }
- if(time_over) //倒计时结束处理
- {
- clear();
- LED=leds[0];
- time_over=0;
- BELL(3);
- }
- if(INT_ON)//有选手按下
- {
- TR0=0;//关定时器
- beep=0;//开提示音
- BG=1;//关灯
- delay_ms(100);
- INT_ON=0;
- LED=leds[juder()];//显示选手号
- }
- }
- }
- void main()
- {
- bit set=0;//设置状态标记
- bit model=1; //模式标记
- uchar key;
- Init_Sys();//初始化外部中断 1 捕获按键输入
- P0=0XFF;
- TR0=1;//开启定时器0
- while(1)//死循环
- {
- key=key_scan();
- if(key!=0)
- {
- if(!model)switch(key)
- {
- case 1:
- {
- set=1;
- set_time+=10;
- if(set_time>90)set_time=10;
- break;
- }
- case 3:
- {
- set=1;
- if(set_time>10)set_time-=10;//范围限制
- else set_time=90;
- break;
- }
- }
- if(key==2)
- {
- start(model);//开始抢答
- set=0;//非设置状态
- }
- if(key==4)
- {
- model=!model;//模式切换
- set=0; //非设置状态
- }
- }
- if(model)LED=leds[14];
- else
- {
- if(set)LED=leds[set_time/10];//显示设置时间
- else LED=leds[15];
- }
- }
- }
复制代码
所有资料51hei提供下载:
抢答器.rar
(1.01 MB, 下载次数: 7)
|