标题:
51单片机八路抢答器代码与Proteus仿真
[打印本页]
作者:
845464672
时间:
2022-10-15 21:31
标题:
51单片机八路抢答器代码与Proteus仿真
8路抢答器设计难度分:9基本要求:8个选手抢答按键,1个主持人按键,4只LED数码管显示。系统复位状态LED显示“00 00”;主持人按下按键则抢答开始,系统显示3秒抢答时间倒计时,计时到无人抢答则系统发出报警后自动复位;8个选手最先按下者抢答成功,显示选手编号和答题时间10秒,支持人发出开始作答指令同时按下主持人键,答题时间开始倒计时并显示,若选手回答结束之后主持人按下主持人键复位系统,若倒计时结束选手未回答问题系统发出报警后自动复位。扩展要求:增加1个“√”键和1个“×”键,只在10秒回答时间内有效,若选手回答正确,主持人按下“√”键彩灯闪烁,若选手回答错误,主持人按下“×”键发出低沉报警音;系统复位后抢答开始前,选手不得提前抢答,否则发出违例报警,显示违例选手编号,由主持人复位系统;可修改答题时间。
仿真原理图如下(proteus8.10版本的仿真工程文件可到本帖附件中下载)
1.png
(235.51 KB, 下载次数: 49)
下载附件
2022-10-16 00:16 上传
单片机源程序如下:
//头文件声明
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
//code uchar seven_seg[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
code uchar seven_seg[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
code uchar seven_bit[] = {0xfe,0xfd,0xfb,0xf7};
sbit run_key = P3^2; //启动按键
sbit buzzer = P3^5; //报警
sbit add_key = P3^6; //加
sbit dec_key = P3^7; //减
uchar player; //定义选手按键的键值参数
uint player_num = 0; //选手号
uchar now_time = 0; //默认复位时间0S
uchar next_time=10; //默认答题时间10s
bit run_flag = 0; //主持人按下开始标志位
bit time_off = 0; //倒计时时间到,或者开始有人抢答成功标志位
uint Count_A = 0; //定时器计数参数
uint Count_B = 0; //定时器计数参数
void delay(uint ms) //延时函数
{
uint i,j;
for(i=ms;i>0;i--)
for(j=110;j>0;j--);
}
void dispaly(uint a,uint b) //a为选手号码,b为时间
{
P2=seven_bit[0];
P0=seven_seg[a]; //显示选手号
delay(5);
P2=seven_bit[1];
P0=0x40; //显示横杠
delay(5);
P2=seven_bit[2];
P0=seven_seg[b/10]; //显示倒计时时间
delay(5);
P2=seven_bit[3];
P0=seven_seg[b%10];
delay(5);
P2=0xff;
}
void keyScan() //按键子程序
{
if(run_key==0) //如果启动按键按下
{
delay(5); //消抖
if(run_key==0)
{
if(now_time!=next_time)
{
if(player_num!=0)
{
now_time=0; //答题结束按键按键复位
player_num=0;
time_off=0;//复位选手按下标志
}
else
{
player_num=0;
run_flag=1; //设置模式调整
buzzer=0;//0.5S声音
now_time=3;
TR0=1; //开启定时器
TR1=1;
}
}
else
{
buzzer=0;//0.5S声音
TR0=1; //开启定时器
TR1=1;
}
}
while(run_key==0); //等待按键放开
}
if(run_flag==0&&time_off==0) //只有没开始抢答的时候可以加减
{
if(add_key==0)
{
delay(5);
if(add_key==0)
{
next_time++; //时间加上去
}
while(add_key==0) dispaly(player_num,next_time); //显示
}
if(dec_key==0)
{
delay(5);
if(dec_key==0)
{
next_time--; //时间减下来
}
while(dec_key==0) dispaly(player_num,next_time); //显示
}
}
}
void EX_Init()
{
/*********初始化定时器/外部中断**********/
TMOD = 0x11; //10ms
TH0 = 0x0D8;
TL0 = 0x0F0;
TH1 = 0x0D8;
TL1 = 0x0F0;
IE = 0x8b; //IE = 0x85;
IT0 = 1;
IT1 = 1;
PX0 = 1;
TR0 = 0; //关闭定时器
TR1 = 0;
}
void main(void)
{
EX_Init(); //初始化
buzzer=1;
P2=0xff;
P1=0xff;
P0=0xff;
while(1) //死循环
{
keyScan(); //按键程序
dispaly(player_num,now_time); //显示
}
}
void Time0() interrupt 1
{
TH0 = 0x0D8; //10ms
TL0 = 0x0F0;
if(run_flag==1) //如果开始抢答
{
player=P1; //读取端口
switch(player)
{
case 0xfe:player_num=1;run_flag=0;time_off=1;TR0=0;TR1=0;now_time=next_time;break; //为第一个选手按下时,选手号=1,定时器停止,时间十秒
case 0xfd:player_num=2;run_flag=0;time_off=1;TR0=0;TR1=0;now_time=next_time;break;
case 0xfb:player_num=3;run_flag=0;time_off=1;TR0=0;TR1=0;now_time=next_time;break;
case 0xf7:player_num=4;run_flag=0;time_off=1;TR0=0;TR1=0;now_time=next_time;break;
case 0xef:player_num=5;run_flag=0;time_off=1;TR0=0;TR1=0;now_time=next_time;break;
case 0xdf:player_num=6;run_flag=0;time_off=1;TR0=0;TR1=0;now_time=next_time;break;
case 0xbf:player_num=7;run_flag=0;time_off=1;TR0=0;TR1=0;now_time=next_time;break;
case 0x7f:player_num=8;run_flag=0;time_off=1;TR0=0;TR1=0;now_time=next_time;break;
case 0xff:break; //全高电平-无人按下,退出
default:player_num=9; break; //出现其它情况,显示9
}
}
}
void Time1() interrupt 3
{
TH1 = 0x0D8;
TL1 = 0x0F0; //10ms
Count_A++;
Count_B++;
if(Count_B<50) //500ms的蜂鸣器提示
buzzer=0;
else buzzer=1;
if(Count_A==100) //每秒钟减一,倒计时
{ Count_A=0;
now_time--; //当前倒计时时间 --
if(now_time<=0) //倒计时结束(到0),那么开始报警,其它复位
{ now_time=0;run_flag=0;TR0=0;TR1=0;time_off=1;buzzer=0; delay(1200);buzzer=1;}
}
}
复制代码
Keil代码与Proteus8.10仿真下载:
抢答器.rar
(94.5 KB, 下载次数: 80)
2022-10-15 21:30 上传
点击文件名下载附件
抢答器
下载积分: 黑币 -5
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1