1602字元液晶

1602字元液晶

1602字元型液晶也叫1602液晶,它是一種專門用來顯示字母、數字、符號等的點陣型液晶模塊。字元型液晶,能夠同時顯示16x02即32個字元。

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

簡介


工業字元型液晶,能夠同時顯示16x02即32個字元。(16列2行)
註:為了表示的方便,後文皆以1表示高電平,0表示低電平

管腳功能


引腳說明
引腳說明
1602字元型LCD通常有14條引腳線或16條引腳線的LCD,多出來的2條線是背光電源線
VCC(15腳)和地線GND(16腳),其控制原理與14腳的LCD完全一樣,其中:
引腳符號功能說明
1VSS一般接地
2VDD接電源(+5V)
3V0液晶顯示器對比度調整端,接正電源時對比度最弱,接地電源時對比度最高(對比度過高時會產生“鬼影”,使用時可以通過一個10K的電位器調整對比度)。
4RSRS為寄存器選擇,高電平1時選擇數據寄存器、低電平0時選擇指令寄存器
5R/WR/W為讀寫信號線,高電平(1)時進行讀操作,低電平(0)時進行寫操作。
6E
E(或EN)端為使能(enable)端,
寫操作時,下降沿使能。
讀操作時,E高電平有效
7DB0低4位三態、雙向數據匯流排 0位(最低位)
8DB1低4位三態、雙向數據匯流排 1位
9DB2低4位三態、雙向數據匯流排 2位
10DB3低4位三態、雙向數據匯流排 3位
11DB4高4位三態、雙向數據匯流排 4位
12DB5高4位三態、雙向數據匯流排 5位
13DB6高4位三態、雙向數據匯流排 6位
14DB7高4位三態、雙向數據匯流排 7位(最高位)(也是busy flag)
15BLA背光電源正極
16BLK背光 電源負極
寄存器選擇控制表
RSR/W操作說明
寫入指令寄存器(清除屏等)
1讀busy flag(DB7),以及讀取位址計數器(DB0~DB6)值
1寫入數據寄存器(顯示各字型等)
11從數據寄存器讀取數據
註:關於E=H脈衝——開始時初始化E為0,然後置E為1,再清0.
busy flag(DB7):在此位為1時,LCD忙,將無法再處理其他的指令要求。

字符集


1602液晶模塊內部的字元發生存儲器(CGROM)已經存儲了160個不同的點陣字元圖形,這些字元有:阿拉伯數字、英文字母的大小寫、常用的符號、和日文假名等,每一個字元都有一個固定的代碼,比如大寫的英文字母“A”的代碼是01000001B(41H),顯示時模塊把地址41H中的點陣字元圖形顯示出來,我們就能看到字母“A”。
因為1602識別的是ASCII碼,試驗可以用ASCII碼直接賦值,在單片機編程中還可以用字元型常量或變數賦值,如'A’。
以下是1602的16進位ASCII碼錶:
1602字元液晶
1602字元液晶
(圖片打開是大圖)
讀的時候,先讀上面那行,再讀左邊那列,如:感嘆號!的ASCII為0x21,字母B的ASCII為0x42(前面加0x表示十六進位)。

顯示地址


1602字元液晶顯示可分為上下兩部分各16位進行顯示,處於不同行時的字元顯示地址如下
顯示字元12345678910111213141516
第一行
地址
00H01H02H03H04H05H06H07H08H09H0AH0BH0CH0DH0EH0FH
第二行
地址
40H41H42H43H44H45H46H47H48H49H4AH4BH4CH4DH4EH4FH

指令集


1602通過D0~D7的8位數據端傳輸數據和指令。
顯示模式設置:(初始化)
0011 1000[0x38]設置16×2顯示,5×8點陣,8位數據介面;
顯示開關及游標設置:(初始化)
0000 1DCB D顯示(1有效)、C游標顯示(1有效)、B游標閃爍(1有效)
0000 01NS N=1(讀或寫一個字元后地址指針加1 &游標加1),
N=0(讀或寫一個字元后地址指針減1 &游標減1),
S=1 且 N=1 (當寫一個字元后,整屏顯示左移)
s=0 當寫一個字元后,整屏顯示不移動
數據指針設置:
數據首地址為80H,所以數據地址為80H+地址碼(0-27H,40-67H)
其他設置:
01H(顯示清屏,數據指針=0,所有顯示=0);02H(顯示回車,數據指針=0)。
通常推薦的初始化過程:
延時15ms
寫指令38H
延時5ms
寫指令38H
延時5ms
寫指令38H
延時5ms
(以上都不檢測忙信號)
(以下都要檢測忙信號)
寫指令38H
寫指令08H 關閉顯示
寫指令01H 顯示清屏
寫指令06H游標移動設置
寫指令0cH 顯示開及游標設置
完畢
Proteus模擬
使用Proteus模擬1602--即LM016L--依照數據手冊說明可能遇到困難,可以嘗試採用以下方案解決:
1、數據手冊中可能介紹1602內部D0~D7已有上拉,可以使用P0口直接驅動。在Proteus里LM016L內部可能沒有,應該人為
加上拉電阻。建議不要使用排阻,使用普通電阻一個一個拉應該可以解決問題;
2、可能碰到不能檢測忙信號的問題,嘗試使用延時把忙信號拖過去。

時序圖


基本的讀寫時序圖
讀寫操作時序如圖1和2所示:
寫操作時序:
1602字元液晶
1602字元液晶
讀操作時序:
1602字元液晶
1602字元液晶

