5软件设计
5.1 LCD12864模块初始化流程
POWER ON 上电 延时>37ms RESET LOW→HIGH FUNCTION SET 功能设定 控制字 30H RS 0 R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 0 0 0 1 1 X 0 X X 延时>100us FUNCTION SET 功能设定 控制字 30H RS 0 R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 0 0 0 1 1 X 0 X X 延时>37us DISPLAY ON/OFF CONTROL 显示开/关 控制字0FH RS 0 R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 0 0 0 0 0 1 D C B 延时>100us
16
DISPLAY CLEAR 清除屏幕 控制字:01H RS 0 R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 0 0 0 0 0 0 0 0 1 延时>10ms ENTRY MODEL SET 进入模式设置 控制字:06H RS 0 R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 0 0 0 0 0 0 1 I/D S INITIALIZATION END 初始化结束 图5.1 LCD12864初始化流程图
5.2部分程序代码
5.2.1软件延时
延时程序是本设计中很重要的一部分,因为延时时间的长短不仅能决定该LCD模块能否成功初始化,还决定了人眼能不能看到稳定的显示。在本设计中有两个延时程序,以满足不同延时时间的需要。而且,第二个延时程序的延时时间比第一个延时程序延时时间长。
void delay1(unsigned int t) {
unsigned int j;
17
for( ;t>0;t--)
for (j=19;j>0;j--); }
void delay2(unsigned int t) {
unsigned int j; for( ;t>0;t--)
for (j=6425;j>0;j--); }
5.2.2 端口输出函数
由于本设计中从ATMEGA8单片机中的I/O口输出数据时没有使用某个整体的I/O口,只是使用了其中某个I/O口的一部分。所以传送地址数据时,不能整体传送,只能逐位传送。而本设计中,又需多次使用数据传送。所以为了简便起见,则写了一个从I/O口输出8位数据的write函数,以供传送数据使用。
void write(unsigned char z) {
if ((z&0x01)==0x01)PORTC|=0x08;//0000,1000 PC3=1 else PORTC&=0xf7;//1111,0111 PC3=0
if ((z&0x02)==0x02)PORTC|=0x10;//0001,0000 PC4=1 else PORTC&=0xef;//1110,1111 PC4=0
if ((z&0x04)==0x04)PORTC|=0x20;//0010,0000 PC5=1 else PORTC&=0xdf;//1101,1111 PC5=0
if ((z&0x08)==0x08)PORTB|=0x01;//0000,0001 PB0=1 else PORTB&=0xfe;//1111,1110 PB0=0
if ((z&0x10)==0x10)PORTB|=0x02;//0000,0010 PB1=1 else PORTB&=0xfd;//1111,1101 PB1=0
if ((z&0x20)==0x20)PORTB|=0x04;//0000,0100 PB2=1 else PORTB&=0xfb;//1111,1011 PB2=0
if ((z&0x40)==0x40)PORTB|=0x08;//0000,1000 PB3=1 else PORTB&=0xf7;//1011,1111 PB3=0
if ((z&0x80)==0x80)PORTB|=0x10;//0001,0000 PB4=1 else PORTB&=0xef;//1110,1111 PB4=0 }
5.2.3 写数据函数
由3.2.4中的8位并行时序图及RS、RW功能设定示意图知,RS为高电平时,表示写数据。当RW为低电平时,表示MPU写资料到模块。当E为低电平时,延时一
18
会儿,向I/O口准备数据,到E为高电平时,没有变化。再当E为高电平后,延时一会儿,令E为低电平,则数据写入完全。最后使RW为高电平,RS为低电平,指令书写完成。
void write_12864dat(unsigned char a) {
PORTC|=0x01;//0000,0001 rs=1 PC0=1 写数据 PORTC&=0xfd;//1111,1101 rw=0 PC1=0 PORTC&=0xfb;//1111,1011 e=0 PC2=0 delay1(1); write(a);
PORTC|=0x04;//0000,0100 e=1 PC2=1 delay1(10);
PORTC&=0xfb;//1111,1011 e=0 PC2=0 delay1(2);
PORTC|=0x02;//0000,0010 rw=1 PC1=1 PORTC&=0xfe;//1111,1110 rs=0 PC0=0 }
5.2.4 写指令函数
由3.2.4中的8位并行时序图及RS、RW功能设定示意图知,RS为低电平时,表示写指令。当RW为低电平时,表示MPU写资料到模块。当E为低电平时,延时一会儿,向I/O口准备数据,到E为高电平时,没有变化。再当E为高电平后,延时一会儿,令E为低电平,则数据写入完全。最后使RW为高电平,RS为低电平,指令书写完成。
void write_12864com(unsigned char b) {
PORTC&=0xfe;//1111,1110 rs=0 PC0=0 写指令 PORTC&=0xfd;//1111,1101 rw=0 PC1=0 PORTC&=0xfb;//1111,1011 e=0 PC2=0 delay1(1); write(b);
PORTC|=0x04;//0000,0100 e=1 PC2=1 delay1(10);
PORTC&=0xfb;//1111,1011 e=0 PC2=0
19
delay1(2);
PORTC|=0x02;//0000,0010 rw=1 PC1=0 PORTC&=0xfe;//1111,1110 rs=0 PC0=0 }
5.2.5 初始化函数
要使LCD12864模块显示汉字,必须对该模块进行初始化。由图5.1初始化流程图可知,先打开电源,等待大于40ms,再进行复位操作。本设计是直接将复位端接高电平。之后写入控制字,进行功能设定。接着延时等待,再进行显示开关控制字设定,其中D=1、整体显示ON,C=1、游标ON,B=1、游标位置ON。之后,进行清屏设置。最后,进行模式选择设置,初始化过程结束。
void initinal(void) {
delay2(20);
write_12864com(0x30);//写控制字30H delay1(4);
write_12864com(0x30);//写控制字30H delay1(4);
write_12864com(0x0f);// DCB均为一 delay1(4);
write_12864com(0x01);//清屏设置01H delay2(20);
write_12864com(0x06);//模式设置06H delay1(10); }
5.2.6 显示函数
RAM在液晶中的地址为80H~9FH,地址指针自动加一,将汉字地址送入写指令和写数据函数,即可显示汉字。本显示函数功能是显示一首古诗《锄禾》。
20