当前位置:文档之家› 单片机89S52小游戏1602显示

单片机89S52小游戏1602显示

百度贴吧,中国南车1985编写C程序源码:/*********************************************猜图案小游戏,通过4*4矩阵键盘下注,键值按从上到下,从左到右依次为0~16。

**********************************************/#include<reg52.h>#include "stdlib.h" //后面ran()随机函数调用,必须先声明#include<intrins.h>#include <string.h> //后面要调用strlen()函数,必须声明#define uchar unsigned char#define uint unsigned intsbit key_a=P1^0;sbit key_b=P1^1;sbit key_c=P1^2;sbit key_d=P1^3;sbit key_1=P1^4;sbit key_2=P1^5;sbit key_3=P1^6;sbit key_4=P1^7;sbit rs=P2^5;sbit rw=P2^6;sbit ep=P2^7;unsigned char code dis_num[]={"0123456789abcdef"};unsigned char code dis2[]={'7','4','1','.','8','5','2','0','9','6','3','=','/','*','-','+','\0'};//键盘按键值unsigned char a[8];uchar code zf1[8][8]={//自定义字符字模表10x04,0x0e,0x0f,0x1f,0x1e,0x0e,0x04,0x00, //方块0x04,0x0e,0x1f,0x1f,0x1f,0x04,0x0e,0x00,0x0e,0x0e,0x1f,0x1f,0x1f,0x04,0x0e,0x00,0x00,0x0a,0x1f,0x1f,0x1f,0x0e,0x04,0x00,0x04,0x04,0x0e,0x1f,0x0e,0x04,0x04,0x00,0x1b,0x1b,0x00,0x1b,0x00,0x1b,0x1b,0x00,0x04,0x04,0x1b,0x04,0x1b,0x04,0x04,0x00,0x04,0x0c,0x1c,0x1e,0x0f,0x06,0x04,0x00};uchar code zf2[8][8]={//自定义字符字模表20x04,0x0e,0x1e,0x1b,0x0f,0x0e,0x04,0x00,0x09,0x1b,0x1f,0x0e,0x1f,0x1b,0x12,0x00,0x0e,0x1f,0x1f,0x1f,0x1f,0x1f,0x0e,0x00,0x1f,0x1f,0x15,0x1f,0x15,0x1f,0x1f,0x00,0x0e,0x0a,0x04,0x15,0x15,0x0e,0x04,0x00,0x04,0x1f,0x15,0x04,0x0e,0x1b,0x0e,0x00,0x00,0x00,0x0a,0x00,0x11,0x0e,0x00,0x00,0x0e,0x11,0x1b,0x11,0x15,0x1b,0x0e,0x00};void delay(unsigned char ms) //延时函数{unsigned char i;while(ms--){for(i=0;i<250;i++){_nop_();_nop_();_nop_();_nop_();}}}bit lcd_bz() //测忙函数{bit result;rs=0; //1602的HD44780芯片时序表:R=L,W=H,E=H为读状态,且由D7位输出状态:H为忙,L为不忙rw=1;ep=1;_nop_();_nop_();_nop_();_nop_();result=(bit)(P0&0x80); //判断D7位状态并赋给result返回ep=0;return result;}void lcd_wcmd(unsigned char cmd) //写指令函数{while(lcd_bz());//判断LCD是否忙碌每次读写指令必须先测忙rs=0; //S=L,W=L,e为高脉冲(即L-H——L)。

