基于AT89C52的乒乓球游戲機:要求:通過8只連續排列的發光二極管的依次點亮代表“乒乓球”的運動,中間兩個綠燈表示擋板,其余為紅燈。再用兩個按鍵模擬左右兩個球拍,鍵按下代表球拍擊球。“左拍”按下可使發光二極管從左向右依次點亮,如同“乒乓球”從左向右飛來;“右拍”按下則可使發光二極管從右向左依次點亮,代表“乒乓球”從右向左運動。在游戲過程中,用數碼顯示管實時顯示雙方比分。游戲規則如下:
(1)“乒乓球”移動速度是固定的,設定每秒鐘移動一位(發光二極管)。
(2)在“乒乓球”移位一次的過程中,進行25次的測試(即每40毫秒一次),查詢接球方是否有擊球動作。
(3)接球方的擊球動作應發生在“乒乓球”到達本方最后一位發光二極管(即點亮)一秒鐘時間之內。如接球方在此一秒鐘之內按鍵,則接球成功,接球方得分。“乒乓球”轉為相反方向運動。此后,原接球方變為發球方,原發球方變為接球方。游戲繼續進行。
(4)如接球方提前或滯后擊球,則接球方失誤。雙方都不得分。這時“乒乓球”熄滅,數碼顯示管顯示雙方的比分不變。然后仍由原發球方發球。
原理圖見附件,程序分兩部分:
(1)pingpang.h
#ifndef __TYPE_CPU_H__
#define __TYPE_CPU_H__
#include <REG52.h>
#include <absacc.h>
#include <intrins.h>
#define D_CYCLE() _nop_() // 2個指令周期的延時
#define TRUE 1 // 布爾型變量真
#define FALSE 0 // 布爾型變量假
#define H 1 // IO口線電平高
#define L 0 // IO口線電平低
#define key_1 0x0e;
#define key_2 0x0d;
#define key_3 0x0b;
#define key_4 0x07;
sbit LED1 = P3^6;
sbit LED2 = P3^5;
sbit LED3 = P3^4;
sbit LED4 = P3^3;
sbit LED5 = P3^2;
typedef unsigned char INT8U; // 無符號8位整數
typedef unsigned int INT16U; // 無符號16位整數
typedef bit BOOLEAN;
#endif
(2)main.c
#include "pingpang.h"
INT8U count_interval_scan = 0;
INT8U value_keynow,value_keyfore;
INT8U count_keypad;
INT16U count_interval_ball = 0;
INT8U num_track = 7;
BOOLEAN flag_start =FALSE;
BOOLEAN flag_end=FALSE;
BOOLEAN flag_restart=FALSE;
BOOLEAN flag_change=FALSE;
BOOLEAN flag_goal=TRUE;
INT8U LED_list[] = //{0x3f,0x30,0x9b,0xb9,0xb4, //段碼表
// 0 1 2 3 4 對應內容
// 0xad,0xaf,0x3c,0xbf,0xbd,0x80,0x40};
// 5 6 7 8 9 - .
{0xc0,0xcf,0x64,0x46,0x4b,0x52,0x50,0xc7,0x40,0x42,0x41,0x7F};//hondeng
//0 1 2 3 4 5 6 7 8 9 A -
//------------------------------------------------------------------
void timer_Init()//定時器1初始化
{
TMOD = (TMOD&0x00)|0x01; //16位計時模式 方式1
TH0 = (65535-922)/255; //定時時間1000uS
TL0 = (65535-922)%255;
ET0 = 1;
TR0 = 1;
EA = 1;
}
//--------------------------------------------------------
//---------------------------------------------------------
void timer0_ISR (void)interrupt 1 using 2
{
TR0 = 0; //關定時器0
TH0 = (65535-922)/256; //定時時間1000uS
TL0 = (65535-922)%256;
count_interval_scan ++;//1000uS加1; //1000uS定時加一計數
TR0 = 1; //重新打開定時器1
}
//-----------------------------------------------------------
//---------------------------------------------------------
INT8U GetKeyCode()
{
INT8U value_key;
INT8U status_P1 = 0;
INT8U status_P3 = 0;
status_P1 = P1 & 0x07;
status_P3 = P3 & 0x80;
value_key = status_P1 | (status_P3>>4);
return value_key;
}
//-----------------------------------------------------------
//------------------------------------------------------------
INT8U KeyPadTask()
{
INT8U key_now;
key_now = GetKeyCode();
if(key_now == 0xFF)
{
count_keypad = 0;
value_keynow = 0;
value_keyfore = 0;
return 0;
}
if(value_keynow != value_keyfore)
{
value_keyfore = value_keynow;
count_keypad = 0;
return 0;
}
if((count_keypad++)>0x02)
{
if(value_keynow == value_keyfore)
{
return 0;
}
value_keynow = value_keyfore;
return key_now;
}
}
//------------------------------------------------------
//------------------------------------------------------
void toy_start()
{
flag_start = TRUE;
flag_end = FALSE;
flag_restart = FALSE;
}
//-------------------------------------------------------
//------------------------------------------------------
void toy_end()
{
flag_start = FALSE;
flag_end = TRUE;
flag_restart = FALSE;
}
//----------------------------------------------------------
//---------------------------------------------------------
void toy_restart()
{
flag_start = FALSE;
flag_end = FALSE;
flag_restart = TRUE;
flag_goal = TRUE;
if(flag_change)
{
num_track = 1;
}
else
{
num_track = 8;
}
}
//-----------------------------------------------------------
//---------------------------------------------------------------
void toy_change()
{
flag_change = !(flag_change);
flag_goal = TRUE;
if(flag_change)
{
num_track = 1;
}
else
{
num_track = 8;
}}
//------------------------------------------------------
//-------------------------------------------------------
//--------------------------------------------------------
void main()
{
INT8U value_get;
INT8U player_L = 0;
INT8U player_R = 0;
BOOLEAN runing = TRUE;
timer_Init();
while(1)
{
if(count_interval_scan >=20)
{
value_get = KeyPadTask();
count_interval_ball++;
}
switch(value_get)
{
case 0x0e:
if(flag_change)
{
num_track = 1;
}
toy_start();
break;
case 0x0d:
if(!flag_change)
{
num_track = 8;
}
toy_end();
break;
case 0x0b: toy_restart();
runing = TRUE;
break;
case 0x07: toy_change();
runing = TRUE;
break;
default: //toying = TRUE;
break;
}
P0 = 0x01<<num_track-1;
while(count_interval_ball >1000)
{
count_interval_ball = 0;
if(flag_start & flag_change & runing)
{
num_track ++;
if(num_track>8)
{
num_track = 1;
player_L ++;
flag_start = FALSE;
}
}
if(flag_end & (!flag_change) & runing)
{
num_track --;
if(num_track<1)
{
num_track = 8;
player_R ++;
flag_end = FALSE;
}
}
if(flag_start & (!flag_change) & (num_track != 8))
{
if(num_track == 1)
{
flag_change = !flag_change;
}
else
{
flag_start = FALSE;
if(flag_goal)
{
player_R ++;
}
flag_goal = FALSE;
runing = FALSE;
}
}
if(flag_end & flag_change & (num_track != 1))
{
if(num_track == 8)
{
flag_change = !flag_change;
}
else
{
flag_end = FALSE;
if(flag_goal)
{
player_L++;
}
flag_goal = FALSE;
runing = FALSE;
}
}
if(flag_restart & flag_change)
{
num_track = 1;
}
if(flag_restart & (!flag_change))
{
num_track = 8;
}
}
if(player_L>10)
{
if((player_L-2)<player_R)
{
player_L = 0;
}
else
{
runing = FALSE;
}
}
if(player_R>10)
{
if((player_R-2)<player_L)
{
player_R = 0;
}
else
{
runing = FALSE;
}
}
if(count_interval_ball%5 == 0)
{
P2 = LED_list[player_L];
LED2 = 0;
LED3 = 0;
LED4 = 0;
LED5 = 0;
LED1 = 1;
}
if(count_interval_ball%9 == 0)
{
P2 = LED_list[player_R];
LED2 = 0;
LED3 = 0;
LED4 = 0;
LED5 = 1;
LED1 = 0;
}
if(count_interval_ball%14 == 0)
{
P2 = LED_list[11];
LED2 = 1;
LED3 = 1;
LED4 = 1;
LED5 = 0;
LED1 = 0;
}
}
}
程序有些亂,請大家幫我改改,幫我做出完整程序流程圖。
希望各位高手幫幫我!