程式運行效果說明
測驗方法說明:只需要一個電路板,按鍵KEY3用于選手1開球(即左邊開球)或回擊球,按鍵KEY2用于選手2開球(即右邊開球)或回擊球,剛開始的時候數碼管上顯示“00 VS 00”,LED燈中間有兩個亮燈,是初始狀態,如果按下KEY3或KEY2鍵,會有一亮燈從最左邊(最右邊)出現,并一位位地向右移(左移),當亮燈移至最右邊(最左邊)時,按下KEY3(KEY2)鍵則表示回擊球成功,亮燈會逆向開始移動,否則開球方得分加一,一局的勝負是某一方取得11分且比對方分數大2為止,數碼管中間顯示局數比分,如果一方局數得分為2,則表示其比賽取勝,相應數碼管會有閃爍圖案表示,
程式相關電路及作業原理說明



乒乓球游戲功能主要依靠2個部分來實作,一是數碼管與LED部分,二是按鍵部分,
兩個部分原理很簡單,需要的注意的是數碼管和LED燈不能同時顯示,需要利用引腳P2^3分時調控,利用人眼球的視覺殘留和LED燈的余暉效應來實作相應功能,
代碼如下:
#include "STC15F2K60S2.h"
#define uint unsigned int
#define uchar unsigned char
sbit Led_sel=P2^3;//數碼管與LED燈的切換引腳,為1時選擇LED燈,為0時選擇數碼管
sbit Sel0=P2^0;
sbit Sel1=P2^1;
sbit Sel2=P2^2;//位選要用的三個引腳
sbit Key2=P3^3;//Key2
sbit Key3=P1^7;//Key3
uchar show_w1,show_w2,show_w3,show_w4,show_w5,show_w6,show_w7,show_w8,flag,count,v,s;
//show_wi是數碼管上數字顯示,flag用來分頻所用和位選下標所用,count也用于分頻,v:s是局比分
uchar duanxuan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40,0x00}; //段選,顯示0-f
uchar weixuan[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07};//位選
uint i;//狀態引數,0表示左邊開球,1表示右邊開球,2表示等待開球,3表示比賽結束
uint P1score,P2score; //分別是左邊和右邊的分數
uint shfitcounter; //分頻所用的變數
uchar G_value; //LED顯示
void Init()
{
P2M0=0xff;
P2M1=0x00;
P0M0=0xff;
P0M1=0x00;//P0和P2設定為推挽輸出
G_value=0x18;//LED燈中間顯示兩個紅點
P0=G_value;
Led_sel=1;
i=2;
v=s=0;
flag=0;
count=0;
shfitcounter=0;
P1score=0;
P2score=0;
show_w1=0x3f; //這里是讓數碼管上顯示 00 VS 00
show_w2=0x3f;
show_w3=0x00;
show_w4=0x3E;
show_w5=0x6D;
show_w6=0x00;
show_w7=0x3f;
show_w8=0x3f;
TMOD=0x01;//定時器0,方式1
EA=1;//打開總的中斷
ET0=1;//開啟定時器中斷
TH0=(65535-100)/256;//定時器初值0.1毫秒
TL0=(65535-100)%256;
TR0=1;//啟動定時器
}
void Delay_1ms(uint t) //延時函式
{
uchar j;
for(;t>0;t--)
for(j=110;j>0;j--);
}
//定時器中斷處理程式
void timer0() interrupt 1 //把數碼管的顯示提到中斷里面來了,定時器中斷
{
TH0=(65535-100)/256;//重裝定時器0的初值
TL0=(65535-100)%256;
P0=G_value;
Led_sel=1;
flag++;
shfitcounter++;
if(flag==8) //分頻作用,同時用來作為位選下標所用
{
flag=0;
count++;
}
if(count==20) //考慮到掃描頻率很高這里進行分頻顯示;
{
count=0;
Led_sel=1; //這一半的時間用來顯示LED
}
else if(count<10)
{
P0=0x00;
Led_sel=0; //這一半的時間用來顯示數碼管
P2=weixuan[flag]; //位選
switch(flag) //段選,show_wi對應負責第i個數碼管上的數字顯示內容
{
case 0:P0=show_w1;break;
case 1:P0=show_w2;break;
case 2:P0=show_w3;break;
case 3:P0=show_w4;break;
case 4:P0=show_w5;break;
case 5:P0=show_w6;break;
case 6:P0=show_w7;break;
default:P0=show_w8;break;
}
}
else
P0=G_value; //這里顯示的是LED燈上的
//這里是處理乒乓球的擊打程序
if(shfitcounter==1000) //考慮到掃描頻率很高這里進行分頻資料更新;
{
shfitcounter=0;
if(i==0)//從左往右開始
{
G_value=G_value>>1; //乒乓球右移
if(G_value==0x00) //如果到右邊了還沒被擊打,左邊分數加一
{
P1score++;
show_w1=duanxuan[P1score/10];
show_w2=duanxuan[P1score%10];
}
}
else if(i==1)//從右往左開始
{
G_value=G_value<<1; //乒乓球左移
if(G_value==0x00) //如果到左邊了還沒被擊打,右邊分數加一
{
P2score++;
show_w7=duanxuan[P2score/10];
show_w8=duanxuan[P2score%10];
}
}
if(P1score-P2score>=2&&P1score>=11)//這一局左邊贏了
{
P1score=P2score=0;
v++;//左邊贏了一局
show_w1=duanxuan[P1score/10];
show_w2=duanxuan[P1score%10];
show_w4=duanxuan[v];
show_w5=duanxuan[s];
show_w7=duanxuan[P2score/10];
show_w8=duanxuan[P2score%10];
}
else if(P2score-P1score>=2&&P2score>=11)//這一局右邊贏了
{
P1score=P2score=0;
s++;//右邊贏了一局
show_w1=duanxuan[P1score/10];
show_w2=duanxuan[P1score%10];
show_w4=duanxuan[v];
show_w5=duanxuan[s];
show_w7=duanxuan[P2score/10];
show_w8=duanxuan[P2score%10];
}
else if(v>=2)//左邊先贏兩局,表明比賽勝利,中間顯示兩個11,LED閃爍
{
v=s=0;
P1score=P2score=0;
i=3;
show_w1=0x62;
show_w2=0x62;
show_w3=0x62;
show_w4=duanxuan[1];
show_w5=duanxuan[1];
show_w6=0x62;
show_w7=0x62;
show_w8=0x62;
}
else if(s>=2) //右邊先贏兩局,表明比賽勝利,中間顯示兩個22,LED閃爍
{
v=s=0;
P1score=P2score=0;
i=3;
show_w1=0x62;
show_w2=0x62;
show_w3=0x62;
show_w4=duanxuan[2];
show_w5=duanxuan[2];
show_w6=0x62;
show_w7=0x62;
show_w8=0x62;
}
}
}
void main()
{
Init();
while(1)
{
if(i==2)//i=2表示等待開球狀態
{
if(Key3==0)//KEY3按下,左邊開球
{
i=0;
G_value=0x80;
}
else if(Key2==0)//KEY2按下,右邊開球
{
i=1;
G_value=0x01;
}
}
if(i==0)
{
if(G_value==0x00)
{
i=2;
G_value=0x18;
}
if(Key2==0&&G_value==0x01) i=1;//球在最右邊時按下KEY2,表示回擊球
}
else if(i==1)
{
if(G_value==0x00)
{
i=2;
G_value=0x18;
}
if(Key3==0&&G_value==0x80) i=0;//球在最左邊時按下KEY3,表示回擊球
}
else if(i==3) //i=3是比賽結束狀態,進行閃爍
{
G_value=0xFF;
Delay_1ms(500);
G_value=0x00;
Delay_1ms(500);
G_value=0xFF;
}
Delay_1ms(100);
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/294300.html
標籤:其他
上一篇:2021-08-15
