标题:
单片机实现八路抢答器+查看分数+加减分源程序
[打印本页]
作者:
小孩。。。
时间:
2020-5-14 20:25
标题:
单片机实现八路抢答器+查看分数+加减分源程序
基于单片机的八路抢答器
一、主要内容
通过利用数码管显示,并自动复位的思路,运用单片机的运行产生输出信号,通过数码管显示对应的通道,实现了一个以单片机为核心的8路抢答器,
并且具有查看选手分数和进行加减分的功能。
二、具体操作
2、主持人按下开始键选手等待时间计完听到滴声后才可以抢答,若提前抢到则
视为犯规。
3、抢答成功后别的选手再抢到也是没有用的。
4、显示屏上显示哪位选手抢到,并开始对答题时间进行倒计时。
5、显示答题时间,在答题时间小于 5S 时报警电路会发生作用。
7、当主持人按下 RESET 键则进行下一轮的比赛。
二、程序用什么软件查看?
打开程序的软件是Keil
单片机源程序如下:
#include <reg51.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit smg1=P2^0; //定义数码管第一位
sbit smg3=P2^2; //定义数码管第三位
sbit smg4=P2^3; //定义数码管第四位
sbit keyks=P3^5; //定义开始按键
sbit keytz=P3^4; //定义停止按键
sbit keyqc=P3^3; //定义清除按键
sbit beep=P3^6; //定义蜂鸣器
uchar k;
uchar keyvalue=0;
uint a;
int djs=20,js=0; //djs和bt是初始倒计时时间,可修改
int table[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
int zhunbei[] = {0x92,0x99,0xb0,0xa4,0xf9,0xc0};//准备抢答
int fenshu[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
char fs[8];
uchar mode=0; //主持人的按键模式
// mode=0:显示选手1的分数 mode=1:显示选手2的分数....../////////
void delayzb(uint z)//准备抢答延时
{
uint x,y;//局部变量定义
for(x = z;x>0;x--)//此for循环100次
for(y = 144;y>0;y--);//此for循环144次,100*144次循环正好是100ms.
}
void delay()
{
uchar m,n,s;
for(m = 20;m>0;m--);
for(n = 20;n>0;n--);
for(s = 248;s>0;s--);
}
void delayms(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void Getch () //取键值函数
{
//keyvalue=0;
P1=0xf0; //先对P3 置数 列扫描
if(P1!=0xf0) //判断是否有键按下
{
delay(); //延时,软件去干扰
if(P1!=0xf0) //确认按键按下
{
switch (P1) //判断键值(哪一列被按下)
{
case 0xe0: keyvalue=1; break; //第一列被按下
case 0xd0: keyvalue=2; break; //第二列被按下
case 0xb0: keyvalue=3; break; //被三列被按下
case 0x70: keyvalue=4; break; //被四列被按下
}
P1 = 0x0f; //行扫描
switch (P1) //判断哪一行被按下
{
case 0x0e: keyvalue=keyvalue; break; //第一行被按下
case 0x0d: keyvalue=keyvalue + 4; break; //第二行被按下
case 0x0b: keyvalue=keyvalue + 8; break; //第三行被按下
case 0x07: keyvalue=keyvalue + 12; break; //第四行被按下
}
while (P1 != 0x0f); //松手检测
}
}
}
void Timer0_init() //定时器0初始化
{
js=0;
TMOD=0x01; //TR0=1;//IT1=1; //T0为定时器方式1 //EX1=1;
TH0=0x4c; //每50ms溢出一次
TL0=0x00;
ET0=1;
EA=1;
}
void timer0() interrupt 1 using 1 //定时器0中断服务函数
{
TF0=0;
TH0=0x4c; //每50ms溢出一次
TL0=0x00; //赋初值
js++;
if(js==20) //20*50=1000ms=1s
{
js=0;
djs--; //产生1s的倒计时
}
if(djs==5)
{
beep = 0; //倒计时后5s报警
delay();
beep = 1;
delay();
}
if(djs==0)
{
P2 = 0xff;
TR0=0; //倒计时结束,关闭定时器
}
}
void djsxs() //显示倒计时函数
{
int shi,ge;
shi=djs/10;
ge=djs%10; // 将倒计时时间分成高低位
P2=0XFF;
smg4 = 0;
P0=table[ge];
smg4 = 0;
delayms(2);
P2=0XFF;
smg3 = 0;
P0=table[shi];
smg3 = 0;
delayms(2);
P2=0XFF;
}
void djsxs22() //显示- --
{
P2=0XFF;
P0=0xbf;
smg1 = 0;
delayms(3);
P2=0XFF; //第一位数码管显示-
P0=0xbf;
smg3 = 0;
delayms(3); //第三位数码管显示-
P2=0XFF;
P0=0xbf;
smg4 = 0;
delayms(3);
P2=0XFF; //第四位数码管显示-
}
void playerxs()
{
P0=table[keyvalue];
smg1=0;
delayms(3);
smg1=1;
} //第一位数码管显示
void main()
{
int djs1=20;
Timer0_init(); //初始化定时器中断
beep=1; //蜂鸣器不响
djs=20; //倒计时赋值
while(1)
{
LOOP1:
Getch();
djs=djs1;
djsxs22(); //LOOP1是标号,显示 - --
keyvalue = 0;
// beep=1; //蜂鸣器不响
djs=20; //倒计时赋值
TR0 = 0;
if(keyks==0)//开始按键
{
beep=0;//蜂鸣器响
delayms(3); //去除按键抖动
if(keyks==0) //确定开始按下
{
while(!keyks); //松手检测
{
beep=1;
for(a = 0;a<6;a++) //5s倒计时准备抢答
{
P2 = 0xf7;//1111 0111 //第四位数码管显示5s倒计时
P0 = zhunbei[a];
delayzb(800);
P2 = 0xff;
}
}
while(1)
{
Getch();
if(keyqc == 0)
{
delayms(3); //去除抖动
if(keyqc == 0)
{
while(!keyqc); //如果按下清除键,则回到- --状态
goto LOOP1; //goto语句,回到loop1表号处
}
}
/*以下是八个选手抢答,key1表示1号选手,依次类推,注释只写第一位选手,其他和第一个完全一致*/
if((keyvalue>=1)&&(keyvalue<=8)&&(TR0==0)) //在定时器关闭状态下,key1==0 则说明1号选手按下按
{
beep=0; //蜂鸣器响
//while(!key1); //去除按键抖动后,重新在判断,是否确实按下
beep=1; //蜂鸣器不响
TR0=1; //定时器开始
while(1)
{
mode = keyvalue;
playerxs(); //显示选手编号
djsxs(); //显示剩余倒计时时间
//keyvalue = 1;
if(keyqc == 0)
{
delayms(3); //去除抖动
if(keyqc == 0)
{
while(!keyqc); //如果按下清除键,则回到- --状态
goto LOOP1; //goto语句,回到loop1表号处
}
}
if(keytz == 0) //暂停按下按下
{
delayms(3); //去除抖动
if(keytz == 0) //再次判断是否按下复位按键
{
while(!keytz) //如果按下复位键,则回到- --状态
TR0=0;
}
}
if(keyks == 0)//开始按键
{
beep=0;//蜂鸣器响
delayms(30); //去除按键抖动
if(keyks == 0) //确定开始按下
{
while(!keyks); //松手检测
{
beep=1; //蜂鸣器不响
delay();
TR0 = 1;
}
}
}
if(djs == 0)
break;
}
}
if (mode!=0)
{
TR0 = 0;
while(1)
{
P0=table[mode];
smg1=0;
delayms(3);
smg1=1; //显示选手编号
P0=table[fs[mode]];
smg4=0;
delayms(3);
smg4=1;
Getch();
if(keyvalue == 9)
{
keyvalue = 0;
mode++;
if(mode>8)
{
mode=0;
}
}
else if(keyvalue == 10) //加分
{
keyvalue = 0;
fs[mode]++;
if(fs[mode] == 10)
fs[mode] = 9;
}
复制代码
八路抢答器last.zip
2020-5-14 20:05 上传
点击文件名下载附件
下载积分: 黑币 -5
32.09 KB, 下载次数: 36, 下载积分: 黑币 -5
作者:
浅墨墨
时间:
2020-6-15 17:12
那个能把原理图发一下吗
作者:
畅聊甜语
时间:
2020-6-21 08:54
程序不对吧
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1