标题:
关于抢答器,请大佬帮忙看看我截图的那几行单片机代码是什么意思?
[打印本页]
作者:
yewangege
时间:
2020-12-10 08:22
标题:
关于抢答器,请大佬帮忙看看我截图的那几行单片机代码是什么意思?
A3DFF3B5-BF23-416F-A358-480F651FD67B.jpeg
(114.97 KB, 下载次数: 44)
下载附件
2020-12-10 08:22 上传
单片机源程序如下:
#include<reg51.h>
#define JZKEY P1
#define GPIO_DIG P0
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
sbit K1=P3^2;
sbit K2=P3^3;
sbit BEEP=P1^5;
sbit LED1=P2^7;
sbit LED2=P2^6;
sbit LED3=P2^5;
sbit LED4=P2^1;
sbit LED5=P2^0;
unsigned char code COMD_CODE[17] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};
//0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F的显示码
unsigned char COMD_Display[8];
//用来存放要显示的8位数的值
unsigned char k;
unsigned char KeyValue;
unsigned char flag=0;
char Sec=10;
char xuanshou=0;
unsigned char Keyflag; //记录按键的状态,0没有,1有
void Delay10ms(); //延时10ms
void KeyDown(); //检测按键函数
//--声明全局函数--//
void DigDisplay(); //动态显示函数
void Delay(unsigned int i) //无符号类型的int
{
char j;
for(i; i > 0; i--)
for(j = 200; j > 0; j--);
}
void Delay10ms2(unsigned int c) //误差 0us
{
unsigned char a,b;
for(;c>0;c--)
for(b=38;b>0;b--)
for(a=130;a>0;a--);
}
void BZ1() //正确抢答蜂鸣器
{
unsigned int t;
for(t=0;t<1000;t++)
{
BEEP= 1;
Delay(10);
BEEP= 0;
Delay(10);
}
}
void BZ2() //错误抢答蜂鸣器
{
unsigned int t;
for(t=0;t<1000;t++)
{
BEEP= 1;
Delay(10);
BEEP= 0;
Delay(10);
}
Delay10ms2(30);
for(t=0;t<1000;t++)
{
BEEP= 1;
Delay(10);
BEEP= 0;
Delay(10);
}
}
void main(void)
{
unsigned char i=0;
BEEP=1;
Keyflag=0;
TMOD=0x01; //定时器0方式1
TH0=(65536-50000)/256; //定时器0:50ms
TL0=(65536-50000)%256;
TH1=(65536-50000)/256; //定时器0:50ms
TL1=(65536-50000)%256;
EA=1; //开启总中断
ET1=1;TR1=1; //开启T1定时器 T1定时器允许中断
while(1)
{
ET0=0;TR0=0;
while(flag==0)
{
COMD_Display[0] = COMD_CODE[Sec/10%10];
COMD_Display[1] = COMD_CODE[Sec%10];
DigDisplay();
if(K1==0)
{
flag=1;
ET0=1;TR0=1;
}
if(K2==0)
{
Sec=10;
COMD_Display[0] = COMD_CODE[Sec/10%10];
COMD_Display[1] = COMD_CODE[Sec%10];
flag=0;
P2=0xff;
xuanshou=0;
}
KeyDown();
if(Keyflag==1)
{
if(KeyValue<5)
{
BZ2();
COMD_Display[0]=COMD_CODE[(KeyValue+1)/10];
COMD_Display[1]=COMD_CODE[(KeyValue+1)%10];
xuanshou=(KeyValue+1);
flag=3;
}
Keyflag=0;
}
}
while(flag==1)
{
KeyDown();
if(Keyflag==1)
{
Keyflag=0;
if(KeyValue<5)
{
COMD_Display[0]=COMD_CODE[(KeyValue+1)/10];
COMD_Display[1]=COMD_CODE[(KeyValue+1)%10];
ET0=0;TR0=0;
xuanshou=(KeyValue+1);
flag=2;
BZ1();
}
}
DigDisplay();
}
ET0=0;TR0=0;
while(flag==2)
{
if(K2==0)
{
Sec=10;
COMD_Display[0] = COMD_CODE[Sec/10%10];
COMD_Display[1] = COMD_CODE[Sec%10];
flag=0;
P2=0xff;
xuanshou=0;
}
DigDisplay();
}
while(flag==3)
{
COMD_Display[0]=COMD_CODE[15];
COMD_Display[1]=COMD_CODE[xuanshou];
DigDisplay();
if(K2==0)
{
Sec=10;
COMD_Display[0] = COMD_CODE[Sec/10%10];
COMD_Display[1] = COMD_CODE[Sec%10];
flag=0;
P2=0xff;
xuanshou=0;
Keyflag=0;
}
}
}
}
void DigDisplay()
{
unsigned char i;
unsigned int j;
for(i=0;i<8;i++)
{
switch(7-i) //位选,选择点亮的数码管,
{
case(0):
LSA=0;LSB=0;LSC=0; break;//显示第0位
case(1):
LSA=1;LSB=0;LSC=0; break;//显示第1位
case(2):
LSA=0;LSB=1;LSC=0; break;//显示第2位
case(3):
LSA=1;LSB=1;LSC=0; break;//显示第3位
case(4):
LSA=0;LSB=0;LSC=1; break;//显示第4位
case(5):
LSA=1;LSB=0;LSC=1; break;//显示第5位
case(6):
LSA=0;LSB=1;LSC=1; break;//显示第6位
case(7):
LSA=1;LSB=1;LSC=1; break;//显示第7位
}
GPIO_DIG=COMD_Display[i];//发送段码
j=10; //扫描间隔时间设定
while(j--);
GPIO_DIG=0x00;//消隐
}
}
void KeyDown(void)
{
JZKEY=0x0f;
if(JZKEY!=0x0f)
{
Delay10ms();
if(JZKEY!=0x0f)
{
Keyflag=1;//有按键按下
//测试列
JZKEY=0X0F;
switch(JZKEY)
{
case(0X07): KeyValue=0;break;
case(0X0b): KeyValue=1;break;
case(0X0d): KeyValue=2;break;
case(0X0e): KeyValue=3;break;
}
//测试行
JZKEY=0XF0;
Delay10ms();
switch(JZKEY)
{
case(0X70): KeyValue=KeyValue;break;
case(0Xb0): KeyValue=KeyValue+4;break;
case(0Xd0): KeyValue=KeyValue+8;break;
case(0Xe0): KeyValue=KeyValue+12;break;
}
while(JZKEY!=0xf0);
}
}
}
void Delay10ms(void)
{
unsigned char a,b,c;
for(c=1;c>0;c--)
for(b=38;b>0;b--)
for(a=130;a>0;a--);
}
void Timer0() interrupt 1 //倒计时
{
unsigned char i;
TH0=(65536-50000)/256; //恢复定时器0初值
TL0=(65536-50000)%256;
if(flag==1)
i++;
if(i>=20) //50ms*20=1s
{
i=0;
Sec--;
if(Sec==0)
{
ET0=0;TR0=0;
BZ2();
flag=2;
}
COMD_Display[0] = COMD_CODE[Sec/10%10];
COMD_Display[1] = COMD_CODE[Sec%10];
}
}
void Timer1() interrupt 3 //正确LED闪烁
{
TH1=(65536-50000)/256; //恢复定时器0初值
TL1=(65536-50000)%256;
k++;
if(flag==2)
{
if(k>=200)
{
k=0;
if(xuanshou==1)
{
LED1=!LED1;
}
if(xuanshou==2)
{
LED2=!LED2;
}
if(xuanshou==3)
{
LED3=!LED3;
}
if(xuanshou==4)
{
LED4=!LED4;
}
if(xuanshou==5)
{
LED5=!LED5;
}
}
}
if(flag==3) //错误抢答时的LED闪烁
{
if(k>=20)
{
k=0;
if(xuanshou==1)
{
LED1=!LED1;
}
if(xuanshou==2)
{
LED2=!LED2;
}
if(xuanshou==3)
{
LED3=!LED3;
}
if(xuanshou==4)
{
LED4=!LED4;
}
if(xuanshou==5)
{
LED5=!LED5;
}
}
复制代码
作者:
suncat0504
时间:
2020-12-10 11:00
COMD_Display[0]=COMD_CODE[(KeyValue+1)/10];
COMD_Display[1]=COMD_CODE[(KeyValue+1)%10];
xuanshou=(KeyValue+1);
前两行是为了能在LED上显示选手的编号做的处理,分被显示抢答按键的10位和个位。最后一行是确定选手的按键值。因为KeyValue默认从0开始计数,对应的额选手默认从1开始,所以做加一处理。
KeyValue=0时,对应的是1号选手。KeyValue=5时,对应的是6号选手。
程序里还有计时功能,flag的几个值都有特定意思,逻辑稍微复杂一些。
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1