单片机89S52小游戏1602显示
百度贴吧,中国南车1985编写C程序源码:/*猜图案小游戏,通过4*4矩阵键盘下注,键值按从上到下,从左到右依次为016。*/#include<reg52.h>#include "stdlib.h" /后面ran()随机函数调用,必须先声明#include<intrins.h>#include <string.h>/后面要调用strlen()函数,必须声明#define uchar unsigned char#define uint unsigned intsbit key_a=P10;sbit key_b=P11;sbit key_c=P12;sbit key_d=P13;sbit key_1=P14;sbit key_2=P15;sbit key_3=P16;sbit key_4=P17;sbit rs=P25;sbit rw=P26;sbit ep=P27;unsigned char code dis_num="0123456789abcdef"unsigned char code dis2='7','4','1','.','8','5','2','0','9','6','3','=','/','*','-','+','0'/键盘按键值unsigned char a8;uchar code zf188= /自定义字符字模表1 0x04,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 zf288=/自定义字符字模表2 0x04,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芯片时序表:RL,WH,EH为读状态,且由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为高脉冲(即LHL)。为写指令 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) /光标位置设定函数,因高定光标必须要求D71; if(row=1) lcd_wcmd(pos-1|0x80);/光标第一行位置设定函数0x00位开始, else lcd_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=015(起始列)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,tablez); /逐位显示数组内字符 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键盘扫描返回结果为015 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); else return 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();/初始化LCD P1=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,zf1i); /将自定义字符字模表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_numHP/100);delay(5);lcd_wdat(dis_numH