单片机8位抢答器源程序

来源:本站
导读:目前正在解读《单片机8位抢答器源程序》的相关信息,《单片机8位抢答器源程序》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《单片机8位抢答器源程序》的详细说明。
简介:本文主要为单片机8位抢答器源程序,希望对你的学习有所帮助。

功能如下:显示抢答、回答时间倒计时,能够调节抢答、回答时间,能够报警犯规抢答,可以计分,可以实现软复位

使用AT89S52 单片机。四位数码管(为啥我没有选择用液晶,因为我觉得液晶做的抢答器根本不具有实用性)。我所认为的实用性是做出来的东西是能够使用的而不是模型。同时我的8个按键都是分开来做的,也是实用性的考虑

/*八路抢答器-----能够显示抢答、回答时间倒计时,能够调节抢答、回答时间,能够报警犯规抢答,可以计分,可以实现软复位*/

/*欢迎交流*/

#include<reg52.h>

#define uchar unsigned char

#define uint unsigned int

sbit fmq=P3^6;

sbit Key_Start=P3^4;//开始键,时间设置时+

sbit Key_Stop=P3^5;//停止键,时间设置时-

sbit Key_Restart=P3^0;//复位键

sbit Key_set_Q=P3^2;//抢答时间设置键

sbit Key_set_H=P3^3;//回答时间设置键

sbit led=P3^7;//抢答LED提示

uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff,0xc6,0xf0,0xb6};//段码表

uchar code table_char[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xc7,0xc0,0x92,0x86,0xbf,0xb7,0xff,0xb9,0x8f};//0-9 L O S E -

uchar table_score[9]={0,50,50,50,50,50,50,50,50};//记分数组,初设值50分

void delay(uint z);//延时函数声明

void init();//初始化函数声明

void display(uchar XuanShou,uchar time);//显示数字函数声明

void display_char(uchar char_1,uchar char_2,uchar char_3,uchar char_4 );//显示字符函数声明

void display_set(uchar char_1,uchar time,uchar char_2);//时间设置闪动显示函数声明

void display_score(uchar xs_num);//分数查询显示函数

void beep();//蜂鸣器函数

void beep_last();//蜂鸣器特殊报警

void LED();//提示灯函数

uchar QiangDa_time,HuiDa_time,QiangDa_time_temp=20,HuiDa_time_temp=30;//抢答时间、回答时间变量

uchar count_0,count_1;//定时中计数用的

uint shan_count=0;//闪动显示计数用

void main()

