//由于2051的IO不夠用,必須省出IO口,迫不得已,又根據大量資料對程序進行了修改 //得到如下能夠成功運行的程序。本程序在STC89C51RC@12MHz 4位總線模式下通過data image CM1640液晶模塊 //yusung W-1602A液晶模塊,廣州捷勝 1602A V1.0模塊的測試,均可正常寫入。 #include < reg51.h> sbit rs=P3^5;//指令數據選擇 sbit rw=P2^7;//讀寫選擇 sbit clk=P3^4;//使能脈沖 unsigned char code Logo_text1[]="[China O Soft!] ";//文字數組 unsigned char code Logo_text2[]="Soldering iron. ";//文字數組 unsigned char code Logo_text3[]={'V','o','l','t',':','2','0','V',' ','S','e','t','3','0','0',0xdf};//文字數組 unsigned char code Logo_text4[]={'P','o','w','e','r',':','2','0','W',' ','C','T','2','9','5',0xdf};//文字數組 unsigned char m;//輔助尋址指針變量 sbit clear = P3^2;//清屏按鈕 sbit key1 = P3^4;//寫第一行按鈕 sbit key2 = P3^5;//寫第二行按鈕 sbit key3 = P3^6;//顯示模式變更測試按鈕 void delay2ms()//2064周期延時 { unsigned char temP0; while(--temp1); while(--temp1); while(--temp1); while(--temp1); } void delay() { unsigned char temp1,temp2; temp1=50; while(--temp1) while(--temp2); } void check_busy()//忙檢測 { unsigned char busy;//臨時字節 do { rs=0;//選擇寄存器 rw=1;//讀取 clk=1;//LCD將數據放到總線 busy=P0;//讀入總線數據 clk=0;//關閉總線 busy=busy&0x80;//保留最高位 }while(busy);//判斷是否為忙 } void instructions(unsigned char INS)//寫指令函數 { check_busy();//寫之前檢測忙 rs=0;//選擇指令寄存器 rw=0;//寫操作 clk=1;//準備下降沿 P0=INS;//數據放到總線上 clk=0;//下降沿,數據寫入LCD clk=1;//準備下降沿 P0=INS<<4;//數據放到總線上 clk=0;//下降沿,數據寫入LCD } void write_data(unsigned char dat)//寫數據函數 { check_busy();//寫之前檢測忙 rs=1;//選擇數據寄存器 rw=0;//寫操作 clk=1;//準備下降沿 P0=dat;//數據放到總線上 clk=0;//下降沿,數據寫入LCD clk=1;//準備下降沿 P0=dat<<4;//數據放到總線上 clk=0;//下降沿,數據寫入LCD } void lcd_clear()//清除顯示函數 { instructions(0x01);//清除顯示 delay2ms();//清屏后,按手冊至少應延時1.53ms } void set_4bit_mode() { check_busy();//寫之前檢測忙 rs=0;//選擇指令寄存器 rw=0;//寫操作 clk=1;//準備下降沿 P0=0x2f;//4位總線控制字 clk=0;//下降沿,數據寫入LCD } void lcd_init() { rw=0;//寫操作 set_4bit_mode();//設置成4位總線模式. delay2ms();//按手冊應至少延時39us,但由于執行次數不多,統一使用2ms延時 instructions(0x0f);//設置輸入模式為8位數據總線,光標增量移動,顯示不移位 delay2ms();//按手冊應至少延時39us,但由于執行次數不多,統一使用2ms延時 instructions(0x06);//開顯示,關閉光標,不閃爍 delay2ms();//按手冊應至少延時39us,但由于執行次數不多,統一使用2ms延時 lcd_clear();//調用清屏函數 instructions(0x80+0x00);//寫入顯示緩沖區起始地址為1行1列 delay2ms();//按手冊應至少延時39us,但由于執行次數不多,統一使用2ms延時 for(m=0;m<16;m++)//將預先定義好的字符連續發送到LCD { write_data(Logo_text1);//通過輔助變量查詢數組并寫入LCD delay(); } instructions(0x80+0x40);//寫入顯示緩沖區起始地址為2行1列 delay2ms();//按手冊應至少延時39us,但由于執行次數不多,統一使用2ms延時 for(m=0;m<16;m++)//將預先定義好的字符連續發送到LCD { write_data(Logo_text2);//通過輔助變量查詢數組并寫入LCD delay(); } } void main() { lcd_init();//LCD初始化 while(1) { if(!key1)//判斷按鍵是否按下 { instructions(0x80+0x10);//寫入顯示緩沖區起始地址為1行1列 delay2ms();//按手冊應至少延時39us,但由于執行次數不多,統一使用2ms延時 for(m=0;m<16;m++)//將預先定義好的字符連續發送到LCD { write_data(Logo_text3);//通過輔助變量查詢數組并寫入LCD } } if(!key2)//判斷按鍵是否按下 { instructions(0x80+0x50);//寫入顯示緩沖區起始地址為2行1列 delay2ms();//按手冊應至少延時39us,但由于執行次數不多,統一使用2ms延時 for(m=0;m<16;m++)//將預先定義好的字符連續發送到LCD { write_data(Logo_text4);//通過輔助變量查詢數組并寫入LCD } } if(!clear)//判斷按鍵是否按下 { lcd_clear();//調用清屏函數 } if(!key3)//判斷按鍵是否按下 { instructions(0x0c);//改變顯示模式 delay2ms();//按手冊應至少延時39us,但由于執行次數不多,統一使用2ms延時 } } }