#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
void delay(uchar x); //延時(時間較短)
void delay1(uchar x); //延時(時間較長)
void Js_Jf_Scan(void); //數(shù)碼管動態(tài)掃描顯示函數(shù)
void Key_if(void); //A、B兩隊分值處理函數(shù)
void Js_50ms(void); //定時50ms中斷函數(shù)
void Key_Y(void); //預置時間函數(shù)
void Ptime(uchar); //時間處理函數(shù)
void sound(void); //鳴笛警示函數(shù)
sbit CL1=P2^0; //B隊4位計分數(shù)碼管位控線
sbit CL2=P2^1;
sbit CL3=P2^2;
sbit CL4=P2^3;
sbit KL1=P2^4; // A隊4位計分數(shù)碼管位控線
sbit KL2=P2^5;
sbit KL3=P2^6;
sbit KL4=P2^7;
sbit S1=P1^3; //驅動4位計時數(shù)碼管位控線
sbit S2=P1^2;
sbit S3=P1^1;
sbit S4=P1^0;
sbit YK1=P1^6; //預置分鐘的十位
sbit YK2=P1^7; //預置分鐘的個位
sbit music=P1^4; //P1.4接喇叭,發(fā)聲,鳴笛
sbit Key1=P3^0; //B隊加分鍵
sbit Key2=P3^1; //B隊減分鍵
sbit Key3=P3^4; //A隊加分鍵
sbit Key4=P3^5; //A隊減分鍵
sbit Int_Key=P3^2; //鳴笛鍵
sbit Star=P3^6; //開始按鈕
sbit Puse=P3^7; //停止按鈕
int ms=0,mg=0,fs=0; //秒鐘的十位、個位以及秒鐘的變量說明
int fg=0;m=0,f,fy,num=0; //分鐘的十位、個位以及分鐘的變量說明
int g,s,b,q,sum=0; //B隊定義個十百位
int g1,s1,b1,q1,sum1=0; // A隊定義個十百位
int LED_Num[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x00,}; //段碼
void main(void)
{
TMOD=0x01; //設置T0為工作方式1,作為16位計數(shù)器
TH0=(65535-50000)/256; //設置T0的高8位,并且T0的計數(shù)值為50ms
TL0=(65535-50000)%256; //設置T0的低8位
music=0; //初值喇叭不響
EA=1; //開放所有中斷
ET0=1; //允許定時/計數(shù)器T0溢出中斷
EX0=1; //允許外部中斷0
IT0=1; //設置外部中斷0為邊沿觸發(fā)方式(下降沿)
while(1) //無窮循環(huán),程序一直運行
{
Key_Y(); //預置場次比賽時間
if(Star==0&&f!=0&&Puse!=0) //按下“開始鍵”,設置好比賽時間,并且未按“停止”鍵時,比賽正式開始
{
TR0=1; //啟動定時器T0,開始計時
Key_if(); //開始計分
}
else
{
TR0=0; //比賽還未開始或比賽結束時間到,停止計時
}
Js_Jf_Scan(); //將相應的分數(shù)、時間同步進行顯示
}
}
/*******************設置場次比賽時間********************/
void Key_Y(void)
{
if(YK1==0) //初始狀態(tài),分鐘的十位為0
{
delay(1); //延時去抖動
fs=fs+1; //分十位加1分
fy=fs*10+fg; //求出預置時間的分鐘值
f=fy; //中間變量
}
if(YK2==0) //初始狀態(tài),分鐘的個位為0
{
delay(1); //延時去抖動
fg=fg+1; //分個位加1分
fy=fs*10+fg; //求出預置時間的分鐘值
f=fy; //中間變量
}
Js_Jf_Scan();
}
/********T0中斷服務函數(shù),每隔50ms產(chǎn)生一次中斷********/
void Js_50ms(void)interrupt 1 using 1 //定時器T0中斷,用工作寄存器組1
{
TH0=(65535-50000)/256; //定時器T0的高8位
TL0=(65535-50000)%256; //定時器T0的低8位
num++; //每50ms累加一次
Ptime(num); //調用時間處理函數(shù)
}
/**********************時間處理函數(shù)********************/
void Ptime(uchar time)
{
if(time==20) //如果為1s(50ms*20=1s)
{
num=0;
m++; //每到1s,計時器累加1次
ms=m/10; //秒的十位
mg=m%10; //秒的個位
if(m==60) //如果為1min
{
m=0; //秒鐘置0
mg=m%10; //秒鐘的個位置0
ms=m/10; //秒鐘的十位置0
f--; //分鐘開始在預設的比賽時間基礎上倒計時
fs=f/10; //分鐘的十位
fg=f%10; //分鐘的個位
if(f==0) //分鐘數(shù)倒計時到0
{
TR0=0; //時間到,停止計時
}
}
}
}
/******************數(shù)碼管動態(tài)掃描顯示******************/
void Js_Jf_Scan(void)
{
uchar j;
for(j=0;j<=5;j++)
{
KL4=0;P0=LED_Num[g1];delay(1);KL4=1; /*將A隊分數(shù)的個位傳遞給譯碼器,通過按鍵,實現(xiàn)邊沿跳變,并把結果譯成相應的段碼顯示出來*/
KL3=0;P0=LED_Num[s1];delay(1);KL3=1; /*將A隊分數(shù)的十位傳遞給譯碼器,通過按鍵,實現(xiàn)邊沿跳變,并把結果譯成相應的段碼顯示出來*/
KL2=0;P0=LED_Num[b1];delay(1);KL2=1; /*將A隊分數(shù)的百位傳遞給譯碼器,通過按鍵,實現(xiàn)邊沿跳變,并把結果譯成相應的段碼顯示出來*/
KL1=0;P0=LED_Num[q1];delay(1);KL1=1; /*將A隊分數(shù)的千位傳遞給譯碼器,通過按鍵,實現(xiàn)邊沿跳變,并把結果譯成相應的段碼顯示出來*/
CL4=0;P0=LED_Num[g];delay(1);CL4=1; /*將B隊分數(shù)的個位傳遞給譯碼器,通過按鍵,實現(xiàn)邊沿跳變,并把結果譯成相應的段碼顯示出來*/
CL3=0;P0=LED_Num[s];delay(1);CL3=1; /*將B隊分數(shù)的十位傳遞給譯碼器,通過按鍵,實現(xiàn)邊沿跳變,并把結果譯成相應的段碼顯示出來*/
CL2=0;P0=LED_Num[b];delay(1);CL2=1; /*將B隊分數(shù)的百位傳遞給譯碼器,通過按鍵,實現(xiàn)邊沿跳變,并把結果譯成相應的段碼顯示出來*/
CL1=0;P0=LED_Num[q];delay(1);CL1=1; /*將B隊分數(shù)的千位傳遞給譯碼器,通過按鍵,實現(xiàn)邊沿跳變,并把結果譯成相應的段碼顯示出來*/
S4=0;P0=LED_Num[mg];delay(1);S4=1; /*將秒鐘的個位傳遞給譯碼器,通過按鍵,實現(xiàn)邊沿跳變,并把結果譯成相應的段碼顯示出來*/
S3=0;P0=LED_Num[ms];delay(1);S3=1; /*將秒鐘的十位傳遞給譯碼器,通過按鍵,實現(xiàn)邊沿跳變,并把結果譯成相應的段碼顯示出來*/
S2=0;P0=LED_Num[fg];delay(1);S2=1; /*將分鐘的個位傳遞給譯碼器,通過按鍵,實現(xiàn)邊沿跳變,并把結果譯成相應的段碼顯示出來*/
S1=0;P0=LED_Num[fs];delay(1);S1=1; /*將分鐘的十位傳遞給譯碼器,通過按鍵,實現(xiàn)邊沿跳變,并把結果譯成相應的段碼顯示出來*/
}
}
/*****************判斷是哪個隊加分或者減分*****************/
void Key_if(void)
{
if(Key1==0) //當按鍵按下時
{
delay(1); //延時去抖動
sum=sum+1; //B隊加1分
}
if(Key2==0 && sum>=1) //減分按鍵按下并且中得分不得少于1分
{
delay(1); //延時去抖動
sum=sum-1; //B隊減1分
}
if(Key3==0) //當按鍵按下時
{
delay(1); //延時去抖動
sum1=sum1+1; //A隊加1分
}
if(Key4==0 && sum1>=1) //減分按鍵按下并且中得分不得少于1分
{
delay(1); //延時去抖動
sum1=sum1-1; //A隊減1分
}
q=0; // A隊分值的千位默認為0
b=sum/100; //求出A隊分值的百位
s=sum/10-b*10; //求出A隊分值的十位
g=sum%10; //求出A隊分值的個位
q1=0; // B隊分值的千位默認為0
b1=sum1/100; //求出B隊分值的百位
s1=sum1/10-b1*10; //求出B隊分值的十位
g1=sum1%10; //求出B隊分值的個位
}
/***********************鳴笛處理***********************/
void sound(void) interrupt 0 using 0 //外部中斷0(),用工作寄存器組0
{
uchar i,j;
if(Int_key==0) //判斷鳴笛鍵是否按下,有按下就鳴笛
{
for(i=0;i<8;i++) //控制一種發(fā)音的時間
{
for(j=0;j<250;j++) //控制發(fā)音的頻率,延時長,頻率低,音低
{
music=~music; //取反
delay1(1); //延時去抖動
}
Js_Jf_Scan();
}
for(i=0;i<16;i++) //控制另一種發(fā)音的時間
{
for(j=0;j<250;j++) //控制發(fā)音的頻率,延時短,頻率高,音高
{
music=~music; //取反
delay(1); //延時去抖動
}
Js_Jf_Scan();
}
}
else
music=0; //喇叭不響
}
/*******************延時1.8ms的子程序*******************/
void delay1(uchar x)
{
uchar k;
while(x--)
sbit music=P1^4; //P1.4接喇叭,發(fā)聲,鳴笛
for(k=0;k<215;k++); //延時長
}
/*******************延時1.0ms的子程序*******************/
void delay(uchar x)
{
uchar k;
while(x--)
for(k=0;k<120;k++); //延時短
}
|