lcd12864液晶显示模块(带中文字库)的反白和多级菜单设计
介绍一下,本人单片机爱好者,目前正在学习和使用lcd12864液晶显示模块。在学习过程中,在反白和多级菜单上卡了很久,查阅了不少资料和书籍,最终得以解决。在这里写下反白部分程序及多级菜单编程思想,受资料影响可能部分程序并非原创。主要参考书籍是刘平老师编著的《深入浅出玩转51单片机》。以下程序亲测有效。若是言语有错漏之处,还请各位读者批评指正。
首先是带中文字库的lcd12864反白。在lcd12864的数据手册上有反白的控制指令,但实际上,12864只能对第一、三行同时反白,或者对第二、四行同时反白。不能完成任意反白某一行的任务。原因是在ST7920中第三行的DDRAM地址紧接第第一行的,第四行的DDRAM接第二行的。所以能同时反白两行而不是一行。解决办法是混用图形和字符显示。在ST7920中,字符显示的CGRAM与图形显示的GGRAM是独立的,而最后显示的结果是两个RAM中数据的异或。具体程序如下。
需要用到的程序:
uchar ReadDataLCD() //该程序是读lcd12864数据
{
uchar RdTemp=0;
ReadStatusLCD();
P0=0xff;
LCD_RS=1;
LCD_RW=1;
LCD_E=1;
RdTemp=P0;
LCD_E=0;
return(RdTemp);
}
void ClearScreen() //这是图形显示清屏
{
uchar i,j;
WriteCommandLCD(0x34, 1); //是写命令函数,0x34是指令,1是指需要检测忙状态
for(i=0;i<32;i++)
{
WriteCommandLCD(0x80+i, 1);
WriteCommandLCD(0x80, 1);
for(j=0;j<32;j++)
WriteDataLCD(0x00, 1); //是写数据函数,0x00是数据,1是指需要检测忙状态
}
WriteCommandLCD(0x36, 1);
}
void DrawDotLCD(uchar X,uchar Y,bit color) //该函数是在显示器上画一个点
{
uchar x_Byte,x_bit; //x_Byte表示横轴的大列(8+8个),x_bit是指具体的小列16个
uchar y_Byte,y_bit; //y_Byte表示上下屏,y_bit表示行,半屏32行
uchar RdOldH,RdOldL; //用来存放从lcd12864中读出的数据
x_Byte=X>>4; //计算大列,相当于X/16
x_bit=X&0x0f; //计算小列,相当于X%16
y_Byte=Y>>5;
y_bit=Y&0x1f;
WriteCommandLCD(0x34, 1);
WriteCommandLCD(0x80+y_bit, 1);
WriteCommandLCD(0x80+x_Byte+8*y_Byte, 1);
ReadDataLCD(); //空读一次,
RdOldH=ReadDataLCD();
RdOldL=ReadDataLCD();
WriteCommandLCD(0x80+y_bit, 1); //写垂直地址,读写lcdRAM会改变地址,所以再输入一次
WriteCommandLCD(0x80+x_Byte+8*y_Byte, 1); //写水平地址,下半屏地址为0x88
if(x_bit<8)
{
if(color)
{
WriteDataLCD((RdOldH|(0x01<<(7-x_bit))), 1);
}
else WriteDataLCD(RdOldH, 1);
WriteDataLCD(RdOldL, 1);
}
else
{
WriteDataLCD(RdOldH, 1);
if(color) WriteDataLCD((RdOldL|(0x01<<(15-x_bit))), 1);
else WriteDataLCD(RdOldL, 1);
}
WriteCommandLCD(0x36, 1);
}
void DrawLineLCD(uchar Xs,uchar Xe,uchar Y0,bit color) //写一行,Xs<Xe,Y0是用来选择行0~63,color=1反白
{
for(;Xs<=Xe;Xs++)
DrawDotLCD(Xs,Y0,color);
}
写到这里,就可以任意反白lcd12864的任意一小行了,具体反白多少,看读者自己的意愿。
再来说一下,lcd12864的多级菜单显示问题。经过查资料,我这里有两种方法实现。第一种是使用结构,使用结构的具体理论在这里不做过多阐述,有兴趣的读者可以自己查阅相关资料。对我来说,使用结构的方法稍显繁琐,因为我需要的多级菜单的级数较低。第二种是我自己想出来的,使用switch语句,将需要显示的内容提前写好放入各个case中,根据键盘按键的状态,选择需要显示的内容即可。两种方法各有利弊,结构的方法原理稍显复杂,不好理解;switch语句的方法原理简单,比较好上手,但是当菜单级数过多(大于3级),就会显得异常麻烦,需要许多变量来标记当前状态。读者可以根据需要选择合适的方法。
到这里就结束了,第一次发文,希望大家给予支持,对于错误的地方,欢迎批评指正。也希望能与各位读者进行交流。谢谢。