为写指令 rw=0;ep=0;_nop_();_nop_();P0=cmd;_nop_();_nop_();_nop_();_nop_();ep=1;_nop_();_nop_();_nop_();_nop_();ep=0;}void lcd_pos(unsigned char row,pos) //光标位置设定函数,因高定光标必须要求D7=1;{if(row==1)lcd_wcmd(pos-1|0x80); //光标第一行位置设定函数0x00位开始,elselcd_wcmd(pos-1|0xc0); //光标第二行位置设定函数起始位0x40,}void lcd_wdat(unsigned char dat) //写数据函数{while(lcd_bz());//判断LCD是否忙碌rs=1;rw=0;ep=0;P0=dat;_nop_();_nop_();_nop_();_nop_();ep=1;_nop_();_nop_();_nop_();_nop_();ep=0;}void dis_lcd_byte(uchar y,uchar x,uchar z) //Y=0,1(起始行)X=0~15(起始列)Z=想写字符的ASCII码{if(y>=2) //是否显示在第二行(若在第一行Y=0,不进入IF语句,若在第二行,进入IF语句{x+=0x40; //第二行起始地址加上列数为字符显示地址}x+=0x80; //设置数据指针位置lcd_wcmd(x);lcd_wdat(z); //写入数据}void dis_lcd_text(unsigned char y,unsigned char x,unsigned char table[]) //Y,X同上字符显示,table[]字符串数组{unsigned char z=0;unsigned char t;t=strlen(table)+x; // 求得字符串长度加上起始列位置while(x<t) //功能为LCD显示到字符串最后一个字符,防止字符串{ //没有16个字符,从而不够位产生乱码;dis_lcd_byte(y,x,table[z]); //逐位显示数组内字符x++;z++;}}void lcd_init() //初始化LCD函数{delay(15);lcd_wcmd(0x38);delay(5);lcd_wcmd(0x38);delay(5);lcd_wcmd(0x38);delay(5);lcd_wcmd(0x38);delay(1);lcd_wcmd(0x08);delay(1);lcd_wcmd(0x0c);delay(1);lcd_wcmd(0x06);delay(1);lcd_wcmd(0x01);delay(1);}void lcd_cls() //清屏函数{lcd_wcmd(0x01);}unsigned char key_scan() //键盘扫描函数,4*4键盘扫描返回结果为0~15 {unsigned char i,key;unsigned char k=88;P1=0xf0;if(P1!=0xf0){P1=0xfe;for(i=0;i<4;i++){key=P1&0xf0;switch(key){case 0xe0:k=i;break;case 0xd0:k=i+4;break;case 0xb0:k=i+8;break;case 0x70:k=i+12;break;default: ;}P1=(P1<<1)+1;if(k!=88)break;}P1=0xf0;while(P1!=0xf0);return(k);}elsereturn 16;}void my_word(uchar wei,uchar *zf) //自定义字符函数{uchar j;wei=wei<<3;for(j=0;j<8;j++){lcd_wcmd(0x40|wei+j); //自定义字符地址delay(1); //延迟,否则容易出错lcd_wdat(*zf++); //自定义字符字模}}void main(void){unsigned int j,i,HP,ran,sum8;lcd_init();//初始化LCDP1=0xf0;dis_lcd_text(0,0," Made by:");dis_lcd_text(2,0," CSR1985");while(P1==0xf0);while(P1!=0xf0);start:lcd_wcmd(0x01);HP=100;while(1){for(i=0;i<8;i++)my_word(i,zf1[i]); //将自定义字符字模表1写入CGRAM dis_lcd_text(0,0,"Ready go !");lcd_wcmd(0x0f); //光标闪烁while(P1==0xf0);delay(10);while(P1!=0xf0);lcd_wcmd(0x0c); //关光标lcd_cls();delay(5);lcd_wdat('H');delay(5); //延迟一下,否则容易出错显示不出来lcd_wdat('P');delay(5);lcd_wdat('=');delay(5);lcd_wdat(dis_num[HP/100]);delay(5);lcd_wdat(dis_num[HP%100/10]);delay(5);lcd_wdat(dis_num[HP%10]);for(j=0;j<8;j++)dis_lcd_byte(1,8+j,j); //从CGRAM输出8个自定义字符dis_lcd_text(2,0,"Choose 00000000");xz:lcd_pos(2,9); //下注开始处光标设定为第二行第9个,并在此行程序做好标记XZlcd_wcmd(0x0f);for(i=0;i<8;i++){while(P1==0xf0);delay(10);a[i]=key_scan(); //用键盘下注for(j=0;j<8;j++)sum8=sum8+a[j]; //8个下注分求总和后是否为零,为零那么回到XZ处重新下注,避免全押零分开结果if(i==7&&sum8==0)goto xz;sum8=0; //下注总和清零if(HP>=a[i]) //判断总分是否够下注HP=HP-a[i];else{a[i]=HP;HP=0;}lcd_pos(1,4);lcd_wdat(dis_num[HP/100]);delay(5);lcd_wdat(dis_num[HP%100/10]);delay(5);lcd_wdat(dis_num[HP%10]);delay(5);lcd_pos(2,9+i);lcd_wdat(dis_num[a[i]]); //输出下注分数delay(5);while(P1!=0xf0);}lcd_wcmd(0x0c);while(P1==0xf0);while(P1!=0xf0);ran=TL1;j=rand(); //随机一个数作为结果j=j%8;a[j]=a[j]*(2*j+1); //所得分等于所押下注分数乘以对应倍数lcd_pos(2,1);delay(5);for(i=0;i<6;i++)lcd_wdat(j); //输出5个结果图形HP=HP+a[j]; //总分加上得分lcd_pos(1,4);lcd_wdat(dis_num[HP/100]);delay(5);lcd_wdat(dis_num[HP%100/10]);delay(5);lcd_wdat(dis_num[HP%10]);delay(5);if(HP==0) //判断HP是否为零,为零则输掉了游戏 {delay(5);dis_lcd_text(2,0,"YOU LOST GAME !!");while(1){if(key_scan()==15) //按f键重来一局{lcd_wcmd(0x01);dis_lcd_text(0,0," Try again? ");while(P1==0xf0); //任意键重来while(P1!=0xf0);goto start;}}}if(HP>800) //判断HP如果到了800,则赢得了比赛 {delay(5);dis_lcd_text(2,0," YOU WIN !! ");while(1){if(key_scan()==15){lcd_wcmd(0x01);dis_lcd_text(0,0,"Try again?");while(P1==0xf0);while(P1!=0xf0);goto start;}}}while(P1==0xf0); while(P1!=0xf0); lcd_cls();}}。

相关主题