先上仿真圖,圖比較簡單,一個51單片機最小系統,加上一個LM016L液晶顯示器,需要注意的是,實際的LM016L晶片內部有上拉電阻,但是仿真中是沒有的,如果用P0口傳輸數據的話,需要給P0口接上拉電阻。
然後上代碼,有詳細的注釋,就不多解釋了。
include<intrins.h>//引腳定義sbit RS=P2^0;sbit RW=P2^1;sbit E=P2^2;sbit BF=P0^7;void delay1ms(){unsigned char i,j;for(i=0;i<10;i++)for(j=0;j<33;j++);}/*****************************************************函數功能:延時若干毫秒入口參數: n***************************************************/void delaynms(unsigned char n){unsigned char i;for(i=0;i<n;i++)delay1ms();}/********************函數功能:判斷液晶模塊是否忙碌入口參數:無返回值:result 1忙碌 0空閒**********************/bit BusyTest(void){bit result;RS=0;RW=1;//此時才可以讀狀態E=1;//此時才允許讀寫_nop_();_nop_();_nop_();_nop_();//四個空操作,給硬體反應時間result=BF;//將忙碌標值賦值給resultE=0;return result;}/*****************************************************函數功能:將模式設置指令或顯示地址寫入液晶模塊入口參數: dictate***************************************************/void WriteInstruction(unsigned char dictate){while(BusyTest()==1);RS=0;RW=0;E=0;_nop_();_nop_();P0=dictate;_nop_();_nop_();_nop_();_nop_(); // 空操作四個機器周期,給硬體反應時間E=1;_nop_();_nop_();_nop_();_nop_(); // 空操作四個機器周期,給硬體反應時間E=0;}/*****************************************************函數功能:指定字符顯示的實際地址入口參數: x***************************************************/void WriteAddress(unsigned char x){WriteInstruction(x|0x80); // 顯示位置的確定方法規定為 &34;}/*****************************************************函數功能:將數據 (字符的標準 ASCII 碼) 寫入液晶模塊入口參數: y( 為字符常量 )***************************************************/void WriteData(unsigned char y){while(BusyTest()==1);RS=1; //RS 為高電平, RW為低電平時,可以寫入數據RW=0;E=0; //E 置低電平 ( 根據表 8-6 ,寫指令時, E 為高脈衝,// 就是讓 E 從 0 到 1 發生正跳變,所以應先置 &34;P0=y; // 將數據送入 P0 口,即將數據寫入液晶模塊_nop_();_nop_();_nop_();_nop_(); // 空操作四個機器周期,給硬體反應時間E=1; //E 置高電平_nop_();_nop_();_nop_();_nop_(); // 空操作四個機器周期,給硬體反應時間E=0; // 當 E 由高電平跳變成低電平時,液晶模塊開始執行命令}/*****************************************************函數功能:對 LCD的顯示模式進行初始化設置***************************************************/void LcdInitiate(void){delaynms(15); // 延時 15ms,首次寫指令時應給 LCD一段較長的反應時間WriteInstruction(0x38); // 顯示模式設置: 16×2 顯示, 5×7 點陣, 8 位數據接口delaynms(5); // 延時 5ms ,給硬體一點反應時間WriteInstruction(0x38);delaynms(5); // 延時 5ms ,給硬體一點反應時間WriteInstruction(0x38); // 連續三次,確保初始化成功delaynms(5); // 延時 5ms ,給硬體一點反應時間WriteInstruction(0x0c); // 顯示模式設置:顯示開,無光標,光標不閃爍delaynms(5); // 延時 5ms ,給硬體一點反應時間WriteInstruction(0x06); // 顯示模式設置:光標右移,字符不移delaynms(5); // 延時 5ms ,給硬體一點反應時間WriteInstruction(0x01); // 清屏幕指令,將以前的顯示內容清除delaynms(5); // 延時 5ms ,給硬體一點反應時間}void main(void){LcdInitiate(); // 將液晶初始化WriteAddress(0x01); // 寫 Date 的顯示地址 , 將在第 1 行第 2 列開始顯示WriteData(&39;); // 將字符常量寫入 LCDWriteData(&39;); // 將字符常量寫入 LCDWriteData(&39;); // 將字符常量寫入 LCDWriteData(&39;); // 將字符常量寫入 LCDWriteData(&39;); // 將字符常量寫入 LCDWriteData(&39;); // 將字符常量寫入 LCDWriteData(&39;); // 將字符常量寫入 LCDWriteData(&39;); // 將字符常量寫入 LCDWriteData(&39;); // 將字符常量寫入 LCD}