//包含头文件
#include<reg51.h>
#include <intrins.h>
//宏定义
#define uchar unsigned char
#define uint unsigned int
#include "eeprom52.h" //信息存储位置的头文件
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 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
//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;
sbit beep=P3^6; //蜂鸣器
bit qd; //抢答标志位,=1时开启抢答
bit dt; //答题标志位,=1时开启答题
bit disp_qd_dt; //显示抢答还是答题时间标志位,=0时是显示抢答时间,=1时是显示答题时间
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();
}
没有合适的资源?快使用搜索试试~ 我知道了~
基于51单片机的八路抢答器.rar
共26个文件
bak:5个
rar:2个
obj:2个
需积分: 5 0 下载量 24 浏览量
2024-01-30
14:01:00
上传
评论
收藏 130KB RAR 举报
温馨提示
代码+仿真
资源推荐
资源详情
资源评论
收起资源包目录
基于51单片机的八路抢答器.rar (26个子文件)
基于51单片机的八路抢答器
仿真.rar 19KB
单片机代码+详细注释.rar 45KB
单片机代码+详细注释
qdq_Uv2.Bak 2KB
qdq_uvopt.bak 57KB
qdq.uvopt 57KB
抢答器.LST 29KB
STARTUP.LST 14KB
抢答器.OBJ 21KB
STARTUP.A51 6KB
qdq 19KB
qdq.plg 373B
qdq.hex 3KB
qdq.Uv2.bak 2KB
eeprom52.h 3KB
抢答器.__i 36B
qdq.uvproj 13KB
qdq.M51 28KB
STARTUP.OBJ 749B
抢答器.c 9KB
qdq_Opt.Bak 1KB
qdq.lnp 42B
qdq.opt.bak 1KB
仿真
八路抢答器.hex 3KB
抢答器.PWI 742B
抢答器.pdsprj.LAPTOP-40E75LS2.92831.workspace 328B
抢答器.DSN 99KB
共 26 条
- 1
资源评论
时光の尘
- 粉丝: 3967
- 资源: 203
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功