LCD控制時序:
LCD的初始化過程如下:
第一行顯示"Welcome";第二行顯示="Happy day";若要顯示其他字符,請直接往數組 LCMLineOne[16]和LCMLineTwo[16]填充相應的代碼。仿真圖(仿真是在Proteus7.4SP3下仿真通過)
源程序: #include<reg51.h> #define uchar unsigned char #define uint unsigned int #define busy 0x80 #define DataIO P0 sbit RS=P2^0; sbit RW=P2^1; sbit E=P2^7; uchar data LCDLineOne[16]="Welcome"; //第一行顯示的數據 uchar data LCDLineTwo[16]="Happy day"; //第二行要顯示的數據 void Delayms(uchar ms) //ms級別的延時 { uchar i,j; for(i=0;i<ms;i++) for(j=0;j<57;j++) ; } void delay12(uint z) { uint x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } void Fbusy() { uchar LCDStatus; do { DataIO=0xff; RS=0;RW=1; E=1; LCDStatus=DataIO; E=0; LCDStatus=(LCDStatus&busy); } while(LCDStatus!=0); } //寫指令寄存器 void LCDWriteC(uchar COMData) { Fbusy(); RS=0;RW=0; DataIO=COMData; E=1; E=0; } //讀指令寄存器 uchar LCDReadC() {uchar LCDStatus; Fbusy(); RS=0;RW=1; E=1; LCDStatus=DataIO; E=0; return(LCDStatus); } //讀數據寄存器 uchar LCDReadD(uchar addr) {uchar LCDStatus; Fbusy(); LCDWriteC(0x80+addr); RS=1;RW=1;E=0; E=1; E=0; LCDStatus=DataIO; return(LCDStatus); } //寫數據寄存器帶地址 void LCDWriteDAdd(uchar addr,uchar LCDData) { Fbusy(); LCDWriteC(0x80+addr); RS=1;RW=0; DataIO=LCDData; E=1; E=0; } //寫數據寄存器無地址 void LCDWriteD(uchar LCDData) { Fbusy(); RS=1;RW=0; DataIO=LCDData; E=1; E=0; } //初始化 void LCDInit(void) { Delayms(15); RS=0;RW=0; DataIO=0x38; E=1; E=0; Delayms(5); DataIO=0x38; E=1; E=0; Delayms(5); DataIO=0x38; E=1; E=0; Delayms(5); LCDWriteC(0x38); LCDWriteC(0x08); LCDWriteC(0x01); LCDWriteC(0x06); LCDWriteC(0x0c); } main() { uchar i; LCDInit(); DataIO=0xff; while(1) { LCDWriteC(0x80); //第一行DDRAM地址 for(i=0;i<16;i++) LCDWriteD(LCDLineOne[i]); LCDWriteC(0x80+0x40); //第二行DDRAM地址 for(i=0;i<16;i++) LCDWriteD(LCDLineTwo[i]); } }
這是采用時序的方式,另外也可以采用總線的方式來控制(見我的另外一篇文章http://www.zg4o1577.cn/mcu/1042.html ),總的來說,采用時序的方式可以讓我們更好的理解LCD的控制方法,而總線的方式則可以簡化程序。