基于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;
}
}
}
程序有些乱,请大家帮我改改,帮我做出完整程序流程图。
希望各位高手帮帮我!