单片机89S52小游戏1602显示
单片机应用技术课程报告~1602LCD液晶显示屏的显示

单片机应用技术课程报告
实验名称1602LCD液晶显示屏的显示实验时间2020年 7月 9日学生姓名实验地点钉钉群线上
同组人员专业班级
1、实验目的
1、会使用单片机4个并行I/O端口连接外部设备并构建单片机最小应用系统。
2、能使用工具软件绘制单片机硬件原理图、能编写简LCD控制程序。
3、会使用LCD1602显示指定的内容。
2、任务设计要求
采用STC89C52单片机构建最小系统,在I/O口外接1602,编程实现在1602字符型LCD显示:实现字符的静态和动态显示。
显示字符为第一行:“I am xx”,第二行:“Hou are you”。
3、总体设计方案
根据实验任务要求,通过功能分析,设计的系统总体方案如图所示。
并
行接口AT89C51
单片机
电源
时钟电路
复位电路
实现led显示屏显示
4、硬件电路设计
5、软件程序设计
(2)程序清单
#include<reg51.h>
#include<intrins.h>//包含_nop_()空函数指令的头文件#define uchar unsigned char
#define uint unsigned int
#define out P0
sbit RS=P2^0;//位变量
sbit RW=P2^1;//位变量
sbit E=P2^2;//位变量
void lcd_ini();//LCD初始化函数
void check_busy();//检查忙标志函数
2)性能指标测试及结果分析。
基于单片机的1602液晶显示电路设计

本科毕业论文(设计)题目:基于单片机的1602液晶显示电路设计学生姓名:学号:系别:理工部专业:电气工程及其自动化入学时间:2012年09月导师姓名:职称/学位:基于单片机的1602液晶显示电路设计摘要本文是一篇介绍利用AT89S52单片机和LCD1602液晶显示屏设计一种液晶显示电路并编程实现信息的显示功能。
AT89S52是一种低功耗、高性能CMOS8位微控制器,具有8K系统可编程Flash存储器。
使用Atmel公司高密度非易失性存储器技术制造,与工业80C51产品指令和引脚完全兼容。
片上Flash允许程序存储器在系统可编程,亦适于常规编程器。
在单芯片上,拥有灵巧的8 位CPU 和在系统可编程Flash,使得AT89S52在众多嵌入式控制应用系统中得到广泛应用。
1602LCD是指显示的内容为16*2,即可以显示两行,每行16个字符液晶模块(显示字符和数字)。
从AT89S52单片机与LCD1602液晶显示器性能特点出发,实现两者接口的衔接设计。
经过多次的调试, 使得该设计取得了比较满意的结果, 且系统软硬件设计简单方便、稳定可靠, 可广泛应用于智能化仪器仪表及各种宣传场所, 为嵌入式控制系统提供高灵活、高性价比的解决方案。
关键词:AT89S52单片机;LCD1602液晶显示器;复位电路;时钟电路目录第一章前言 (2)1.1 研究现状 (2)1.2 研究意义 (2)第二章系统硬件电路设计 (3)2.1 AT89S52单片机最小系统 (3)2.1.1 主要性能 (3)2.1.2 功能 (3)2.1.3 引脚说明及实物图 (4)2.2 LCD1602液晶显示器 (7)2.2.1功能 (7)2.2.2 特点 (7)2.2.3 引脚 (7)2.3 复位电路 (9)2.4 时钟电路 (9)第三章软件设计 (10)3.1 软件设计思路 (10)3.1.1 Altium Designer (11)3.1.2 keil (11)3.1.3 AVR_fighter (11)3.2 程序设计 (12)第四章仿真及硬件电路 (15)第五章总结与展望 (17)主要参考文献 (18)致谢 (19)第一章前言本文是一篇研究基于AT89S52单片机的1602液晶显示电路设计,本次设计要求通过对单片机和1602液晶显示模块的学习,设计出完整的电路并焊出电路板,再对单片机写入程序,从而实现在液晶屏上显示出字符。
单片机1602显示程序

