1. 程式人生 > >51微控制器簡單的驅動LCD1602

51微控制器簡單的驅動LCD1602

目錄

【LCD1602】

什麼是LCD1602

LCD1602管腳

狀態字

RAM地址對映

控制器介面時序

基本操作時序

指令介紹

電路圖

【程式】


CSDN始於python,終究還是要回到自己老本行,學一學py只是一時興起,為了自己興趣,電信才是自己的真愛。

【LCD1602】

什麼是LCD1602

LCD1602是一種工業字元型液晶,能夠同時顯示16x02即32個字元。LCD1602液晶顯示的原理是利用液晶的物理特性,通過電壓對其顯示區域進行控制,即可以顯示出圖形。

1602液晶也叫1602字元型液晶,它是一種專門用來顯示字母、數字、符號等的點陣

型液晶模組。它由若干個5X7或者5X11等點陣字元位組成,每個點陣字元位都可以顯示一個字元,每位之間有一個點距的間隔,每行之間也有間隔,起到了字元間距和行間距的作用,正因為如此所以它不能很好地顯示圖形(用自定義CGRAM,顯示效果也不好)。

1602LCD是指顯示的內容為16X2,即可以顯示兩行,每行16個字元液晶模組(顯示字元和數字)。

市面上字元液晶大多數是基於HD44780液晶晶片的,控制原理是完全相同的,因此基於HD44780寫的控制程式可以很方便地應用於市面上大部分的字元型液晶。

注意:LCD1602僅能顯示字母、符號或數字,無法顯示漢字。

LCD1602管腳

狀態字

RAM地址對映

控制器介面時序

1、讀操作時序

2、寫操作時序

3、時序引數

基本操作時序

1602的基本操作時序一共有4個,下面一一介紹。

寫程式前我們先將用到的匯流排介面做一個同意宣告:

#define LCD1602_DB P2			//並行輸入口
sbit LCD1602_RS = P0^5;			//資料/命令選擇端
sbit LCD1602_RW = P0^6;			//讀寫選擇端
sbit LCD1602_EN = P0^7;			//使能端	

<1>讀狀態:RS = L,R/W = H,EN = H

LCD1602_DB = 0xFF;
LCD1602_RS = 0;
LCD1602_RW = 1;
LCD1602_EN = 1;
sta = LCD1602_DB;

這樣就把當前液晶的狀態字讀到了sta這個變數中,可以通過判斷sta最高位的值來了解當前液晶是否處於“忙”狀態,也可以得知當前資料的指標位置。

<2>讀資料:RS = H,R/W = H,EN = H

在實際使用時,讀資料很少使用,大家可以僅瞭解就行。

<3>寫指令:RS = L,R/W = L,D0~D7 = 指令碼,EN = 高脈衝

在這裡就E = 高脈衝需要了解一下。因為這一句很關鍵,當前狀態是寫資料,根據時序圖,首先保證EN引腳是低電平狀態,不管前三句之前怎麼設定,1602這裡EN引腳沒有使能控制,就不會讀總線上的訊號。當前三句準備好之後,讓EN引腳從低電平到高電平變化,然後EN引腳再從高電平到低電平出現一個下降沿,1602檢測到這個下降沿之後,並且檢測到RS = L,R/W = L,就會馬上讀取D0~D7的資料,完成微控制器寫1602指令的過程。

歸納:EN使能引腳先低拉高,再從高拉低,形成一個高脈衝。

<4>寫資料:RS = H,R/W = L,D0~D7 = 資料,EN = 高脈衝

寫資料與寫指令類似,就是把RS改成H,把匯流排改成資料而已。

指令介紹

1、顯示模式設定

寫指令0x38:設定16×2顯示,5×7點陣,8位資料介面。(這條指令是固定的,必須寫0x38)

2、顯示開/關以及游標設定指令

如下圖所示:

第一條指令:一個位元組中8位,前5位是固定的0B0001,低3位分別用DCB從高到低表示

第二條指令:高6位是固定的0B000001,低2位使用NS從高到低表示

3、清屏指令

寫入0x01表示顯示清屏(固定的),其中包含了資料指標清零,所有的顯示清零。

寫入0x02僅僅是資料指標清零,顯示不清零。

4、RAM地址設定指令

該指令的最高位為1,低7位為RAM地址,RAM地址與液晶上字元的關係如上圖所示。通常在讀寫資料之前都要先設定好地址,然後再進行資料的讀寫操作。

5、初始化過程

延時15ms

寫指令38H(不檢測忙訊號)

延時5ms

寫指令38H(不檢測忙訊號)

延時5ms

寫指令38H(不檢測忙訊號)

(以後每次寫指令、讀/寫資料操作前,都要檢測忙訊號)

寫指令38H:顯示模式設定

寫指令08H:顯示關閉

