標題:
關(guān)于搶答器,請大佬幫忙看看我截圖的那幾行單片機代碼是什么意思?
[打印本頁]
作者:
yewangege
時間:
2020-12-10 08:22
標題:
關(guān)于搶答器,請大佬幫忙看看我截圖的那幾行單片機代碼是什么意思?
A3DFF3B5-BF23-416F-A358-480F651FD67B.jpeg
(114.97 KB, 下載次數(shù): 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位數(shù)的值
unsigned char k;
unsigned char KeyValue;
unsigned char flag=0;
char Sec=10;
char xuanshou=0;
unsigned char Keyflag; //記錄按鍵的狀態(tài),0沒有,1有
void Delay10ms(); //延時10ms
void KeyDown(); //檢測按鍵函數(shù)
//--聲明全局函數(shù)--//
void DigDisplay(); //動態(tài)顯示函數(shù)
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) //位選,選擇點亮的數(shù)碼管,
{
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];//發(fā)送段碼
j=10; //掃描間隔時間設(shè)定
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; //恢復(fù)定時器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; //恢復(fù)定時器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;
}
}
復(fù)制代碼
作者:
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開始計數(shù),對應(yīng)的額選手默認從1開始,所以做加一處理。
KeyValue=0時,對應(yīng)的是1號選手。KeyValue=5時,對應(yīng)的是6號選手。
程序里還有計時功能,flag的幾個值都有特定意思,邏輯稍微復(fù)雜一些。
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1