程序代碼


(參考)
/#include<intrins.h> //包含NOP空指令的頭文件
#define uchar unsigned char
#define uint unsigned int
#define LCD1602_H 1 //宏定義手冊中出現的H的定義
#define LCD1602_L 0 //宏定義手冊中出現的L的定義
#define LCD1602_DAT 1 //數據
#define LCD1602_COM 0 //命令
#define LCD_15MS 300 //宏定義15MS延時需要的數值
#defineLCD_5MS 100 //宏定義 5MS延時需要的數值
#define LCD_Display_mode 0X38 //設置16x2顯示 5x7點陣 8位數據介面
#define LCD_shows0 0X0C //開顯示 不顯示游標 游標不閃爍
#define LCD_shows2 0X0E //開顯示 顯示游標 游標不閃爍
#define LCD_shows1 0X0F //開顯示 顯示游標 游標 閃爍
#define LCD_shows3 0X08 //關顯示 不顯示游標 游標不閃爍
#define LCD_cursor1 0X04 //寫一個字元 地址指針減1
#define LCD_cursor2 0X05 //寫一個字元 地址指針減1 並屏幕右移
#define LCD_cursor3 0X06 //寫一個字元 地址指針加1
#define LCD_cursor4 0X07 //寫一個字元 地址指針加1 並屏幕左移
#define LCD_clear 0x01 //清屏指令 數據指針清零 所有顯示清零
#define LCD_WAY 0x80 //狀態字
#define LCD_ADDH 0X80 //第一行地址0x80-0xA7
#define LCD_ADDL 0XC0 //第二行地址0xC0-0xE7
#define LCD1602_DATA P0 //宏定義8位數據線IO為P0口 D0~D7=P00~P07 8位數據線 D0=P00;
sbit LCD1602_RS=P2^5; //數據/命令選擇端(H/L)
sbit LCD1602_RW=P2^6; //讀/寫選擇端(H/L)
sbit LCD1602_E =P2^7; //使能信號
void LCD1602_init(); //液晶初始化函數
void LCD1602_writecd(bit lcd_rs, uchar LCD1602_d);//寫命令/數據 函數bit lcd_rs是數據還是命令 uchar LCD1602_d要寫入的數據
uchar LCD1602_readway(); //讀忙狀態函數 由寫入和讀取函數調用
uchar LCD1602_readata(); //讀數據函數
void LCD_DELAY(uchar LCD_delay); //
void LCD1602_init() //液晶初始化函數
{ LCD_DELAY(LCD_15MS); //延時15MS 初始化
LCD1602_writecd(LCD1602_COM,LCD_Display_mode);//寫指令38H 設置16x2顯示 5x7點陣 8位數據介面
LCD1602_writecd(LCD1602_COM,LCD_shows0); //開顯示 不顯示游標 游標不閃爍
LCD1602_writecd(LCD1602_COM,LCD_cursor1); //檢查忙狀態
LCD1602_writecd(LCD1602_COM,LCD_clear); //寫指令01H:顯示清屏
}
void LCD1602_writecd(bit lcd_rs, uchar LCD1602_cd)//寫命令/數據 函數
{ uchar LCD1602_NUM; //定義變數用來液晶無忙回答的退出死循環
LCD1602_NUM=255; //忙狀態檢測次數
while(LCD1602_readway()) //檢查忙狀態
{LCD1602_NUM--; //檢測次數自減
if(LCD1602_NUM==0) //判斷檢測次數等於0
{break;} //退出循環判斷忙
}
LCD1602_RW = LCD1602_L; //讀/寫選擇端(H/L)
LCD1602_RS = lcd_rs; //數據/命令選擇端(H/L)
LCD1602_DATA= LCD1602_cd; //IO口賦值
LCD1602_E = LCD1602_H; //拉高使能信號開始傳輸數據
LCD1602_E = LCD1602_L; //拉低使能信號鎖存數據
LCD1602_DATA= 0xff; //IO口數據清除
}
uchar LCD1602_readway()//讀狀態函數由寫入和讀取函數調用
{ uchar LCD1602_way; //狀態字變數
LCD1602_DATA=0xff; //IO口數據清除
LCD1602_RS = LCD1602_COM; //數據/命令選擇端(H/L) 命令
LCD1602_RW = LCD1602_H; //讀/寫選擇端(H/L)
LCD1602_E = LCD1602_H; //拉高使能信號開始接收狀態
LCD1602_way =LCD1602_DATA; //讀取狀態
LCD1602_E = LCD1602_L; //拉低使能信號鎖存數據
LCD1602_way =LCD1602_way&LCD_WAY;//取忙狀態字
return(LCD1602_way); //返回狀態字
}
uchar LCD1602_readata()//讀數據函數
{ uchar LCD1602_data; //數據暫存變數
while(LCD1602_readway()); //檢查忙狀態 --------------------
LCD1602_DATA=0xff; //IO口數據清除
LCD1602_RS = LCD1602_DAT; //數據/命令選擇端(H/L) 數據
LCD1602_RW = LCD1602_H; //讀/寫選擇端(H/L)
LCD1602_E = LCD1602_H; //拉高使能信號開始接收狀態
LCD1602_data= LCD1602_DATA; //讀取狀態
LCD1602_E = LCD1602_L; //拉低使能信號鎖存數據
return(LCD1602_data); //返回數據
}
void LCD_DELAY(uchar LCD_delay)//
{ uchar lcd_del;
while(LCD_delay--) //自減
{lcd_del=100;
while(lcd_del--);}
}