1602字元液晶
1602字元液晶
1602字元型液晶也叫1602液晶,它是一種專門用來顯示字母、數字、符號等的點陣型液晶模塊。字元型液晶,能夠同時顯示16x02即32個字元。
它由若干個5X7或者5X11等點陣字元位組成,每個點陣字元位都可以顯示一個字元,每位之間有一個點距的間隔,每行之間也有間隔,起到了字元間距和行間距的作用,正因為如此所以它不能很好地顯示圖形(用自定義CGRAM,顯示效果也不好)。
工業字元型液晶,能夠同時顯示16x02即32個字元。(16列2行)
註:為了表示的方便,後文皆以1表示高電平,0表示低電平。
引腳說明
VCC(15腳)和地線GND(16腳),其控制原理與14腳的LCD完全一樣,其中:
引腳 | 符號 | 功能說明 |
1 | VSS | 一般接地 |
2 | VDD | 接電源(+5V) |
3 | V0 | 液晶顯示器對比度調整端,接正電源時對比度最弱,接地電源時對比度最高(對比度過高時會產生“鬼影”,使用時可以通過一個10K的電位器調整對比度)。 |
4 | RS | RS為寄存器選擇,高電平1時選擇數據寄存器、低電平0時選擇指令寄存器。 |
5 | R/W | R/W為讀寫信號線,高電平(1)時進行讀操作,低電平(0)時進行寫操作。 |
6 | E | E(或EN)端為使能(enable)端, 寫操作時,下降沿使能。 讀操作時,E高電平有效 |
7 | DB0 | 低4位三態、雙向數據匯流排 0位(最低位) |
8 | DB1 | 低4位三態、雙向數據匯流排 1位 |
9 | DB2 | 低4位三態、雙向數據匯流排 2位 |
10 | DB3 | 低4位三態、雙向數據匯流排 3位 |
11 | DB4 | 高4位三態、雙向數據匯流排 4位 |
12 | DB5 | 高4位三態、雙向數據匯流排 5位 |
13 | DB6 | 高4位三態、雙向數據匯流排 6位 |
14 | DB7 | 高4位三態、雙向數據匯流排 7位(最高位)(也是busy flag) |
15 | BLA | 背光電源正極 |
16 | BLK | 背光 電源負極 |
寄存器選擇控制表
RS | R/W | 操作說明 |
寫入指令寄存器(清除屏等) | ||
1 | 讀busy flag(DB7),以及讀取位址計數器(DB0~DB6)值 | |
1 | 寫入數據寄存器(顯示各字型等) | |
1 | 1 | 從數據寄存器讀取數據 |
註:關於E=H脈衝——開始時初始化E為0,然後置E為1,再清0.
busy flag(DB7):在此位為1時,LCD忙,將無法再處理其他的指令要求。
1602液晶模塊內部的字元發生存儲器(CGROM)已經存儲了160個不同的點陣字元圖形,這些字元有:阿拉伯數字、英文字母的大小寫、常用的符號、和日文假名等,每一個字元都有一個固定的代碼,比如大寫的英文字母“A”的代碼是01000001B(41H),顯示時模塊把地址41H中的點陣字元圖形顯示出來,我們就能看到字母“A”。
以下是1602的16進位ASCII碼錶:
1602字元液晶
讀的時候,先讀上面那行,再讀左邊那列,如:感嘆號!的ASCII為0x21,字母B的ASCII為0x42(前面加0x表示十六進位)。
1602字元液晶顯示可分為上下兩部分各16位進行顯示,處於不同行時的字元顯示地址如下
顯示字元 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
第一行 地址 | 00H | 01H | 02H | 03H | 04H | 05H | 06H | 07H | 08H | 09H | 0AH | 0BH | 0CH | 0DH | 0EH | 0FH |
第二行 地址 | 40H | 41H | 42H | 43H | 44H | 45H | 46H | 47H | 48H | 49H | 4AH | 4BH | 4CH | 4DH | 4EH | 4FH |
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字元液晶
(參考)
#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_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--);}
}