📄 v05.c
字号:
//demo board system
//designed 2002/12/25
//modify ---------
//version V1.00
#include <reg51.h>
typedef unsigned char byte;
typedef unsigned int word;
#define XTALL 11.0592 //crystal frequency
#define DLY_10MS (word)(10000*XTALL/12) // 10ms counter
#define DLY_400US (word)(400*XTALL/12) // 400us counter
struct position{
byte x;
byte y;
};
#define xram ( byte xdata *)(0x0000)
sbit power = 0x94; //p1.4
sbit lcd_power = 0x95; //p1.5
sbit DI = 0x92; //p1.2
sbit RW = 0x91; //p1.1
sbit E = 0x90; //p1.0
sbit LCD1 = 0x93; //p1.3
sbit LCD2 = 0x96; //p1.6
sbit RST = 0xB0; //p3.0
sbit latch = 0x97; //p1.7
bit game_on,move_flag;
struct position xdata point[1000] _at_ 0x1200;
byte sp_start,sp_end,spoint,orient;
byte code chinese[350] ={ //lay model catch mod resceive
/*-- 文字: 贪 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x20,0x20,0x10,0x90,0xA8,0xA4,0xAA,0xB1,0xA2,0xE4,0xA8,0x88,0x10,0x30,0x10,0x00,
0x00,0x00,0x80,0x9F,0x40,0x20,0x10,0x0E,0x10,0x20,0x60,0xDF,0x00,0x00,0x00,0x00,
/*-- 文字: 食 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x20,0x20,0x10,0xF0,0xA8,0xA4,0xAB,0xB2,0xA4,0xA8,0xF0,0x10,0x20,0x20,0x00,0x00,
0x00,0x00,0x00,0xFF,0x42,0x22,0x06,0x0A,0x0A,0x12,0x2B,0x64,0x00,0x00,0x00,0x00,
/*-- 文字: 蛇 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0xF0,0x10,0xFF,0x10,0xF0,0x20,0x18,0xE8,0x09,0x0E,0x0A,0xA8,0x18,0x08,0x00,
0x20,0x23,0x21,0x1F,0x11,0x3B,0x10,0x00,0x3F,0x42,0x41,0x41,0x40,0x38,0x00,0x00,
/*-- 文字: V --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00,0x00,0x00,
/*-- 文字: 1 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,
/*-- 文字: 0 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*-- 文字: 游 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x10,0x61,0x86,0x60,0x08,0xF9,0x4E,0xC8,0x28,0x10,0x2F,0xA8,0x68,0x28,0x08,0x00,
0x04,0xFC,0x03,0x40,0x38,0x47,0x80,0x7F,0x00,0x42,0x82,0x7F,0x02,0x02,0x02,0x00,
/*-- 文字: 戏 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0x14,0x24,0x44,0xC4,0x34,0x0C,0x20,0x20,0xFF,0x20,0x22,0x2C,0xA0,0x20,0x00,
0x00,0x10,0x08,0x06,0x01,0x23,0x2C,0x10,0x10,0x08,0x07,0x1A,0x21,0x40,0xF0,0x00,
/*-- 文字: 结 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x20,0x30,0xAC,0x63,0x10,0x00,0x08,0x48,0x48,0x48,0x7F,0x48,0x48,0x48,0x08,0x00,
0x22,0x23,0x22,0x12,0x12,0x00,0x00,0x7E,0x22,0x22,0x22,0x22,0x22,0x7E,0x00,0x00,
/*-- 文字: 束 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x04,0x04,0xF4,0x94,0x94,0x94,0x94,0xFF,0x94,0x94,0x94,0x94,0xF4,0x04,0x04,0x00,
0x20,0x20,0x11,0x10,0x08,0x06,0x01,0xFF,0x02,0x04,0x08,0x08,0x11,0x30,0x10,0x00,
};
//------------------------------10ms timer counter-----------------------------
void TIM0_isr() interrupt 1 using 1 {
static idata word timercount;
TR0=0;
TL0+=-DLY_10MS&0xff;
TH0+=-DLY_10MS>>8;
TR0=1;
if(timercount++ >10){
timercount=0;
move_flag=1;
}
}
//---------------------------reset the lcd controller chip---------------------
void reset_lcd(void){
word i;
RST=0;
for(i=0;i<1000;i++)
;
RST=1;
}
//-------------------------write a command to left part of lcd ---------------
void write_l_com(byte com){
byte i;
LCD2=0;
LCD1=1;
DI=0;
RW=1;
RW=1;
do{
P2=0xff;
E=1;
i=P2;
E=0;
}
while(i&0x80);
RW=0;
DI=0;
P2=com;
E=1;
E=1;
E=0;
}
//----------------------write a data to left part of lcd-----------------------
void write_l_dat(byte dat){
byte i=0x80;
LCD2=0;
LCD1=1;
DI=0;
RW=1;
RW=1;
do{
P2=0xff;
E=1;
i=P2;
E=0;
}
while((i&0x80));
RW=0;
DI=1;
P2=dat;
E=1;
E=1;
E=0;
}
//--------------------------write a command to right part of lcd --------------
void write_r_com(byte com){
byte i;
LCD2=1;
LCD1=0;
DI=0;
RW=1;
RW=1;
do{
P2=0xff;
E=1;
i=P2;
E=0;
}
while(i&0x80);
RW=0;
DI=0;
P2=com;
E=1;
E=1;
E=0;
}
//------------------------write a data to right part of lcd--------------------
void write_r_dat(byte dat){
byte i=0x80;
LCD2=1;
LCD1=0;
DI=0;
RW=1;
RW=1;
do{
P2=0xff;
E=1;
i=P2;
E=0;
}
while((i&0x80));
RW=0;
DI=1;
P2=dat;
E=1;
E=1;
E=0;
}
//----------------------initialize lcd-----------------------------------------
void init_lcd(){
byte i,j,page;
word offset;
reset_lcd();
write_l_com(0x3f);
write_l_com(0xc0);
write_r_com(0x3f);
write_r_com(0xc0);
page=0;
for(i=0;i<8;i++){
page=i|0xb8;
write_l_com(page);
write_l_com(0x40);
write_r_com(page);
write_r_com(0x40);
for(j=0;j<64;j++){
write_l_dat(0x00);
write_r_dat(0x00);
}
}
for(offset=0;offset<1024;offset++){
*(xram+offset)=0x00;
}
}
//---------------------display the data from the xdata buffer-----------------
void display(){ //the display buffer is from 0x0000 to 0x0400 total 1024 byte
byte i,j,page=0;
for(i=0;i<8;i++){
page=i|0xb8;
write_l_com(page); //write the pageof lcd display buffer memory
write_l_com(40); //set the start pixel
for(j=0;j<64;j++){
write_l_dat(*(xram+(128*i)+j));
}
} //write the data to left part of lcd
for(i=0;i<8;i++){
page=i|0xb8;
write_r_com(page); //write the pageof lcd display buffer memory
write_r_com(40); //set the start pixel
for(j=0;j<64;j++){
write_r_dat(*(xram+(128*i)+64+j));
}
} //write the data to right part of lcd
}
//-------------------------write a point at the lcd----------------------------
byte write_point(byte x,byte y){
byte idata temp,buffer;
if(x>128)return 0x00;
if(y>64) return 0x01;
temp=*(xram+(y/8)*128+x);
buffer=0x01;
buffer<<=(y%8);
temp=temp|buffer;
*(xram+(y/8)*128+x)=temp;
}
//-------------------------clear a point at the lcd----------------------------
byte clear_point(byte x,byte y){
byte idata temp,buffer;
if(x>128)return 0x00;
if(y>64) return 0x01;
temp=*(xram+(y/8)*128+x);
buffer=0x01;
buffer<<=(y%8);
buffer=~buffer;
temp=temp&buffer;
*(xram+(y/8)*128+x)=temp;
}
//-------------------------write square at the lcd-----------------------------
void write_square(byte x0,y0,x1,y1,d){
byte i;
for(i=0;i<(x1-x0);i++){
write_point((x0+i),y0);
write_point((x0+i+1),y1);
}
for(i=0;i<(y1-y0);i++){
write_point(x0,(y0+i+1));
write_point(x1,(y0+i));
}
if(d){
for(i=0;i<(x1-x0);i++){
write_point((x0+i),y0+1);
write_point((x0+i+1),y1-1);
}
for(i=0;i<(y1-y0);i++){
write_point(x0+1,(y0+i+1));
write_point(x1-1,(y0+i));
}
}
}
//--------------------put a char at lcd --------------------------------------
void put_char(byte x,y,att,chara){ //att: 0-> 16x16; 1->8x16; 2->24x24
byte i;
word scope;
switch (att){
case 0:
for(i=0;i<16;i++){
*(xram+(y/8)*128+x+i)=chinese[chara*32+i];
scope=&(xram+(y/8)*128+x+i);
*(xram+(y/8)*128+x+128+i)=chinese[chara*32+16+i];
scope=&(xram+(y/8)*128+x+128+i);
}
break;
case 1:
for(i=0;i<16;i++){
*(xram+(y/8)*128+x+i)=chinese[chara*32+i];
scope=&(xram+(y/8)*128+x+i);
*(xram+(y/8)*128+x+128+i)=chinese[chara*32+16+i];
scope=&(xram+(y/8)*128+x+128+i);
}
break;
case 2:
for(i=0;i<8;i++){
*(xram+(y/8)*128+x)=chinese[chara*32+i];
*(xram+(y/8)*128+x)=chinese[chara*32+i];
}
break;
default:break;
}
}
//----------------------write snake body---------------------------------------
void write_body(void){
word i;
byte j,temp,start;
for(i=0;i<spoint;i++){
if(point[sp_end-i].x==point[sp_end-i-1].x){ //write snake bode from snake head
if(point[sp_end-i].y > point[sp_end-i-1].y){ //stand
start=point[sp_end-i-1].y;
temp=point[sp_end-i].y-point[sp_end-i-1].y;
}
else{
start=point[sp_end-i].y;
temp=point[sp_end-i-1].y-point[sp_end-i].y;
}
for(j=0;j<temp;j++){ //adjust the square error
write_point(point[sp_end-i].x,start+j); // "|"
write_point(point[sp_end-i].x+1,start+j); // "||"
}
}
else{
if(point[sp_end-i].x > point[sp_end-i-1].x){ //lay
start=point[sp_end-i-1].x;
temp=point[sp_end-i].x-point[sp_end-i-1].x;
}
else{
start=point[sp_end-i].x;
temp=point[sp_end-i-1].x-point[sp_end-i].x;
}
for(j=0;j<temp;j++){
write_point(start+j,point[sp_end-i].y); // "--"
write_point(start+j,point[sp_end-i].y+1); // "=="
}
}
}
}
//----------check the point is touch the body or square------------------------
byte check_point(){
if((point[sp_end].x== 1)||(point[sp_end].x==126))
return 0xff;
else{
if((point[sp_end].y==17)||(point[sp_end].y== 62))
return 0xff;
else
return 0x00; //that's all right
}
}
//----------------------the game model-----------------------------------------
game(){ //i is y length;don,t bigger than 15
byte i,tempx,tempx1,tempy,tempy1;
game_on=1;
orient=0;
write_square(00,16,127,63,1);
for(i=0;i<6;i++)
put_char((16+16*i),0,0,i);
sp_start=sp_end=spoint=0;
point[0].x=60;
point[0].y=38; // snake tail
point[1].x=70;
point[1].y=38;
point[2].x=70;
point[2].y=50;
point[3].x=40;
point[3].y=50;
// point[4].x=40;
// point[4].y=35;//sp_end id snake head pointer
sp_end=3;
spoint=3; //initialize snake body
write_body();
display();
while(game_on){
if(move_flag){
move_flag=0;
switch (orient){
case 0: //the snake is walk front and don't creat cells
tempx=point[sp_end].x; //move snake head
tempx--;
point[sp_end].x=tempx;
tempx=point[sp_start].x;
tempx1=point[sp_start+1].x;
tempy=point[sp_start].y;
tempy1=point[sp_start+1].y;
if(tempx==tempx1){
clear_point(tempx,point[sp_start].y); // "|"
clear_point(tempx+1,point[sp_start].y);
if(tempy>tempy1){ //move the snake tail
tempy--; // ^
point[sp_start].y=tempy;// |
}
else{
tempy++;
point[sp_start].y=tempy;
}
}
else{
clear_point(tempx,point[sp_start].y); // "--"
clear_point(tempx,point[sp_start].y+1);
if(tempx >tempx1){ // move the snake tail
tempx--; // <----
point[sp_start].x=tempx;
}
else{
tempx++; // ---->
point[sp_start].x=tempx;
}
}
if((point[sp_start].x==point[sp_start+1].x)&&(point[sp_start].y==point[sp_start+1].y)){
sp_start++; //end of a cells
spoint--;
if(sp_start==sp_end){
sp_start=sp_end=0;
}
}
break;
case 1: //creat a new cell for left
break;
case 2: //creat a new cell for right
break;
case 3: //creat a new cell for up
break;
case 4: //creat a new cell for down
break;
default: break;
}
if(check_point()){
for(i=0;i<4;i++)
put_char((32+16*i),32,0,i+6); //print game over
return;
}
write_body();
display();
}
}
}
//-----------------------CPU initialization-----------------------------------
void init(void) {
TMOD=0x21 ; // (T1 MODE 2_send_flagME,T0 MODE 1_send_flagME)
TCON=0x51 ; //0101 0000 (TR1=1 , TR0=1
SCON=0x50 ; //0101 0000 (MODE 1 ;RECEIVE ENABLE)
IP=0x10 ; //0001 0000 (S-PORT HIGH interrupt)
IE=0x12 ; //0001 0010 (S_PORT AND TIME0 ENABLE INT)
TL1=TH1=0xfd; //9600bps
PCON=0x00; //SMOD=0
IE = 0x92;
TR1=0;
EA=1; // enable all interrupt
}
//-----------------------------------------------------------------------------
main(){
power=0;
lcd_power=0;
init();
init_lcd();
while(1){
game();
//------------------------------------------------
display();
while(1);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -