11.1 1602 液晶顯示模塊簡(jiǎn)介
1602 液晶顯示模塊是一種通用的工業(yè)液晶顯示模塊,專門用來(lái)顯示字母、數(shù)字、符號(hào)等的點(diǎn)陣型液晶顯示模塊。從名字就可以看出該液晶顯示模塊有 2 行,每行 16 個(gè)字符共可以顯示 32 個(gè)字符。每個(gè)字符是由 5x7 或者 5x11 的點(diǎn)陣位組成,我們這里講解的為 5x7 模式的模塊。模塊顯示界面結(jié)構(gòu)尺寸如下圖所示:
與數(shù)碼管相比,不需周期性的對(duì)顯示進(jìn)行刷新,只需將需要顯示的字符按照時(shí)序要求發(fā)送給 1602 液晶顯示模塊便可一直顯示,有效的節(jié)省了單片機(jī)的系統(tǒng)資源。通過單片機(jī)控制 1602 的讀寫硬件( RS, RW)進(jìn)行控制,根據(jù)相應(yīng)的時(shí)序?qū)?shù)據(jù) D0-D7 進(jìn)行操作便可實(shí)現(xiàn)顯示指定的字符。1602 模塊共有 16 個(gè)引腳,各引腳定義如下圖所示:
- 第 1,2 引腳:VDD、VS S 為 1602 供電的正負(fù)極,最佳供電電壓為 5V。
- 第 3 引腳:VL 液晶顯示偏壓信號(hào),即為顯示屏的對(duì)比度調(diào)節(jié)端,當(dāng)接電源時(shí)對(duì)比度最高,接低時(shí)對(duì)比對(duì)最低,在使用中往往通過接一個(gè)可變電阻來(lái)調(diào)節(jié)顯示對(duì)比度。
- 第 4 引腳:RS 為數(shù)據(jù)/命令選擇端,當(dāng) RS=1 時(shí),選擇操作 1602 內(nèi)部的數(shù)據(jù)寄存器,當(dāng) RS=0 時(shí),選擇操作內(nèi)部指令寄存器。
- 第 5 引腳:R/W 為讀寫選擇端,當(dāng) R/W=1 時(shí),對(duì) 1602 進(jìn)行讀數(shù)據(jù)操作,當(dāng) R/W=0 時(shí),對(duì) 1602 進(jìn)行寫操作。
- 第 6 引腳:E 為 1602 液晶顯示模塊使能端,與 RS,R/W 配合使用在高電平時(shí)讀取信息,負(fù)跳變時(shí)執(zhí)行指令。
- 第 7-14 引腳:為 8 位的雙向數(shù)據(jù)端口 D0~D7。
- 第 15,16 引腳:BLA 背光源正極,BLK 背光源負(fù)極。BLK 接地,BLA 接電源 VDD 時(shí),1602 液晶背光點(diǎn)亮,接 GND 時(shí),背光熄滅。
RY-51 單片機(jī)開發(fā)板 1602 液晶顯示模塊的電路連接圖如下圖所示:
如上圖所示,1602 的 4,5,6 引腳分別接到到了單片機(jī)的 P3.4-P3.6 端口,數(shù)據(jù)端口 D0-D7 鏈接到單片機(jī)的 P0 端口與 RY-51 開發(fā)板的 8 位數(shù)碼管共用 P1 端口,因此,在應(yīng)用 1602 液晶顯示模塊的時(shí)候首先要關(guān)閉數(shù)碼管。
11.2 1602 讀、寫操作時(shí)序解析
剛開始接觸 1602 液晶顯示模塊的時(shí)候可能會(huì)覺得有一點(diǎn)難度,感覺挺復(fù)雜,理解起來(lái)比較費(fèi)勁。其實(shí),只要掌握了的操作規(guī)律,多次的練習(xí)之后你會(huì)發(fā)現(xiàn)其實(shí)很簡(jiǎn)單。我們要實(shí)現(xiàn)對(duì)單片機(jī)的操作無(wú)非就是 1602 的初始化、對(duì) 1602 的讀操作、寫操作。對(duì) 1602 液晶顯示的一切都是建立在數(shù)據(jù)的讀、寫操作之上了,因此,我們只要研究明白了讀、寫的操作時(shí)序,掌握它的應(yīng)用就非常簡(jiǎn)單了。通過查找 1602 的數(shù)據(jù)手冊(cè),讀、寫時(shí)序如下圖所示:
讀操作時(shí)序解析如下:
將 R/W 拉高進(jìn)入讀操作模式,同時(shí) RS 要么為高電平要么為低電平,高電平時(shí)為讀數(shù)據(jù)操作,低電平時(shí)為讀狀態(tài)操作,經(jīng)過 tSP1 時(shí)間之后才可將使能信號(hào) E 拉高,并且 E 的高電平維持時(shí)間為 tPW,在使能信號(hào) E 拉高之后不超過 tD 時(shí)間內(nèi),1602 液晶顯示器將數(shù)據(jù)放在 DB0~DB7 數(shù)據(jù)線上。這時(shí)我們將數(shù)據(jù)讀取并將使能 E 拉低,整個(gè)數(shù)據(jù)或狀態(tài)的讀取就完成了。
那么,我們?cè)趯⒛硞€(gè)信號(hào)拉高或者拉低需要滿足上面一些時(shí)間的先后順序要求。例如我們以讀 1602 狀態(tài)為例,第一條語(yǔ)句首先將 RS 拉低,即 RS = 0,然后將 R/W 拉高,即 R/W=1,接下來(lái)將使能信號(hào) E 高,即 E=1,上面兩條語(yǔ)句的時(shí)間間隔要求不低于 tSP1,查詢數(shù)據(jù)表格可知 tSP1 最小值為 30ns,而我們開發(fā)板執(zhí)行一條語(yǔ)句的時(shí)間大約為 1us,因此遠(yuǎn)遠(yuǎn)能滿足要求,如果我們?cè)趫?zhí)行語(yǔ)句比較快的系統(tǒng)運(yùn)行時(shí),為了保證時(shí)序要求,可以在兩條語(yǔ)句之間插入軟件延時(shí)。E 的高電平維持時(shí)間 tPW 最小值為 150ns,而我們 E 維持高電平約為 1us,滿足要求。tD 最大值為 100ns,因此,可以直接將數(shù)據(jù)讀取,接著將 E 拉低完成狀態(tài)讀取,我們將代碼放到函數(shù)當(dāng)中,返回值為讀取的狀態(tài)數(shù)據(jù),應(yīng)用的時(shí)候只需調(diào)用該函數(shù)即可,代碼如下:
unsigned char RD_sta()//讀狀態(tài)函數(shù)
{
unsigned char sta;
RS_1602 = 0;
RW_1602 = 1;//進(jìn)入讀1602狀態(tài)模式
EN_1602 = 1;//拉高使能信號(hào)
sta = P0; //將1602狀態(tài)數(shù)據(jù)讀取
EN_1602 = 0;//拉低使能,完成讀操作
return sta; //將狀態(tài)值返
}
寫操作時(shí)序與讀操作的基本一致,唯一不同的是,在使能信號(hào) E 拉高之前 tSP2 單片機(jī)必須把需要學(xué)的數(shù)據(jù)送到數(shù)據(jù)端口上。當(dāng) RS=1 時(shí),表示將要往 1602 寫數(shù)據(jù),當(dāng) RS=0 時(shí),表示將要往 1602 里面寫指令。
LCD1602 時(shí)序參數(shù)如下圖所示:
我們分別把寫數(shù)據(jù)、寫指令分別放到函數(shù) WR_Cmd(unsigned char cmd)、 WR_Dat(unsigned char dat)中。
void WR_Cmd(unsigned char cmd)//寫指令函數(shù)
{
Ready(); //檢測(cè)1602是否處于空閑狀態(tài)
RS_1602 = 0;
RW_1602 = 0;//進(jìn)入寫指令模式
P0 = cmd; //將指令數(shù)據(jù)輸出
EN_1602 = 1;//拉高使能信號(hào)
EN_1602 = 0;//拉低使能,完成寫操作
}
void WR_Dat(unsigned char dat)//寫數(shù)據(jù)函數(shù)
{
Ready(); //檢測(cè)1602是否處于空閑狀態(tài)
RS_1602 = 1;
RW_1602 = 0;//進(jìn)入寫數(shù)據(jù)模式
P0 = dat; //將數(shù)據(jù)輸出
EN_1602 = 1;//拉高使能信號(hào)
EN_1602 = 0;//拉低使能,完成寫操作
}
在上述函數(shù)中,增加了一個(gè) Ready()函數(shù),這個(gè)函數(shù)的作用為先查詢 1602 是否處于空閑狀態(tài),當(dāng)為空閑狀態(tài)時(shí),才開始寫操作。到目前為止,我們已經(jīng)完成了對(duì) 1602 最底層的數(shù)據(jù)讀寫操作,下面我們只要按照數(shù)據(jù)手冊(cè)的要求調(diào)用這三個(gè)函數(shù)便可實(shí)現(xiàn)各種類型的顯示功能。對(duì)于 1602 而言,讀狀態(tài)函數(shù) RD_sta(),的返回值數(shù)據(jù)格式如下:
如上表所示,返回狀態(tài)字的低六位為當(dāng)前數(shù)據(jù)地址指針的數(shù)值,最高位讀寫操作使能,當(dāng)返回值為 1 時(shí),表示 1602 正處于忙的狀態(tài),不允許讀寫操作,當(dāng)返回值為 0 時(shí),表示可以對(duì) 1602 進(jìn)行讀寫,因此,在讀寫前進(jìn)行判斷,我們將忙檢測(cè)函數(shù)如下:
void Ready() //空閑檢測(cè)函數(shù)
{
P0 = 0xFF;//P0端口設(shè)置為輸入時(shí),先賦值0xFF
while(RD_sta() & 0x80);//bit7等于1表示忙,一直檢測(cè)到0為止
}
11.3 1602 液晶顯示初始化
在使用 1602 進(jìn)行顯示前時(shí),首先要通過寫一系列的指令對(duì) 1602 進(jìn)行初始化,各指令碼及功能定義如下所示:
初始化如下:
- 寫指令 38H:設(shè)置 16x2 顯示,5x7 點(diǎn)陣,8 位數(shù)據(jù)接口;
- 寫指令 0CH:開顯示,關(guān)閉光標(biāo);
- 寫指令 06H:讀或?qū)懲暌粋€(gè)字符后,地址指針、光標(biāo)均加 1;
- 寫指令 01H:數(shù)據(jù)指針清零、所示顯示清零
將初始化程序放到初始化函數(shù) Init_1602()中,代碼如下圖所示:
void Init_1602() //1602初始化函
{
WR_Cmd(0x38);//設(shè)置16x2顯示,5x7點(diǎn)陣,8位數(shù)據(jù)接口
WR_Cmd(0x0C);//開顯示,關(guān)閉光標(biāo)
WR_Cmd(0x06);//讀或?qū)懲暌粋€(gè)字符后,地址指針、光標(biāo)均加1
WR_Cmd(0x01);//數(shù)據(jù)指針清零、所示顯示清零
}
11.4 1602 液晶顯示字符操作
當(dāng)我們開始要往 1602 里面寫字符的時(shí)候,我們首先得告訴 1602 我們要從哪個(gè)地方開始寫,也就是寫數(shù)據(jù)開始地址,1602 共可以顯示 2 行 32 個(gè)字符,那么每個(gè)字符的地址是多少呢?1602 內(nèi)部控制器有 80 字節(jié)的 RAM 緩沖區(qū),RAM 地址與 1602 顯示模塊的對(duì)應(yīng)關(guān)系如下圖所示:
如圖所示,地址 00H-0FH 的 RAM 與顯示模塊的第一行一一對(duì)應(yīng)。地址 40H~4FH 的 RAM 與顯示模塊的第二行一一對(duì)應(yīng)。這里要特別注意的是,第一行到第二行的地址不是連續(xù)的。通過寫指令可以告訴 1602 我們將要從哪里開始寫字符了,寫地址指令碼及功能定義如下表所示:
例如,若需要往第二行的第一列開始寫字符,首先應(yīng)該寫指令 WR_Cmd(0x80 + 0x40)。接下通過調(diào)用寫數(shù)據(jù)函數(shù) WR_Dat(dat)將對(duì)應(yīng)的字符顯示到 1602 了。寫數(shù)據(jù)函數(shù)中的 dat 為字符對(duì)應(yīng)的字符碼,字符碼可以通過查詢 1602 的標(biāo)準(zhǔn)字符庫(kù),如下圖所示,行坐標(biāo)為字符碼的低 4 位,縱坐標(biāo)為字符碼的高四位。例如,我們要將“C”顯示到 1602,需要調(diào)用 WR_Dat(0x43)完成顯示。標(biāo)準(zhǔn) 1602 字符字庫(kù)如下:
將顯示字符的步驟寫到函數(shù)中,函數(shù)的功能為:從第 row 行,第 column 列開始顯示字符串 str,函數(shù)代碼如圖所示:
//字符串顯示功能:從第row行,第column列開始顯示字符串str
void Disp_1602_str(unsigned char row,unsigned char column,char *str)
{
unsigned char addr;
addr = (row-1)*0x40 + (column-1);//組合成地址
WR_Cmd(0x80+addr);//寫地址命令
while(*str)//判斷str字符串是否已結(jié)束
{
WR_Dat(*str++);//將str字符串?dāng)?shù)據(jù)依次寫入
}
}
11.5 1602 顯示應(yīng)用實(shí)例
我們結(jié)合上面講解的各個(gè)函數(shù),實(shí)現(xiàn)從 1602 液晶顯示模塊第 1 行第 3 列開始顯示字符串“RongYi RY-51”。由于 RY-51 開發(fā)板的 8 個(gè)數(shù)碼管與 1602 共用 P0 口,因此在主程序開始處將數(shù)碼管關(guān)閉,接著初始化 1602,然后顯示字符串,最后進(jìn)入死循環(huán)。程序代碼如下:
#include < reg52.h >
sbit DU = P2^7;//數(shù)碼管段選、位選引腳定義
sbit WE = P2^6;
sbit RS_1602 = P3^4; //1602,RS、R/W,E引腳定義
sbit RW_1602 = P3^5;
sbit EN_1602 = P3^6;
//字符串顯示函數(shù)聲明
void Disp_1602_str(unsigned char row,unsigned char column,char *str);
void Init_1602();//1602初始化函數(shù)聲明
void Ready();//空閑檢測(cè)函數(shù)聲明
void WR_Cmd(unsigned char cmd);//寫指令函數(shù)聲明
void WR_Dat(unsigned char dat);//寫數(shù)據(jù)函數(shù)聲明
unsigned char RD_sta();//讀狀態(tài)函數(shù)聲明
void main()
{
P0 = 0;//關(guān)閉所有數(shù)碼管
WE = 1;
WE = 0;
Init_1602();//1602初始化
Disp_1602_str(1,3,"RongYi RY-51");//第1行第3列開始顯示"RongYi RY-51"
while(1);
}
//字符串顯示功能:從第row行,第column列開始顯示字符串str
void Disp_1602_str(unsigned char row,unsigned char column,char *str)
{
unsigned char addr;
addr = (row-1)*0x40 + (column-1);//組合成地址
WR_Cmd(0x80+addr);//寫地址命令
while(*str)//判斷str字符串是否已結(jié)束
{
WR_Dat(*str++);//將str字符串?dāng)?shù)據(jù)依次寫入
}
}
void Init_1602() //1602初始化函
{
WR_Cmd(0x38);//設(shè)置16x2顯示,5x7點(diǎn)陣,8位數(shù)據(jù)接口
WR_Cmd(0x0C);//開顯示,關(guān)閉光標(biāo)
WR_Cmd(0x06);//讀或?qū)懲暌粋€(gè)字符后,地址指針、光標(biāo)均加1
WR_Cmd(0x01);//數(shù)據(jù)指針清零、所示顯示清零
}
void Ready() //空閑檢測(cè)函數(shù)
{
P0 = 0xFF;//P0端口設(shè)置為輸入時(shí),先賦值0xFF
while(RD_sta() & 0x80);//bit7等于1表示忙,一直檢測(cè)到0為止
}
unsigned char RD_sta()//讀狀態(tài)函數(shù)
{
unsigned char sta;
RS_1602 = 0;
RW_1602 = 1;//進(jìn)入讀1602狀態(tài)模式
EN_1602 = 1;//拉高使能信號(hào)
sta = P0; //將1602狀態(tài)數(shù)據(jù)讀取
EN_1602 = 0;//拉低使能,完成讀操作
return sta; //將狀態(tài)值返
}
void WR_Cmd(unsigned char cmd)//寫指令函數(shù)
{
Ready(); //檢測(cè)1602是否處于空閑狀態(tài)
RS_1602 = 0;
RW_1602 = 0;//進(jìn)入寫指令模式
P0 = cmd; //將指令數(shù)據(jù)輸出
EN_1602 = 1;//拉高使能信號(hào)
EN_1602 = 0;//拉低使能,完成寫操作
}
void WR_Dat(unsigned char dat)//寫數(shù)據(jù)函數(shù)
{
Ready(); //檢測(cè)1602是否處于空閑狀態(tài)
RS_1602 = 1;
RW_1602 = 0;//進(jìn)入寫數(shù)據(jù)模式
P0 = dat; //將數(shù)據(jù)輸出
EN_1602 = 1;//拉高使能信號(hào)
EN_1602 = 0;//拉低使能,完成寫操作
}
將上面程序下載到 RY-51 開發(fā)板后觀察現(xiàn)象,并通過調(diào)準(zhǔn)可變電阻 R6 觀察 1602 顯示器對(duì)比度的變化。
大家有沒有發(fā)現(xiàn),我們將和 1602 有關(guān)的函數(shù)都放在主程序所在的.c 文件中,以后我們每次要用到 1602 時(shí),都要將這些函數(shù)復(fù)制到主函數(shù)下面,這樣是不是有點(diǎn)不方便。其實(shí),我們可將這些函數(shù)都放到另外一個(gè).c 文件、將函數(shù)聲明放到一個(gè)。h 格式的文件中,在主程序中我們只要包含這個(gè)文件就可以了,主程序代碼如下:
#include < reg52.h >
#include "Drive_1602.h"
sbit DU = P2^7;//數(shù)碼管段選、位選引腳定義
sbit WE = P2^6;
void main()
{
P0 = 0;//關(guān)閉所有數(shù)碼管
WE = 1;
WE = 0;
Init_1602();//1602初始化
Disp_1602_str(1,3,"RongYi RY-51");//第1行第3列開始顯示"RongYi RY-51"
while(1);
}

如上圖所示,將 Drive_1602.c、Drive_1602.h 添加到工程當(dāng)中,并且在主函數(shù)文件 Main1602.c 中添加語(yǔ)句#include "Drive_1602.h"即可。Drive_1602.h 文件內(nèi)容如下所示:
#ifndef __1602_H__
#define __1602_H__
//字符串顯示函數(shù)聲明
extern void Disp_1602_str(unsigned char row,unsigned char column,char *str);
extern void Init_1602();//1602初始化函數(shù)聲明
void Ready();//空閑檢測(cè)函數(shù)聲明
void WR_Cmd(unsigned char cmd);//寫指令函數(shù)聲明
void WR_Dat(unsigned char dat);//寫數(shù)據(jù)函數(shù)聲明
unsigned char RD_sta();//讀狀態(tài)函數(shù)聲明
#endif
關(guān)鍵字“extern”表示該函數(shù)可以在其它文件中被調(diào)用。Drive_1602.c 部分代碼如下所示:
#include < reg52.h >
#include "Drive_1602.h"
sbit RS_1602 = P3^4; //1602,RS、R/W,E引腳定義
sbit RW_1602 = P3^5;
sbit EN_1602 = P3^6;
//字符串顯示功能:從第row行,第column列開始顯示字符串str
void Disp_1602_str(unsigned char row,unsigned char column,char *str)
{
unsigned char addr;
addr = (row-1)*0x40 + (column-1);//組合成地址
WR_Cmd(0x80+addr);//寫地址命令
while(*str)//判斷str字符串是否已結(jié)束
{
WR_Dat(*str++);//將str字符串?dāng)?shù)據(jù)依次寫入
}
}
void Init_1602() //1602初始化函
{
WR_Cmd(0x38);//設(shè)置16x2顯示,5x7點(diǎn)陣,8位數(shù)據(jù)接口
WR_Cmd(0x0C);//開顯示,關(guān)閉光標(biāo)
WR_Cmd(0x06);//讀或?qū)懲暌粋€(gè)字符后,地址指針、光標(biāo)均加1
WR_Cmd(0x01);//數(shù)據(jù)指針清零、所示顯示清零
}
void Ready() //空閑檢測(cè)函數(shù)
{
P0 = 0xFF;//P0端口設(shè)置為輸入時(shí),先賦值0xFF
while(RD_sta() & 0x80);//bit7等于1表示忙,一直檢測(cè)到0為止
}
unsigned char RD_sta()//讀狀態(tài)函數(shù)
{
unsigned char sta;
RS_1602 = 0;
RW_1602 = 1;//進(jìn)入讀1602狀態(tài)模式
EN_1602 = 1;//拉高使能信號(hào)
sta = P0; //將1602狀態(tài)數(shù)據(jù)讀取
EN_1602 = 0;//拉低使能,完成讀操作
return sta; //將狀態(tài)值返
}
void WR_Cmd(unsigned char cmd)//寫指令函數(shù)
{
Ready(); //檢測(cè)1602是否處于空閑狀態(tài)
RS_1602 = 0;
RW_1602 = 0;//進(jìn)入寫指令模式
P0 = cmd; //將指令數(shù)據(jù)輸出
EN_1602 = 1;//拉高使能信號(hào)
EN_1602 = 0;//拉低使能,完成寫操作
}
void WR_Dat(unsigned char dat)//寫數(shù)據(jù)函數(shù)
{
Ready(); //檢測(cè)1602是否處于空閑狀態(tài)
RS_1602 = 1;
RW_1602 = 0;//進(jìn)入寫數(shù)據(jù)模式
P0 = dat; //將數(shù)據(jù)輸出
EN_1602 = 1;//拉高使能信號(hào)
EN_1602 = 0;//拉低使能,完成寫操作
}
除了如上面定義語(yǔ)句外,其他函數(shù)代碼均從最開始的主程序中拷貝過來(lái)即可。
11.6 本章小結(jié)
本章詳細(xì)介紹了1602字符顯示的原理,以及讀寫操作函數(shù)的實(shí)現(xiàn),后續(xù)項(xiàng)目中需要顯示字符時(shí),調(diào)用上面的函數(shù)即可。
-
單片機(jī)
+關(guān)注
關(guān)注
6076文章
45495瀏覽量
670396 -
寄存器
+關(guān)注
關(guān)注
31文章
5608瀏覽量
129998 -
液晶顯示
+關(guān)注
關(guān)注
6文章
604瀏覽量
41565 -
顯示模塊
+關(guān)注
關(guān)注
1文章
56瀏覽量
23971
發(fā)布評(píng)論請(qǐng)先 登錄
使用1602液晶顯示的實(shí)驗(yàn)例子
1602液晶顯示模塊的應(yīng)用
基于單片機(jī)的液晶屏1602-LCD液晶顯示商標(biāo)【匯編】
基于單片機(jī)的液晶屏1602-LCD液晶顯示【C語(yǔ)言+匯編】
使用51單片機(jī)實(shí)現(xiàn)LCD1602液晶顯示實(shí)驗(yàn)的程序免費(fèi)下載
51單片機(jī)怎么顯示當(dāng)前時(shí)間_(記錄)51單片機(jī)——LCD1602液晶顯示模塊
基于單片機(jī)的1602液晶顯示實(shí)驗(yàn) 1602液晶顯示模塊簡(jiǎn)介
評(píng)論