{

uchar AnJian,ShuJu,XuanShou_num;

Top:init();//初始化

XuanShou_num=1;//为分数查询做好准备

while(1)

{

display(10,0);//显示一杠

ShuJu=P1;

if(ShuJu!=0xff)//犯规抢答!!

{

// delay(10);

// if(ShuJu!=0xff)

// {

AnJian=ShuJu;

switch(AnJian)//取出选手编号

{

case 0xfe : XuanShou_num=1;break;//1111 1110

case 0xfd : XuanShou_num=2;break;//1111 1101

case 0xfb : XuanShou_num=3;break;//1111 1011

case 0xf7 : XuanShou_num=4;break;//1111 0111

case 0xef : XuanShou_num=5;break;//1110 1111

case 0xdf : XuanShou_num=6;break;//1101 1111

case 0xbf : XuanShou_num=7;break;//1011 1111

case 0x7f : XuanShou_num=8;break;//0111 1111

default : goto LOSE;//无法显示了,有两个以上的键同时按下了!!不过这种概率相当小

}

while(1)

{

display_char(13,14,14,XuanShou_num);//闪动显示犯规选手并且报警

if(shan_count==50)

{

beep();

}

if(Key_Stop==0)

{

delay(10);

if(Key_Stop==0)

{

beep();

table_score[XuanShou_num]--;//扣分

}

}

while(!Key_Stop)

{

display_char(14,14,1,16);//按键不放开的情况下显示-1

shan_count=1;//调用的是闪动显示函数,但是不让其闪动

}

if(Key_Restart==0)

{

delay(10);

if(Key_Restart==0)

{

beep();

goto Top;//热复位

}

}

}

// }

}

if(Key_Start==0)

{

delay(10);

if(Key_Start==0)//主持人按下抢答键,抢答正式开始!

{

QiangDa_time=QiangDa_time_temp;

HuiDa_time=HuiDa_time_temp;

beep();

TR1=1;//抢答时间开始倒计时

break;//跳出犯规抢答查询循环

}

}

//一下为查分程序测试

if(Key_Stop==0)

{

delay(10);

if(Key_Stop==0)//进入分数查询显示

{

beep();

while(!Key_Stop);

while(1)

{

display_score(XuanShou_num);

if(Key_Start==0)

{

delay(10);

if(Key_Start==0)

{

XuanShou_num++;

if(XuanShou_num==9) XuanShou_num=1;

}

}

while(!Key_Start);//等待按键释放

if(Key_Stop==0)

{

delay(10);

if(Key_Stop==0)

{

XuanShou_num--;

if(XuanShou_num==0) XuanShou_num=8;

}

}

while(!Key_Stop);//等待按键释放

if(Key_Restart==0)

{

delay(10);

if(Key_Restart==0)

{

beep();

goto Top;//热复位

}

}

}

}

}

}

while(1) //查询是否有按键按下,进入抢答循环

{

display(10,QiangDa_time);//显示抢答倒计时

if(QiangDa_time==0)

{

// beep();

TR1=0;//关闭定时器1

LOSE: while(1)

{

display_char(10,11,12,13); //显示lose 字符

if(Key_Restart==0)

{

delay(10);

if(Key_Restart==0)//热复位键,从头开始下一轮

{

beep();

goto Top;

}

}

}

}

ShuJu=P1;//把P1口的数据送给变量

if(ShuJu!=0xff)//有按键按下

{

// delay(10);

// if(ShuJu!=0xff)//确定有按键按下

// {

AnJian=ShuJu;//传递数据扫描值

// TR0=1;//启动定时器0

TR1=0;//关闭定时器1

break;//不再进行查询是否有按键按下了

// }

}

}

switch(AnJian)//取出选手编号

{

case 0xfe : XuanShou_num=1;beep();LED();break;//1111 1110

case 0xfd : XuanShou_num=2;beep();LED();break;//1111 1101

case 0xfb : XuanShou_num=3;beep();LED();break;//1111 1011

case 0xf7 : XuanShou_num=4;beep();LED();break;//1111 0111

case 0xef : XuanShou_num=5;beep();LED();break;//1110 1111

case 0xdf : XuanShou_num=6;beep();LED();break;//1101 1111

case 0xbf : XuanShou_num=7;beep();LED();break;//1011 1111

case 0x7f : XuanShou_num=8;beep();LED();break;//0111 1111

default : goto LOSE;//无法显示了,有两个以上的键同时按下了!!不过这种概率相当小

}

TR0=1;//启动定时器0(在这里启动比在前面好)

while(1)

{

display(XuanShou_num,HuiDa_time);//显示选手编号和回答倒计时

if(HuiDa_time==0)

{

TR0=0;//关闭定时器0

goto LOSE;//跳到显示lose字符那里

}

if(Key_Stop==0)

{

delay(30);

if(Key_Stop==0)//停止键按下

{

beep();

TR0=0;//关闭定时器0,选手开始回答

while(!Key_Stop);

while(1) //在显示选手回答倒计时时只有在stop按键按下时,才可按复位键

{

display(XuanShou_num,HuiDa_time);//显示选手编号和回答倒计时

if(Key_Start==0)

{

delay(10);

if(Key_Start==0)

{

beep();

table_score[XuanShou_num]++;//加分

}

}

while(!Key_Start)

{

display_char(17,18,1,16);//按键不放开的情况下显示+1

shan_count=1;//调用的是闪动显示函数,但是不让其闪动

}

if(Key_Stop==0)

{

delay(10);

if(Key_Stop==0)

{

beep();

table_score[XuanShou_num]--;//扣分

}

}

while(!Key_Stop)

{

display_char(14,14,1,16);//按键不放开的情况下显示-1

shan_count=1;//调用的是闪动显示函数,但是不让其闪动

}

if(Key_Restart==0)

{

delay(10);

if(Key_Restart==0)//热复位键,从头开始下一轮

{

beep();

goto Top;

}

}

}

}

}

// else

/* if(Key_Restart==0)

{

delay(10);

if(Key_Restart==0)//热复位键,从头开始下一轮

{

beep();

goto Top;

}

} */

}

}

