|
- //包含头文件
- #include<reg51.h>
- #include <intrins.h>
- //宏定义
- #define uchar unsigned char
- #define uint unsigned int
- #include "eeprom52.h"
- sbit start=P3^0; //主持人按键开始
- sbit reset=P3^1; //复位
- sbit add1=P3^2; //抢答时间调整,加1
- sbit dec1=P3^3; //抢答时间调整,减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时开启答题
- bit disp_qd_dt; //显示抢答还是答题时间标志位,=0时是显示抢答时间,=1时是显示答题时间
- //uchar code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77}; //0-9代码
- unsigned char code tab[]={0x5F,0x44,0x9D,0xD5,0xC6,0xD3,0xDB,0x45,0xDF,0xD7, 0xCE,0xC7,0xDC}; //数字0-9的编码 和H q d
- uchar shiwei,gewei,xuanshou,count,p,second;
- uchar qd_time,dt_time; //抢答时间,答题时间
- uint t,m,n,a,a1,a2,a3,a4,a5,a6,a7,a8;
- void Timer()
- {
- TMOD=0x01; //定义工作方式
- TH0=0x3C; //初值15536,计数50000次,每次1uS,总计50ms
- TL0=0xB0;
- IE=0x82; //这里是中断优先级控制EA=1(开总中断),ET0=1(定时器0允许中断),这里用定时器0来定时
- TR0=0; //开启定时器定时
- }
- void tim(void) interrupt 1 using 1 //为定时中断T0
- {
- TH0=0x3C; //重新赋值
- TL0=0xB0;
- TR0=1;
- count++; //计数一次时50ms,20次为1s
- if((second<=10)&&(count==10)&&(dt==1)) //计时到500ms时,根据需要蜂鸣器闪烁
- beep=0;
- if(count==20) //20*50ms=1秒
- {
- count=0;
- if(second>=1)
- second--; //秒减1
- else
- TR0=0;
- if((second<=10)&&(dt==1)) //当秒见到10以下时,控制蜂鸣器闪烁鸣响
- beep=1;
- }
- }
- void delay(uint z) //延时函数
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--); //约1ms
- }
- /******************把数据保存到单片机内部eeprom中******************/
- void write_eeprom()
- {
- SectorErase(0x2000);
- byte_write(0x2000, qd_time);
- byte_write(0x2001, dt_time);
- byte_write(0x2060, a_a);
- }
- /******************把数据从单片机内部eeprom中读出来*****************/
- void read_eeprom()
- {
- qd_time = byte_read(0x2000);
- dt_time = byte_read(0x2001);
- a_a = byte_read(0x2060);
- }
- /**************开机自检eeprom初始化*****************/
- void init_eeprom()
- {
- read_eeprom(); //先读
- if(a_a != 1) //新的单片机初始单片机内问eeprom
- {
- qd_time = 30;
- dt_time = 60;
- a_a = 1;
- write_eeprom(); //保存数据
- }
- }
- void display (void) //显示函数
- {
- unsigned char shiwei,gewei,xuanshou;
- shiwei=tab[second/10]; //将秒数据拆开成两个一位数
- gewei=tab[second%10];
- xuanshou=tab[p];
- P0=gewei; //送入P0口的gewei数据
- P2=0x7F; //个位位选
- delay(5); //延时5ms
- 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; //显示q 代表抢答时间设置
- disp_qd_dt=0; //显示抢答时间
- qd_time++; //抢答时间加
- if(qd_time>=99) //最大值可以加到99
- qd_time=99;
- }
- second=qd_time; //将抢答时间赋值秒数据,用于计时
- do
- display(); //调用显示函数
- while(add1==0); //按键释放
- write_eeprom(); //保存数据
- }
- if(dec1==0) //键按键是否按下
- {
- display(); //用显示函数代替延时去抖,防止按下按键时屏幕的闪烁
- if(dec1==0) //再次判断按键是否按下
- {
- p=11; //显示q
- disp_qd_dt=0; //标志位置0
- qd_time--; //抢答时间减
- if(qd_time<=1) //时间减最低值1
- qd_time=1;
- }
- second=qd_time; //将抢答时间赋值秒,用于倒计时
- do
- display(); //调用显示函数
- while(dec1==0); //按键释放
- write_eeprom(); //保存数据
- }
- if(add2==0) //答题时间设置参照抢答时间设置部分注释
- {
- display();
- if(add2==0)
- {
- p=12;
- disp_qd_dt=1;
- dt_time++;
- if(dt_time>=99)
- dt_time=99;
- }
- second=dt_time;
- do
- display();
- while(add2==0);
- write_eeprom(); //保存数据
- }
- if(dec2==0)
- {
- display();
- if(dec2==0)
- {
- p=12;
- disp_qd_dt=1;
- dt_time--;
- if(dt_time<=1)
- dt_time=1;
- }
- second=dt_time;
- do
- display();
- while(dec2==0);
- write_eeprom(); //保存数据
- }
- }
- void init() //初始化函数
- {
- t=0;
- beep=1;
- p=10; //选手号初始为显示H,表示等待
- second=qd_time; //将抢答时间赋值秒
- }
- void main() //主函数
- {
- uchar i;
- init_eeprom(); //开始初始化保存的数据
- init(); //调用初始化函数
- Timer(); //定时器设置
- while(1) //循环
- {
- if((qd==0)&&(dt==0))
- keyscan(); //扫描按键
- display(); //显示函数
- if(start==0) //主持人按下开始键
- {
- if((qd==0)&&(dt==0)) //在非抢答,非答题状态下
- {
- p=10; //显示H
- disp_qd_dt=0; //标志位置0
- second=qd_time; //抢答时间赋值秒
- qd=1; //开始抢答
- }
- beep=0; //蜂鸣器长响一声
- for(i=0;i<20;i++) //此处用于延时
- {
- display();
- }
- beep=1; //关闭蜂鸣器
- TR0=~TR0; //定时器开关取反(就是一个开关,按一个就计时,再按一下就停止)
- do
- display(); //调用显示函数
- while(!start); //等待释放按键
- }
- if(reset==0) //复位按键按下时
- {
- display(); //显示函数用做延时去抖
- if(reset==0) //再次判断按键是否按下
- {
- disp_qd_dt=0; //标志位置0
- second=qd_time;
- t=0;
- p=10; //显示H
- TR0=0; //停止计时
- beep=1;
- qd=0;
- dt=0; //停止抢答和答题计时
- }
- do
- display();
- while(!reset);
- }
- if(qd==1) //开始抢答后,才检测选手按键的状态
- {
- if(k1==0) //1号选手按下时
- {
- display(); //显示函数用作延时去抖
- if(k1==0) //再次判断按键是否按下
- {
- t=1; //抢答序号置1
- qd=0; //停止抢答,该位置0后,选手按键按下无效
- dt=1; //准备答题
- }
- }
- else if(k2==0) //其他选手按键扫描参考1号选手按键注释
- {
- display();
- if(k2==0)
- {
- t=2;
- qd=0;
- dt=1;
- }
- }
- else if(k3==0)
- {
- display();
- if(k3==0)
- {
- t=3;
- qd=0;
- dt=1;
- }
- }
- else if(k4==0)
- {
- display();
- if(k4==0)
- {
- t=4;
- qd=0;
- dt=1;
- }
- }
- else if(k5==0)
- {
- display();
- if(k5==0)
- {
- t=5;
- qd=0;
- dt=1;
- }
- }
- else if(k6==0)
- {
- display();
- if(k6==0)
- {
- t=6;
- qd=0;
- dt=1;
- }
- }
- else if(k7==0)
- {
- display();
- if(k7==0)
- {
- t=7;
- qd=0;
- dt=1;
- }
- }
- else if(k8==0)
- {
- display();
- if(k8==0)
- {
- t=8;
- qd=0;
- dt=1;
- }
- }
- if(t) //有选手按下按键时,t的值不为0,进入此if语句
- {
- switch(t) //判断t的值
- {
- case 1: //t的值为1时,就是选手1按下按键
- {
- TR0=0; //停止计时
- p=1; //数码管显示选手号码
- second=dt_time; //答题时间赋值秒
- beep=0; //蜂鸣器响
- for(i=0;i<20;i++) //此处用于延时
- {
- display();
- }
- beep=1; //蜂鸣器延时后关闭
- qd=0;break; //qd置0,抢答环节结束,跳出switch语句
- }
- case 2: //t为2时就是2号选手按下按键
- {
- TR0=0; //以下参考1号选手注释/|\即可
- p=2;
- second=dt_time;
- beep=0;
- for(i=0;i<20;i++)
- {
- display();
- }
- beep=1;
- qd=0;break;
- }
- case 3:
- {
- TR0=0;
- p=3;
- second=dt_time;
- beep=0;
- for(i=0;i<20;i++)
- {
- display();
- }
- beep=1;
- qd=0;break;
- }
- case 4:
- {
- TR0=0;
- p=4;
- second=dt_time;
- beep=0;
- for(i=0;i<20;i++)
- {
- display();
- }
- beep=1;
- qd=0;break;
- }
- case 5:
- {
- TR0=0;
- p=5;
- second=dt_time;
- beep=0;
- for(i=0;i<20;i++)
- {
- display();
- }
- beep=1;
- qd=0;break;
- }
- case 6:
- {
- TR0=0;
- p=6;
- second=dt_time;
- beep=0;
- for(i=0;i<20;i++)
- {
- display();
- }
- beep=1;
- qd=0;break;
- }
- case 7:
- {
- TR0=0;
- p=7;
- second=dt_time;
- beep=0;
- for(i=0;i<20;i++)
- {
- display();
- }
- beep=1;
- qd=0;break;
- }
- case 8:
- {
- TR0=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;
- TR0=1; //开启定时器计时答题时间
- }
- }
- }
- }
- if(second==0) //为0时报警
- {
- beep=0; //蜂鸣器报警
- qd=0;
- dt=0; //抢答和答题标志清零
- }
- }
- }
复制代码 |
|