ORG 0000HAJMP STARTORG 0030H;液晶初始化START: MOV OUT,#01H;清屏LCALL WRMLMOV OUT,#38H;8为数据口,两行显示5*7点阵 LCALL WRMLMOV OUT,#06H;设置输入方式为光标向右移,屏幕上文字不移动LCALL WRMLMOV OUT,#0CH;设置显示方式,开显示屏LCALL WRML;第一行显示Hello!MOV OUT,#80H;设定第一行起始地址LCALL WRMLMOV R3,#80HMOV R4,#16MOV R5,#00HMOV DPTR,#TAB1WRIN1: LCALL DISPDJNZ R4,WRIN1;第二行逐字显示Nice to meet youMOV OUT,#0FH;设置显示方式,开显示屏,有光标,光标闪烁LCALL WRMLMOV OUT,#0C0H;设定第二行起始地址LCALL WRMLMOV R3,#0C0HMOV R4,#16MOV R5,#00HMOV DPTR,#TAB2WRIN2: LCALL DISPLCALL DELAYDJNZ R4,WRIN2MOV OUT,#08H;设置显示方式,关显示屏LCALL WRMLLCALL DELAYAJMP START;******************查表显示子程序******************DISP: PUSH AMOV A ,R5MOVC A,@A+DPTRMOV OUT,ALCALL WRDTINC R3INC R5POP ARET;*************判忙子程序************RDBF: MOV OUT,#0FFH;置位,准备读CLR RS;RS=0SETB RW ;R/W=1CLR ENOPSETB EJB OUT.7, RDBFRET;**************写命令子程序***************WRML: CLR RSCLR RWCLR ELCALL RDBFSETB ERET;*************写显示数据子程序*************WRDT: SETB RSCLR RW ;准备写入数据CLR E ;执行显示命令LCALL RDBF ;判断液晶模块是否忙?SETB ERET;*******************延时子程序*********** DELAY: MOV R6,#00HMOV R7,#00HDELAY1: NOPDJNZ R7,DELAY1DJNZ R6,DELAY1RETTAB1: DB 20H,20H,20H,20H,20H,48H,65H,6CH,6CH,6FH,21H ;Hello!DB 20H,20H,20H,20H,20HTAB2: DB 4EH,69H,63H,65H,20H,74H,6FH,20H,6DH,65H,65H ;Nice to meet youDB 74H,20H,79H,6FH,75HEND。
1602字符液晶显示原理+实例详解