void delay(uint z)//1ms基准延时

{

uint x,y;

for(x=z;x>0;x--)

for(y=110;y>0;y--);

}

void init()//初始化函数

{

// P1=0xff

EA=1;//开总中断;

TMOD=0x11;//定时器工作方式1,16位定时计数器

TH0=(65536-50000)/256;//50us

TL0=(65536-50000)%256;

ET0=1;//开定时器0中断(暂时不启动定时器)

// TMOD=0x01;//定时器工作方式1,16位定时计数器

TH1=(65536-50000)/256;//50us

TL1=(65536-50000)%256;

ET1=1;//开定时器0中断(暂时不启动定时器)

EX0=1;//启动外中断0

EX1=1;//启动外中断1

P1=0xff;//读P1口的数据要先置1准备

count_0=0;//定时器中的计数清零

count_1=0;

shan_count=0;

}

void display(uchar XuanShou,uchar time)//显示数字的函数

{

P2=0x7f;//0111 1111最后一位数码管亮

P0=table[XuanShou];//选手编号

delay(1);

P2=0x7f;//0111 1111

P0=0xff;//消余辉

delay(1);

P2=0xdf;//1101 1111

P0=table[time%10];//时间的个位

delay(1);

P2=0xdf;//0111 1111

P0=0xff;//消余辉

delay(1);

P2=0xef;// 1110 1111

P0=table[time/10];//时间的十位

delay(1);

P2=0xef;//0111 1111

P0=0xff;//消余辉

delay(1);

}

void display_char(uchar char_1,uchar char_2,uchar char_3,uchar char_4 )//闪动!显示字符的函数

{

shan_count++;

if(shan_count==150) shan_count=0;

if(shan_count>0&&shan_count<50)

{

P2=0x7f;//0111 1111

P0=table_char[char_4];

delay(1);

P2=0x7f;//0111 1111

P0=0xff;

delay(1);

P2=0xbf;//1011 1111

P0=table_char[char_3];

delay(1);

P2=0xbf;//1011 1111

P0=0xff;

delay(1);

P2=0xdf;//1101 1111

P0=table_char[char_2];

delay(1);

P2=0xdf;//1101 1111

P0=0xff;

delay(1);

P2=0xef;//1110 1111

P0=table_char[char_1];

delay(1);

P2=0xef;//1110 1111

P0=0xff;

delay(1);

}

else

{

P2=0x7f;//0111 1111

P0=0xff;

delay(1);

P2=0xbf;//

P0=0xff;

delay(1);

P2=0xdf;//

P0=0xff;

delay(1);

P2=0xef;//

P0=0xff;

delay(1);

}

}

void display_set(uchar char_1,uchar time,uchar char_2)//时间设置的闪动显示

{

shan_count++;

if(shan_count==120) shan_count=0;

if(shan_count>0&&shan_count<40)

{

P2=0x7f;//0111 1111最后一位数码管亮

P0=table[char_2];//显示一个符号

delay(1);

P2=0x7f;//0111 1111

P0=0xff;//消余辉

delay(1);

P2=0xbf;//1011 1111

P0=table[time%10];//时间的个位

delay(1);

P2=0xbf;//1011 1111

P0=0xff;//消余辉

delay(1);

P2=0xdf;//1101 1111

P0=table[time/10];//时间的十位

delay(1);

P2=0xdf;//1101 1111

P0=0xff;//消余辉

delay(1);

P2=0xef;// 1110 1111

P0=table[char_1];//显示一个符号

delay(1);

P2=0xef;//1110 1111

P0=0xff;//消余辉

delay(1);

}

else

{

P2=0x7f;//0111 1111

P0=table[char_2];

delay(1);

P2=0xbf;//

P0=0xff;

delay(1);

P2=0xdf;//

P0=0xff;

delay(1);

P2=0xef;//

P0=table[char_1];

delay(1);

}

}

void display_score(uchar xs_num)//分数查询显示函数