寫指令01H:顯示清屏

寫指令06H:顯示游標移動設定

寫指令0CH:顯示開及游標設定

電路圖

或者可以參考下圖

【程式】

關於LCD1602的參考程式,我在這裡放兩個,一個是自己最開始做51小車時寫的關於LCD1602的程式,以下程式僅供參考

/*寫命令*/
void Write_Cmd(uchar cmd)
{
	LCD1602_RS = 0;			//寫入命令
	LCD1602_RW = 0;
	LCD1602_DB = cmd;			
	Delay_10us(10);
	LCD1602_EN = 1;			//使能端高電平
	Delay_10us(10);
	LCD1602_EN = 0;
}

/*寫資料*/
void Write_Dat(uchar dat)
{
	LCD1602_RS = 1;
	LCD1602_RW = 0;
	LCD1602_DB = dat;
	Delay_10us(10);
	LCD1602_EN = 1;			//使能端高電平
	Delay_10us(10);
	LCD1602_EN = 0;
}

/*LCD1602初始化*/
void LCD_INIT()
{
	Write_Cmd(0x38);		//設定顯示模式
	Write_Cmd(0x0c);		//開顯示不顯示游標,游標不閃爍
	Write_Cmd(0x06);		//寫一個指標+1
	Write_Cmd(0x01);		//清屏
	Write_Cmd(0x80);		//設定資料指標起點
}

/*延時函式*/
void Delay_10us(uint n)
{
	while(n--)
	{		
		_nop_();
		_nop_();
		_nop_();
		_nop_();
		_nop_();
	}
}

/*LCD1602顯示*/
void Print_LCD1602()
{
	uint i,j;
	Write_Cmd(0x80);				//寫第1行
	for(i = 0;i < 6;i++)
		Write_Dat(str1[i]);
	for(i = 0;i < 4;i++)
		Write_Dat(disdata[i]);
	for(i = 0;i < 4;i++)
		Write_Dat(str2[i]);
	
	Write_Dat(0x20);
	
	if(HAA == 1)
		Write_Dat('B');
	else if(HAA == 0)
		Write_Dat('T');
	
	Write_Cmd(0x80 + 0x40);	//寫第2行
	for(j = 0;j < 9;j++)
		Write_Dat(str3[j]);
	for(j = 0;j < 4;j++)
		Write_Dat(distance[j]);
	for(j = 0;j < 2;j++)
		Write_Dat(str4[j]);
}

另一個是自己後來多瞭解之後看的

#define LCD1602_DB P2			//並行輸入口
sbit LCD1602_RS = P0^5;			//資料/命令選擇端
sbit LCD1602_RW = P0^6;			//讀寫選擇端
sbit LCD1602_EN = P0^7;			//使能端	

void main()
{
    LCD1602_Init();
    LCD1602_Show(2,0,"Xiaomo_HAA");
    LCD1602_Show(0,11,"HAppy!");
}

//等待液晶準備好
void LCD1602_wait()
{
    unsigned char sta;
    LCD1602_DB = 0xff;
    LCD1602_RS = 0;
    LCD1602_RW = 1;

    do{
        LCD1602_EN = 1;
        sta = LCD1602_DB;    //讀取狀態字
        LCD1602_EN = 0;      
    }while(sta & 0x80);      //bit7等於1表示液晶正忙,重複檢測直到其為0為止
}

//寫命令
void LCD1602_cmd(unsigned char cmd)
{
    LCD1602_wait();
    LCD1602_RS = 0;
    LCD1602_RW = 0;
    LCD1602_DB = cmd;
    LCD1602_EN = 1;
    LCD1602_EN = 0;
}

//寫資料
void LCD1602_Data(unsigned char dat)
{
    LCD1602_wait();
    LCD1602_RS = 1;
    LCD1602_RW = 0;
    LCD1602_DB = dat;
    LCD1602_EN = 1;
    LCD1602_EN = 0;
}

//設定顯示RAM起始地址(x,y對應螢幕上字元座標)
void LCD1602_SetRAM(unsigned char x,unsigned char y)
{
    unsigned char addr;
    if(y == 0)
        addr = 0x00 + x;
    else
        addr = 0x40 + x;
    LCD1602_cmd(addr | 0x80);
}

//顯示字串
void LCD1602_Show(unsigned char x,unaigned y,unsigned char *str)
{
    LCD1602_SetRAM(x,y);
    while(*str != '\0')
    {
        LCD1602_Data(*str++);
    }
}

//初始化LCD1602
void LCD1602_Init()
{
	Write_Cmd(0x38);		//設定顯示模式
	Write_Cmd(0x0c);		//開顯示不顯示游標,游標不閃爍
	Write_Cmd(0x06);		//寫一個指標+1
	Write_Cmd(0x01);		//清屏
}