1602详细资料和实例1602字符液晶在实际的产品中运用的也比较多了,前几天留意了一下,发现宿舍门前的自动售水机就是采用的1602液晶进行显示的。
而且对于单片机的学习而言,掌握1602的用法是每一个学习者必然要经历的过程。
在此,我将使用1602过程中遇到的问题以及感受记录下来,希望能够给初学者带来一点指导,少走一点弯路。
所谓1602是指显示的内容为16*2,即可以显示两行,每行16个字符。
目前市面上字符液晶绝大多数是基于HD44780液晶芯片的,控制原理是完全相同的,因此基于HD44780写的控制程序可以很方便地应用于市面上大部分的字符型液晶。
1602液晶的正面(绿色背光,黑色字体)1602液晶背面(绿色背光,黑色字体)另一种1602液晶模块,显示屏是蓝色背光白色字体字符型LCD1602通常有14条引脚线或16条引脚线的LCD,多出来的2条线是背光电源线VCC(15脚)和地线GND(16脚),其控制原理与14脚的LCD完全一样,引脚定义如下表所示:HD44780内置了DDRAM、CGROM和CGRAM。
DDRAM就是显示数据RAM,用来寄存待显示的字符代码。
共80个字节,其地址和屏幕的对应关系如下表:也就是说想要在LCD1602屏幕的第一行第一列显示一个"A"字,就要向DDRAM的00H地址写入“A”字的代码(指A的字模代码,0x20~0x7F为标准的ASCII码,通过这个代码,在CGROM中查找到相应的字符显示)就行了。
但具体的写入是要按LCD模块的指令格式来进行的,后面我会说到的。
那么一行可有40个地址呀?是的,在1602中我们就用前16个就行了。
第二行也一样用前16个地址。
对应如下:DDRAM地址与显示位置的对应关系。
(事实上我们往DDRAM里的00H地址处送一个数据,譬如0x31(数字1的代码,见字模关系对照表)并不能显示1出来。
这是一个令初学者很容易出错的地方,原因就是如果你要想在DDRAM的00H地址处显示数据,则必须将00H加上80H,即80H,若要在DDRAM的01H处显示数据,则必须将01H加上80H即81H。
基于AT89s52单片机1602四位数据口液晶显示

//*****************************************************************/*程序功能:显示两行字符并且整屏左移(程序使用在接口为4位的1602液晶)涉及芯片:1602液晶显示器*///*****************************************************************#include<reg52.h>#define uint unsigned int#define uchar unsigned charsbit rs=P2^0;//数据/命令选择端(H/L)sbit rw=P2^1;//读/写选择端(H/L)sbit en=P2^2; //使能选择端uchar code mingzi[]="Gci fa zhi !_! "; //定义数据mingzi【】uchar code num[]="tel:10778434282 "; //定义数组num【】void delay(uint time)//延时函数(运行的时间与晶振有关系){uint i,j;for(i=time;i>0;i--)for(j=110;j>0;j--);}void write_com(uchar mingling)//命令输入函数{uchar gao,di; //定义高、低四位gao=mingling&0xf0;//分出高四位di=(mingling<<4)&0xf0;//分出低四位//==========================================读走高四位P2=gao;//让数据(mingling)高四位有效rs=0;//rs端为低电平时,为接收命令delay(5);en=1; //en一个高脉冲读走高四位数据(mingling)delay(5);en=0;//把使能端拉回低电平//============================================读走低四位delay(5);P2=di;//让数据(mingling)低四位有效rs=0;//rs端为低电平时,为接收命令delay(5);en=1 ;//en一个高电平读走低四位命令(mingling)delay(5);en=0;//把使能端拉回低电平}void write_date(uchar shuju)//数据输入函数{uchar gao,di;gao=shuju&0xf0;//分出高四位di=(shuju<<4)&0xf0;//分出低四位//=======================================读走高四位P2=gao;//让数据(shuju)高四位有效rs=1;//rs端为高电平时,为接收数据delay(5);en=1;//en一个高电平读走低四位数据(shuju)delay(5);en=0;//把使能端拉回低电平//============================================读走低四位delay(5);P2=di;//让数据(shuju)低四位有效rs=1;//rs端为高电平时,为接收数据delay(5);en=1;//en一个高电平读走低四位数据(shuju)delay(5);en=0;//把使能端拉回低电平}void chushihua(){rw=0;//把数据/命令选择端先置为零en=0;//把使能端先置为零write_com(0x28);//设置16*12显示,5*7点阵,4位数据接口write_com(0x01);//清屏write_com(0x0c);//显示开启,不显示光标write_com(0x06);//整屏不移动}void main()//主函数{uint i,j;chushihua();//对液晶初始化while(1)//死循环{write_com(0x80);for(i=0;i<16;i++){write_date(mingzi[i]);}write_com(0x80+0x40);for(j=0;j<16;j++){write_date(num[j]);}write_com(0x18);//写控制字,在英文文档里介绍。
1602动态显示字符串的完整程序

#include<reg52.H>#include <stdio.h>#include<string.h>#define uchar unsigned charsfr lcd_data=0x80;sbit lcd_E=P0^0;sbit lcd_RW=P0^1;sbit lcd_RS=P0^2;sbit P3_4=P3^4;sbit P3_5=P3^5;sbit P3_6=P3^6;unsigned char code show1[]="Welcome"; unsigned char code show2[]="Friend"; unsigned char code show3[]="Welcome gj"; unsigned char code show4[]="Friendship"; unsigned char code show5[]="Welcome ftl"; unsigned char code show6[]="Friendship"; unsigned char code show7[]="Welcome wf"; unsigned char code show8[]="Friendship"; unsigned char temp;unsigned char key;uchar i,j,k;/****************************延时函数**************************//*函数原型:void f_v_delay5ms(void)/*函数功能:延时/*输入参数:无/*输出参数:无///**********************************************************************/void f_v_delay5ms(void){unsigned char i;unsigned char j;for(i=0;i<100;i++){for(j=0;j<250;j++);}}void f_v_delay50us(void){unsigned char i;for(i=0;i<50;i++){;}}void f_v_delay2ms(void){unsigned char i;unsigned char j;for(i=0;i<200;i++){for(j=0;j<50;j++);}}void f_v_delay10ms(void){f_v_delay5ms();f_v_delay5ms();}//*lcd显示*//****************************1602A读状态函数**************************//*函数原型:unsigned char f_uc_lcdReadStatus(void) /*函数功能:1602A读状态/*输入参数:无/*输出参数:1602A返回的状态/*调用模块:///**********************************************************************/void f_uc_lcdReadStatus(void){lcd_data=0xff;lcd_RS = 0;lcd_RW = 1;lcd_E = 1;f_v_delay50us();while(P2&0x80);//检测忙信号lcd_E = 0;}/****************************1602A写数据函数**************************//*函数原型:void f_v_lcdWriteData(unsigned charWDLCM)/*函数功能:1602A写数据/*输入参数:要写入的数?/*输出参数:无/*调用模块:/**********************************************************************/void f_v_lcdWriteData(unsigned char WDLCM){f_uc_lcdReadStatus(); //检测忙P2 = WDLCM;lcd_RS = 1;lcd_RW = 0;lcd_E = 1;//若晶振速度太高可以在这后加小的延时f_v_delay50us();//延时lcd_E = 0;}/****************************1602A写指令函数**************************//*函数原型:void f_v_lcdWriteCommand(unsigned charWCLCM,BuysC)/*函数功能:1602A写指令/*输入参数:要写入的指令/*输出参数:无/*调用模块:/**********************************************************************/void f_v_lcdWriteCommand(unsigned char WCLCM,unsigned char BuysC)/ /BuysC为0时忽略忙检测{if (BuysC)f_uc_lcdReadStatus();//根据需要检测忙P2 = WCLCM;lcd_RS = 0;lcd_RW = 0;lcd_E = 1;f_v_delay50us();//延时lcd_E = 0;}/****************************1602A读数据函数**************************//*函数原型:unsigned char f_v_lcdReadData(void)/*函数功能:1602A读数据/*输入参数:无/*输出参数:1602A返回的数据/*调用模块:/***********************************************************************//*unsigned char f_uc_lcdReadData(void){lcd_RS = 1;lcd_RW = 1;lcd_E = 0;lcd_E = 0;lcd_E = 1;return(lcd_data);}*//******************1602A按指定位置显示一个字符函数**********************//*函数原型:void f_v_displayOneChar(unsigne char X, unsigned char Y, unsigned char DData)/*函数功能:1602A按指定位置显示一个字符/*输入参数:X坐标Y坐标要显示的字符/*输出参数:无/*调用模块:/**********************************************************************/void f_v_displayOneChar(unsigned char X, unsigned char Y, unsigned ch ar DData){Y &= 0x1;X &= 0xF;//限制X不能大于15,Y不能大于1if (Y)X |= 0x40;//当要显示第二行时地址码+0x40;X |= 0x80;// 算出指令码f_v_lcdWriteCommand(X, 0);//这里不检测忙信号,发送地址码f_v_lcdWriteData(DData);}/*******************1602A按指定位置显示一串字符函数*********************//*函数原型:void f_v_displayListChar(unsigned charX, unsigned char Y, unsigned char code *DData)/*函数功能:1602A按指定位置显示一个字符/*输入参数:X坐标Y坐标要显示字符串的首地址/*输出参数:/**********************************************************************/void f_v_displayListChar(unsigned char X, unsigned char Y, unsigned cha r *DData){unsigned char ListLength;ListLength = 0;Y &= 0x1;X &= 0xF;//限制X不能大于15,Y不能大于1while (DData[ListLength]>=0x20)//若到达字串尾则退出{if (X <= 0xF)//X坐标应小于0xF{f_v_displayOneChar(X, Y, DData[ListLength]);//显示单个字符ListLength++;X++;}}}/****************************1602A初始化函数**************************//*函数原型:void f_v_lcdInit(void)/*函数功能:1602A初始化/*输入参数:无/*输出参数:无/*调用模块://**********************************************************************/void f_v_lcdInit(void){lcd_data = 0;f_v_lcdWriteCommand(0x38,0);//三次显示模式设置,不检测忙信号f_v_delay5ms();f_v_lcdWriteCommand(0x38,0);f_v_delay5ms();f_v_lcdWriteCommand(0x38,0);f_v_delay5ms();f_v_lcdWriteCommand(0x38,1);//显示模式设置,开始要求每次检测忙信号f_v_lcdWriteCommand(0x08,1);//关闭显示f_v_lcdWriteCommand(0x01,1);//显示清屏f_v_delay2ms();f_v_lcdWriteCommand(0x06,1);// 显示光标移动设置f_v_lcdWriteCommand(0x0C,1);// 显示开及光标设置}/////////////////////////////////////////////////////////////////////////////*喂狗程序*//*void f_v_watchDog(){dog=1;;;;;;;;dog=0;}*/////////////////////////////////////////////////// ///////////////////////////*void f1(){f_v_delay10ms();f_v_delay10ms();f_v_lcdInit();f_v_delay10ms();f_v_delay10ms();f_v_displayListChar(0,0,show1); f_v_displayListChar(0,1,show2); }void f2(){f_v_delay10ms();f_v_delay10ms();f_v_lcdInit();f_v_delay10ms();f_v_delay10ms();f_v_displayListChar(0,0,show3); f_v_displayListChar(0,1,show4); }void f3(){f_v_delay10ms();f_v_delay10ms();f_v_lcdInit();f_v_delay10ms();f_v_delay10ms();f_v_displayListChar(0,0,show5);f_v_displayListChar(0,1,show6);}*/void main(void){i="0";j="0";while(1){/* for(i=0;i<10;i++){;f_v_lcdInit();;f_v_displayListChar(i,0,show1);f_v_displayListChar(i,1,show2);;}for(i=10;i<16;i++){;f_v_lcdInit();;for(j=0;j<7;j++){f_v_displayOneChar((i+j)%16,0,show1[j]);f_v_displayOneChar((i+j)%16,1,show2[j]); ;}}*/for(i=0;i<16;i++){;f_v_lcdInit();;for(j=0;j<strlen(show1);j++){f_v_displayOneChar((i+j)%16,0,show1[j]);;}for(j=0;j<strlen(show2);j++){f_v_displayOneChar((i+j)%16,1,show2[j]); ;}}}}。
单片机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)。
基于89c52单片机LCD1602滚动显示的程序

#include "reg52.h"//此文件中定义了单片机的一些特殊功能寄存器
#include "lcd.h"
typedef unsigned int u16;//对数据类型进行声明定义
typedef unsigned char u8;
u8 a[16]="perchin designed";
{
LcdWriteData(a[i]);
}
LcdWriteCom(0x40+0x80);
for(i=0;i<27;i++)
{
LcdWriteData(b[i]);
}
LcdWriteCom(0x07);//每写一个数据屏幕就要右移一位,就相对于数据来说就是左移了;
while(1)
{
LcdWriteCom(0x00+0x80);
{
uchar a,b;
for (; c>0; c--)
{
for (b=199;b>0;b--)
{
for(a=1;a>0;a--);
}
}
}
/**************************************************************************
* 函 数 名 : LcdWriteCom
Lcd1602_Delay1ms(5); //保持时间
LCD1602_E = 0;
}
#else
void LcdWriteData(uchar dat)//写入数据
{
LCD1602_E = 0;//使能清零
LCD1602_RS = 1;//选择写入数据
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
百度贴吧,中国南车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();}}。