{

P2=0x7f;//0111 1111最后一位数码管亮

P0=table[(table_score[xs_num]%10)];//分数的个位

delay(1);

P2=0x7f;//0111 1111

P0=0xff;//消余辉

delay(1);

P2=0xbf;//1011 1111

P0=table[(table_score[xs_num]/10)];//分数的十位

delay(1);

P2=0xbf;//1011 1111

P0=0xff;//消余辉

delay(1);

P2=0xdf;//1101 1111

P0=table_char[15];//间隔符号

delay(1);

P2=0xdf;//1101 1111

P0=0xff;//消余辉

delay(1);

P2=0xef;// 1110 1111

P0=table[xs_num];//选手编号

delay(1);

P2=0xef;//1110 1111

P0=0xff;//消余辉

delay(1);

}

void beep() //有源蜂鸣器函数

{

fmq=0;

delay(80);

fmq=1;

}

void beep_last()//最后一声特殊声调

{

fmq=0;

delay(300);

fmq=1;

}

void LED()

{

led=0;

delay(150);

led=1;

}

void T0_time() interrupt 1//定时器0中断函数_回答时间

{

TH0=(65536-50000)/256;//50ms

TL0=(65536-50000)%256;//马上重装初值,以免有误差

if(count_0==20)

{

count_0=0;

HuiDa_time--;

if(HuiDa_time<=5)

{

if(HuiDa_time==0)

{

beep_last();//最后一声特殊警告

}

beep();

}

}

count_0++;

}

void T1_time() interrupt 3//定时器1中断函数_抢答时间

{

TH1=(65536-50000)/256;//50us

TL1=(65536-50000)%256;//马上重装初值,这样在后面调用beep()函数时就不会影响定时器的准确计时了

if(count_1==20)

{

count_1=0;

QiangDa_time--;

if(QiangDa_time<=5)

{

if(QiangDa_time==0)

{

beep_last();//最后一声警告

}

else

beep();

}

}

count_1++;

}

void EX0_set_QiangDa_time() interrupt 0 //外中断0,设置抢答时间

{

delay(10);//消抖一下

if(Key_set_Q==0)

{

beep();

while(1)

{

// display(11,QiangDa_time_temp);

// delay(100);//闪动效果

display_set(12,QiangDa_time_temp,13);//调用时间设置闪动显示函数,效果为 [时间]

if(Key_Start==0)//时间+1键

{

delay(10);

if(Key_Start==0)

{

QiangDa_time_temp++;

if(QiangDa_time_temp==100)

{

QiangDa_time_temp=1;

}

}

}

while(!Key_Start);//等待按键释放

// else

if(Key_Stop==0)//时间-1键

{

delay(10);

if(Key_Stop==0)

{

QiangDa_time_temp--;

if(QiangDa_time_temp==0)

{

QiangDa_time_temp=99;

}

}

}

while(!Key_Stop);//等待按键释放

// else

if(Key_Restart==0)

{

if(Key_Restart==0)

{

beep();

break;

}

}

}

}

}

void EX1_set_HuiDa_time() interrupt 2 //外中断1,设置回答时间

{

delay(10);//消抖一下

if(Key_set_H==0)

{

beep();

while(1)

{

display_set(12,HuiDa_time_temp,13);//调用时间设置闪动显示函数,效果为 [时间]

if(Key_Start==0)//时间+1键

{

delay(10);

if(Key_Start==0)

{

HuiDa_time_temp++;

if(HuiDa_time_temp==100)

{

HuiDa_time_temp=1;

}

}

}

while(!Key_Start);//等待按键释放

// else

if(Key_Stop==0)//时间-1键

{

delay(10);

if(Key_Stop==0)

{

HuiDa_time_temp--;

if(HuiDa_time_temp==0)

{

HuiDa_time_temp=99;

}

}

}

while(!Key_Stop);//等待按键释放

// else

if(Key_Restart==0)

{

if(Key_Restart==0)

{

beep();

break;

}

}

}

}

}

提醒:《单片机8位抢答器源程序》最后刷新时间 2024-03-14 00:53:12,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《单片机8位抢答器源程序》该内容的真实性请自行鉴别。