1.LCD顯示器相關(guān)背景
1.LCD簡介
(1)顯示器,常見顯示器:電視,電腦
(2)LCD(Liquid Crystal Display),液晶顯示器,原理介紹
(3)LCD應(yīng)用領(lǐng)域:手機(jī),電腦
(4)將來取代LCD:LED,OLED【全面屏---軟性】
2.電子顯示器的原理
1.像素(分辨率)
顯示單元【液晶分子】
但是實(shí)際上:像素!=分辨率
比如:出廠時電腦的像素已經(jīng)確定,就是最大的顯示【比如是1920*1080】,所以最大的分辨率是1920*1080,但是不能超過1920*1080,卻可以小于1920*1080
2.顯存
用來做顯示的內(nèi)存【電子顯示效果跟內(nèi)存有關(guān)】
找一塊空間來存儲像素和內(nèi)存的對應(yīng)關(guān)系。【將要顯示的內(nèi)容丟到顯存中---存儲的是要顯示的內(nèi)容與液晶分子的一一對應(yīng)關(guān)系】
3.字模
字的模型。表示將這個字如何對應(yīng)到顯示器中?!緦ⅰ癆“放入相同的分辨率的顯示器上,會產(chǎn)生不同的字?!?/p>
4.字庫
字模形成的庫。
5.控制器(關(guān)鍵)和驅(qū)動器
LCD顯示器中的2個器件
控制器:方向盤,掛擋---跟CPU對接---靠近軟件
驅(qū)動器:馬達(dá),發(fā)動器---將要顯示的東西打到液晶顯示器上---靠近硬件
6.軟件+硬件實(shí)現(xiàn)功能
2.LCD1602
1.簡介
1.為什么叫1602
16*2--》顯示器可以顯示的字符【顯示器可以顯示2排,每排16個】
能顯示的字符數(shù)是32,但是像素數(shù)不是32,因?yàn)橐粋€字符是由多個像素組成的。有可能一個字符是由5*7=35個像素組成的,也有可能是由6*8=48給像素組成的。但是我們不用去管,因?yàn)長CD1602內(nèi)置了字庫了。
2.帶ASCII碼字庫,不能顯示中文
當(dāng)我們想要讓LCD1602顯示某一個ASCII碼字符時候,只需要將這個字符對應(yīng)的ASCII碼發(fā)給LCD1602內(nèi)部的控制器,控制器就會去查字庫就得到字模,如何將字模發(fā)給內(nèi)部的驅(qū)動器去驅(qū)動LCD做顯示。
2.原理圖和接線引腳
1.引腳分為:數(shù)據(jù)接口+控制接口
16根線:2根VCC,2根GND,1根VO(調(diào)節(jié)屏幕亮度),RS+RW+E(控制信號線),DB0-DB7(數(shù)據(jù)線)
2.并行接口
串行:就是數(shù)據(jù)線只有1根(I2C中的SDA),同時只能傳輸1個bit位,如果要傳送多個bit位必須分時傳輸。
并行:就是數(shù)據(jù)線有很多根,每一根可以傳輸1個bit位,所以同時可以傳輸多個bit位。
如LCD1602有8根數(shù)據(jù)線,所以一次同時傳輸8bit位
3.背光調(diào)節(jié)
1根VO(調(diào)節(jié)屏幕亮度)
4.接線確認(rèn)
3.數(shù)據(jù)手冊
LCD1602數(shù)據(jù)手冊速覽 - 電子組培訓(xùn)文檔
https://www.dfrobot.com.cn/image/data/DFR0063/CN/HD44780.pdf
1.LCM和LCD
LCM:就是lcd module(LCD模組)
2.主要技術(shù)參數(shù)解析
3.引腳定義(結(jié)合原理圖來對照分析)
4.控制器接口說明(主要控制器型號)
RS=1時候,D0-D7上傳輸?shù)氖菙?shù)據(jù)
RS=0時候,D0-D7上傳輸?shù)氖敲?/span>
RW=1時候,表示我們要讀
RW=0時候,表示我們要寫
E=1時候,表示使能? ? ? ? enable
E=0時候,表示禁止(禁能) disable
3.LCD1602控制器的底層時序
1.關(guān)鍵點(diǎn)
(1)時序走控制接口引腳
(2)指令碼,狀態(tài)字,數(shù)據(jù),這三個走數(shù)據(jù)接口
(3)注意是并行的
2.控制器接口
3.讀狀態(tài)時序分析(判斷是否在忙)
判斷當(dāng)前LCD是否有在顯示數(shù)據(jù)
對控制器每一次進(jìn)行讀寫操作之前,都必須進(jìn)行讀寫檢測,確保bit7==0
狀態(tài)字的解析方法
讀狀態(tài):RS=0;RW=1;RE=1;
讀取狀態(tài)字的bit7位,如果此時bit7=1--》表示此時還在顯示東西,此時不可以進(jìn)入
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? bit7=0---》表示此時沒有顯示東西,可以開始顯示
//基本操作時序:讀狀態(tài):輸入RS=0,RW=1,EN=1 輸出:bit0-bit7--》狀態(tài)
void Read_Busy{ //忙檢測函數(shù),判斷bit7是0:允許執(zhí)行;1禁止
unsigned char sta;
LCD1602_DB=0xff;
LCD1602_RS=0;
LCD1602_RW=1;
do{
LCD1602_EN=1;//使能
sta=LCD1602_DB;//讀取8個bit位的狀態(tài)
LCD1602_EN=0;
//如果sta&0x80==1,表示sta的bit7為1,則表示禁止?fàn)顟B(tài),還要繼續(xù)循環(huán)
}while(sta & 0x80);
}
4.寫指令時序分析
void Lcd1602_Write_Cmd(unsigned char cmd){
Read_Busy();
LCD1602_RS=0;
LCD1602_RW=0;
LCD1602_DB=cmd; //寫入bit0-bit7
LCD1602_EN=1;
LCD1602_EN=0;
}
5.讀數(shù)據(jù)時序分析
讀數(shù)據(jù)實(shí)際上是讀”顯存“
但是實(shí)際上我們不需要
6.寫數(shù)據(jù)的時序分析
void Lcd1602_Write_Data(unsigned char dat){ //寫數(shù)據(jù)
Read_Busy();
LCD1602_RS=0;
LCD1602_RW=0;
LCD1602_DB=dat; //將數(shù)據(jù)寫入
LCD1602_EN=1;
LCD1602_EN=0;
}
注意點(diǎn):
寫指令-->RS=0
寫數(shù)據(jù)-->RS=1
7.RAM地址映射圖
芯片范圍是0-39每行,但是實(shí)際只用了0-15每行
將”A“給00這個空間,這個00會自動查找該位
4.指令說明
1.顯示模式設(shè)置
lcd1602_write_cmd(0x38);//設(shè)置16*2顯示,數(shù)據(jù)總線8位,5*7點(diǎn)陣/字符
2.顯示開/關(guān)及光標(biāo)設(shè)置
// 本函數(shù)用來設(shè)置當(dāng)前光標(biāo)位置,其實(shí)就是設(shè)置當(dāng)前正在編輯的位置,
// 其實(shí)就是內(nèi)部的數(shù)據(jù)地址指針,其實(shí)就是RAM顯存的偏移量
// x范圍是0-15,y=0表示上面一行,y=1表示下面一行
void lcd1602_set_cursor(unsigned char x,unsigned char y){//顯示坐標(biāo)位置
unsigned char addr;//鼠標(biāo)所在位置
if(y==0){//第一行
addr=0x00+x;
}else{//第二行
//LCD1602是一行只能顯示16個,但是實(shí)際上一行有40
addr=0x40+x;
}
lcd1602_write_cmd(addr|0x80);
}
關(guān)閉顯示:0000 1000? ?0x08
打開顯示不顯示光比 : 0000 1100? ?0x0c
打開顯示并且顯示光標(biāo)且光標(biāo)閃爍: 0000 1111? ?0x0f
地址指針自動+1,整體屏幕不移動 :0000 0110? ?0x06
3.數(shù)據(jù)控制
控制器內(nèi)部設(shè)有一個數(shù)據(jù)地址指針,用戶可以通過它們來訪問內(nèi)部的全部80字節(jié)RAM
1.數(shù)據(jù)指針設(shè)置
0x80+(0x00-0x0f)? ?第一行設(shè)置地址指針指令
0x80+(0x40-0x4f)? ?第二行設(shè)置地址指針指令
2.讀數(shù)據(jù)
3.寫數(shù)據(jù)
4.其他設(shè)置
0x01? 顯示清屏
0x02? 顯示回車
5.初始化過程
void lcd1602_init(void)
{
lcd1602_write_cmd(0x28);//數(shù)據(jù)總線4位,顯示2行,5*7點(diǎn)陣/字符
lcd1602_write_cmd(0x08);//顯示關(guān)閉【可以省略】
lcd1602_write_cmd(0x01);//顯示清屏【可以省略】
lcd1602_write_cmd(0x0c);//顯示功能開,無光標(biāo),光標(biāo)閃爍
lcd1602_write_cmd(0x06);//寫入新數(shù)據(jù)后光標(biāo)右移,顯示屏不移動
lcd1602_write_cmd(0x01);//清屏
}
4.顯示字符
可以進(jìn)行換行的
/*******************************************************************************
* 函 數(shù) 名 : lcd1602_show_string
* 函數(shù)功能 : LCD1602顯示字符
* 輸 入 : x,y:顯示坐標(biāo),x=0~15,y=0~1;
str:顯示字符串
* 輸 出 : 無
*******************************************************************************/
void lcd1602_show_string(u8 x,u8 y,u8 *str)
{
u8 i=0;
if(y>1||x>15)return;//行列參數(shù)不對則強(qiáng)制退出
if(y<1) //第1行顯示
{
while(*str!='\0')//字符串是以'\0'結(jié)尾,只要前面有內(nèi)容就顯示
{
if(i<16-x)//如果字符長度超過第一行顯示范圍,則在第二行繼續(xù)顯示
{
lcd1602_write_cmd(0x80+i+x);//第一行顯示地址設(shè)置
}
else
{
lcd1602_write_cmd(0x40+0x80+i+x-16);//第二行顯示地址設(shè)置
}
lcd1602_write_data(*str);//顯示內(nèi)容
str++;//指針遞增
i++;
}
}
else //第2行顯示
{
while(*str!='\0')
{
if(i<16-x) //如果字符長度超過第二行顯示范圍,則在第一行繼續(xù)顯示
{
lcd1602_write_cmd(0x80+0x40+i+x);
}
else
{
lcd1602_write_cmd(0x80+i+x-16);
}
lcd1602_write_data(*str);
str++;
i++;
}
}
}
不可以自動換行的
static void Lcd1602_Write_Data(unsigned char dat) //寫數(shù)據(jù)
{
Read_Busy();
LCD1602_RS = 1;
LCD1602_RW = 0;
LCD1602_DB = dat;
LCD1602_EN = 1;
LCD1602_EN = 0;
}
/************* 高層時序 ******************************/
// 本函數(shù)用來設(shè)置當(dāng)前光標(biāo)位置,其實(shí)就是設(shè)置當(dāng)前正在編輯的位置,
// 其實(shí)就是內(nèi)部的數(shù)據(jù)地址指針,其實(shí)就是RAM顯存的偏移量
// x范圍是0-15,y=0表示上面一行,y=1表示下面一行
void LcdSetCursor(unsigned char x,unsigned char y) //坐標(biāo)顯示
{
unsigned char addr;
if(y == 0)
addr = 0x00 + x;
else
addr = 0x40 + x;
Lcd1602_Write_Cmd(addr|0x80);
}
// 函數(shù)功能是:從坐標(biāo)(x,y)開始顯示字符串str
// 注意這個函數(shù)不能跨行顯示,因?yàn)轱@存地址是不連續(xù)的
// 其實(shí)我們可以封裝出一個能夠折行顯示的函數(shù)的
void LcdShowStr(unsigned char x,unsigned char y,unsigned char *str) //顯示字符串
{
LcdSetCursor(x,y); //當(dāng)前字符的坐標(biāo)
while(*str != '\0')
{
Lcd1602_Write_Data(*str++);
}
}
5.代碼實(shí)現(xiàn)
lcd1602.c
#include <reg51.h>
// 對LCD1602的底層以及高層時序做封裝
// IO接口定義
#define LCD1602_DB P0 //data bus 數(shù)據(jù)總線
// 控制總線
sbit LCD1602_RS = P2^6;
sbit LCD1602_RW = P2^5;
sbit LCD1602_EN = P2^7;
/************ 低層時序 ********************************/
void Read_Busy() //忙檢測函數(shù),判斷bit7是0,允許執(zhí)行;1禁止
{
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);
}
void Lcd1602_Write_Cmd(unsigned char cmd) //寫命令
{
Read_Busy();
LCD1602_RS = 0;
LCD1602_RW = 0;
LCD1602_DB = cmd;
LCD1602_EN = 1;
LCD1602_EN = 0;
}
void Lcd1602_Write_Data(unsigned char dat) //寫數(shù)據(jù)
{
Read_Busy();
LCD1602_RS = 1;
LCD1602_RW = 0;
LCD1602_DB = dat;
LCD1602_EN = 1;
LCD1602_EN = 0;
}
/************* 高層時序 ******************************/
// 本函數(shù)用來設(shè)置當(dāng)前光標(biāo)位置,其實(shí)就是設(shè)置當(dāng)前正在編輯的位置,
// 其實(shí)就是內(nèi)部的數(shù)據(jù)地址指針,其實(shí)就是RAM顯存的偏移量
// x范圍是0-15,y=0表示上面一行,y=1表示下面一行
void LcdSetCursor(unsigned char x,unsigned char y) //坐標(biāo)顯示
{
unsigned char addr;
if(y == 0)
addr = 0x00 + x;
else
addr = 0x40 + x;
Lcd1602_Write_Cmd(addr|0x80);
}
// 函數(shù)功能是:從坐標(biāo)(x,y)開始顯示字符串str
// 注意這個函數(shù)不能跨行顯示,因?yàn)轱@存地址是不連續(xù)的
// 其實(shí)我們可以封裝出一個能夠折行顯示的函數(shù)的
void LcdShowStr(unsigned char x,unsigned char y,unsigned char *str) //顯示字符串
{
LcdSetCursor(x,y); //當(dāng)前字符的坐標(biāo)
while(*str != '\0')
{
Lcd1602_Write_Data(*str++);
}
}
// 初始化LCD,使之能夠開始正常工作
void InitLcd1602() //1602初始化
{
Lcd1602_Write_Cmd(0x38); //打開,5*8,8位數(shù)據(jù)
//Lcd1602_Write_Cmd(0x0c); // 打開顯示并且無光標(biāo)
Lcd1602_Write_Cmd(0x0f); // 打開顯示并且光標(biāo)閃爍
Lcd1602_Write_Cmd(0x06);
Lcd1602_Write_Cmd(0x01); //清屏
}
lcd1602.h
#ifndef __lcd1602__H__
#define __lcd1602__H__
#include<reg51.h>
#define u8 unsigned char
//只需要聲明高層時序即可,而底層時序是不需要聲明
//因?yàn)槲覀冊陬^文件中聲明這個函數(shù),目的是為了讓別的文件去包含這個
//從而調(diào)用這個頭文件中聲明的函數(shù),所以我們只需要聲明1602.c中將來
//會被外部.c文件調(diào)用的哪些函數(shù)即可,而且1602.c中自己使用的內(nèi)部函數(shù)將來也
//不會被外部.c文件調(diào)用,因此就不用聲明了。
void LcdSetCursor(unsigned char x,unsigned char y);
void LcdShowStr(unsigned char x,unsigned char y,unsigned char *str);
void lcd1602_show_string(u8 x,u8 y,u8 *str);
void InitLcd1602();
#endif
main.c
#include"lcd1602.h"
void main(){
InitLcd1602();
LcdShowStr(0, 0, "nihao,xiaolin");
}
6.LCD12864
1.什么是LCD12864
(1)128p*64p,注意不是字符而是pixel【像素】
(2)沒有內(nèi)置字庫,用戶需要提供字模給LCD12864內(nèi)部的控制器
(3)常見外觀有2種
(4)可以顯示文字(英文,中文或者其他文字),可以顯示圖片(點(diǎn)陣圖)
2.原理圖和數(shù)據(jù)手冊和接線
1.接線確認(rèn)
2.原理圖(開發(fā)板底板,屏幕轉(zhuǎn)接板)
3.數(shù)據(jù)手冊(LCD12894,ST7565【內(nèi)部控制器】)
https://www.dfrobot.com.cn/image/data/FIT0021/CN/LCD12864%20chinese%20char.pdf
?
http://pdf-html.ic37.com/pdf_file_A/20200531/pdf_pdf/pdf4/SITRONIX/ST756_datasheet_832636/135203/ST756_datasheet.pdf
7.LCD12864低層時序分析
1.學(xué)習(xí)方法
(1)找準(zhǔn)數(shù)據(jù)手冊中關(guān)鍵信息點(diǎn),用來查而不是挨個看
(2)數(shù)據(jù)手冊對照官方示例代碼來參照對比
(3)要結(jié)合各部分原理圖,各部分?jǐn)?shù)據(jù)手冊,實(shí)例代碼來綜合分析
(4)必要時做筆記
2.ST7565低層時序分析
由于我們找不到時序圖所以只能通過引腳描述來進(jìn)行分析
1.寫指令
void LcdSt7565_WriteCmd(cmd){
LCD12864_CS=0; //chip select 打開片選
LCD12864_RD=1; //disable read 讀失能
LCD12864_RS=0; //select command 懸著命令
LCD12864_RW=0; //slect write 選擇寫模式
_nop_();
_nop_();
DATA_PORT = cmd; //put command,放置命令
_nop_();
_nop_();
LCD12864_RW = 1; //command writing ,寫入命令
}
2.寫數(shù)據(jù)
void LcdSt7565_WriteData(dat)
{
LCD12864_CS = 0; //chip select,打開片選
LCD12864_RD = 1; //disable read,讀失能
LCD12864_RS = 1; //select data,選擇數(shù)據(jù)
LCD12864_RW = 0; //select write,選擇寫模式
_nop_();
_nop_();
DATA_PORT = dat; //put data,放置數(shù)據(jù)
_nop_();
_nop_();
LCD12864_RW = 1; //data writing,寫數(shù)據(jù)
}
8.ST7565的指令集
1.高層時序分析
1.指令式交互系統(tǒng)
實(shí)際上我們是給CPU編程,控制ST7565
2.指令表是關(guān)鍵
操作手冊
2.指令系統(tǒng)學(xué)習(xí)方法
(1)沿著數(shù)據(jù)手冊順序分析
(2)沿著示例代碼按需分析
3.逐個分析
對應(yīng)上面的P32頁
1. 打開開關(guān):Display ON/OFF
Display ON/OFF
? ? ? ? ? ? ? ? ? ? ? ? 1010 1111? ? ? ? ? ? ? ? 0xaf? ? on
? ? ? ? ? ? ? ? ? ? ? ? 1010 1110? ? ? ? ? ? ? ? 0xae? ? off
2.一行顯示:Display Start Line Set
顯示行號設(shè)置
? ? ? ? 0x 0100 0000+(0-63)
? ? ? ? 0x40+(0-63)? ? ? ? ? ? ? ? 表示要將內(nèi)容顯示在第0-63行
實(shí)際上ST7565是65*132【多了一行沒有顯示】
3.頁地址設(shè)置:Page Address Set
設(shè)置page address? ?
? ? ? ? 1011 0000+(0-7)
? ? ? ? 0xB0+(0-7)? ? 表示設(shè)置page address
4.列地址設(shè)置Column Address Set
設(shè)置column address? ? ?
? ? ? ? 一個完整指令是分為2條相連的指令合起來的。必須連發(fā)2個
? ? ? ? 指令1:0001 0000+高4位? ? ? ? 0x10+高4位
? ? ? ? 指令2:0000 0000+低4位? ? ? ? 0x00+低4位
5.設(shè)置從哪一個方向開始顯示:ADC Select
設(shè)置ADC
? ? ? ? 0xA0? ? ? ? normal? ? ? ? ? ? ? ? columu address 從左往后的
? ? ? ? 0xa1? ? ? ? ?reverse? ? ? ? ? ? ? ?columu address 從右往左的
6.設(shè)置相反的顯示:Display Normal/Reverse
該命令可以反轉(zhuǎn)點(diǎn)亮和熄滅的顯示,而不覆蓋顯示數(shù)據(jù) RAM 的內(nèi)容。 完成此操作后
顯示數(shù)據(jù) RAM 內(nèi)容被保留。
7.軟件復(fù)位:Reset
在初始化的時候,應(yīng)該先硬件復(fù)位【LCD12864_RSET = 0】,在軟件復(fù)位【LcdSt7565_WriteCmd(0xE2)】。
8.設(shè)置背景光對比度:Electronic volume
1000 0001? ?---->0x81
4.對照官方代碼進(jìn)行解析:初始化操作
初始化函數(shù):
(1)第一類指令:時序需要
(2)第二類指令:硬件特性設(shè)置需要的(比如屏幕亮度,對比度之類)
(3)第三類指令:顯示i參數(shù)相關(guān)的:A1/A0
/*******************************************************************************
* 函 數(shù) 名 : LCD12864_Init
* 函數(shù)功能 : 初始化12864
* 輸 入 : 無
* 輸 出 : 無
* 說 明 : LCD12864的命令指令可以查看例程文件夾下的《ST7565p數(shù)據(jù)手冊》
* * 的第51頁的位置。
*******************************************************************************/
void Lcd12864_Init()
{
uchar i;
LCD12864_RSET = 0;//硬件復(fù)位
for (i=0; i<100; i++);//讓內(nèi)部進(jìn)行復(fù)位
LCD12864_CS = 0;//打開片選,選中芯片
LCD12864_RSET = 1;//關(guān)閉復(fù)位
//----------------Start Initial Sequence(時序)-------//
//------程序初始化設(shè)置,具體命令可以看文件夾下---//
//--軟件初始化--//
LcdSt7565_WriteCmd(0xE2); //軟件復(fù)位:reset
for (i=0; i<100; i++); //延時一下
//--表格第8個命令,0xA0段(左右)方向選擇正常方向(0xA1為反方向)--//
// 0xA0對應(yīng)0-127,0xA1對應(yīng)4-131
LcdSt7565_WriteCmd(0xA0); //ADC select segment direction
//--表格第15個命令,0xC8普通(上下)方向選擇選擇反向,0xC0為正常方向--//
LcdSt7565_WriteCmd(0xC8); //Common direction
//--表格第9個命令,0xA6為設(shè)置字體為黑色,背景為白色---//
//--0xA7為設(shè)置字體為白色,背景為黑色---//
LcdSt7565_WriteCmd(0xA6); //reverse display
//--表格第10個命令,0xA4像素正常顯示,0xA5像素全開--//
LcdSt7565_WriteCmd(0xA4); //normal display
//--表格第11個命令,0xA3偏壓為1/7,0xA2偏壓為1/9--//
LcdSt7565_WriteCmd(0xA2); //bias set 1/9
//--表格第19個命令,這個是個雙字節(jié)的命令,0xF800選擇增壓為4X;--//
//--0xF801,選擇增壓為5X,其實(shí)效果差不多--//
LcdSt7565_WriteCmd(0xF8); //Boost ratio set
LcdSt7565_WriteCmd(0x01); //x4
//--表格第18個命令,這個是個雙字節(jié)命令,高字節(jié)為0X81,低字節(jié)可以--//
//--選擇從0x00到0X3F。用來設(shè)置背景光對比度。---/
LcdSt7565_WriteCmd(0x81); //V0 a set
LcdSt7565_WriteCmd(0x23);
//--表格第17個命令,選擇調(diào)節(jié)電阻率--//
LcdSt7565_WriteCmd(0x25); //Ra/Rb set
//--表格第16個命令,電源設(shè)置。--//
LcdSt7565_WriteCmd(0x2F);
for (i=0; i<100; i++);
//--表格第2個命令,設(shè)置顯示開始位置--//
LcdSt7565_WriteCmd(0x40); //start line
//--表格第1個命令,開啟顯示--//
LcdSt7565_WriteCmd(0xAF); // display on
for (i=0; i<100; i++);
}
9.清屏操作
/*******************************************************************************
* 函 數(shù) 名 : LCD12864_ClearScreen
* 函數(shù)功能 : 清屏12864
* 輸 入 : 無
* 輸 出 : 無
*******************************************************************************/
void Lcd12864_ClearScreen(void)
{
uchar i, j;
for(i=0; i<8; i++)//行--64行分為8頁【8個bit位容易操作】
{
//--表格第3個命令,設(shè)置Y的坐標(biāo)--//
//--Y軸有64個,一個坐標(biāo)8位,也就是有8個坐標(biāo)--//
//所以一般我們使用的也就是從0xB0到0x07【設(shè)置頁地址0xB0+(0-7)】,就夠了--//
LcdSt7565_WriteCmd(0xB0+i);
//--表格第4個命令,設(shè)置X坐標(biāo)--//
//--當(dāng)你的段初始化為0xA1時【4-131】,X坐標(biāo)從0x10,0x04到0x18,0x04,一共128位--//
//--當(dāng)你的段初始化為0xA0時【0-127】,X坐標(biāo)從0x10,0x00到0x18,0x00,一共128位--//
//--在寫入數(shù)據(jù)之后X坐標(biāo)的坐標(biāo)是會自動加1的,我們初始化使用0xA1所以--//
//--我們的X坐標(biāo)從0x10,0x00開始---//
LcdSt7565_WriteCmd(0x10);
LcdSt7565_WriteCmd(0x00);
//--X軸有128位,就一共刷128次,X坐標(biāo)會自動加1,所以我們不用再設(shè)置坐標(biāo)--//
for(j=0; j<128; j++)
{
LcdSt7565_WriteData(0x00); //如果設(shè)置背景為白色時,清屏選擇0XFF
}
}
}
擴(kuò)展
此時我們設(shè)置白背景,黑字
所以0x00顯示白字,0xff顯示黑字
下面我們設(shè)置0xf0【則在一頁中,上面四行顯示黑色,下面四行顯示白色】
//--X軸有128位,就一共刷128次,X坐標(biāo)會自動加1,所以我們不用再設(shè)置坐標(biāo)--//
for(j=0; j<128; j++)
{
LcdSt7565_WriteData(0xf0); //如果設(shè)置背景為白色時,清屏選擇0XFF
}
10.LCD12864顯示文字
1.文字顯示的原理
(1)字模
(2)像素&顯存的對應(yīng)關(guān)系:一一對應(yīng)
(3)顯示函數(shù):將字模丟到正確的顯存中去
2.字模的獲取
(1)芯片自帶字庫
(2)網(wǎng)上下載字庫
(3)字模生成軟件自助生成
3.代碼實(shí)戰(zhàn)顯示6*8ASCII碼
1.先弄初始化函數(shù)和清屏函數(shù)
main.c
#include"st7565.h"
void main(){
Lcd12864_Init();
Lcd12864_ClearScreen();
while(1);
}
st7565.c
#include "st7565p.h"
/*******************************************************************************
* 函 數(shù) 名 : LCD12864_WriteCmd
* 函數(shù)功能 : 寫入一個命令到12864
* 輸 入 : cmd
* 輸 出 : 無
*******************************************************************************/
void LcdSt7565_WriteCmd(cmd)
{
LCD12864_CS = 0; //chip select,打開片選
LCD12864_RD = 1; //disable read,讀失能
LCD12864_RS = 0; //select command,選擇命令
LCD12864_RW = 0; //select write,選擇寫模式
_nop_();
_nop_();
DATA_PORT = cmd; //put command,放置命令
_nop_();
_nop_();
LCD12864_RW = 1; //command writing ,寫入命令
}
/*******************************************************************************
* 函 數(shù) 名 : LcdSt7565_WriteData
* 函數(shù)功能 : 寫入一個數(shù)據(jù)到12864
* 輸 入 : dat
* 輸 出 : 無
*******************************************************************************/
void LcdSt7565_WriteData(dat)
{
LCD12864_CS = 0; //chip select,打開片選
LCD12864_RD = 1; //disable read,讀失能
LCD12864_RS = 1; //select data,選擇數(shù)據(jù)
LCD12864_RW = 0; //select write,選擇寫模式
_nop_();
_nop_();
DATA_PORT = dat; //put data,放置數(shù)據(jù)
_nop_();
_nop_();
LCD12864_RW = 1; //data writing,寫數(shù)據(jù)
}
/*******************************************************************************
* 函 數(shù) 名 : LCD12864_Init
* 函數(shù)功能 : 初始化12864
* 輸 入 : 無
* 輸 出 : 無
* 說 明 : LCD12864的命令指令可以查看例程文件夾下的《ST7565p數(shù)據(jù)手冊》
* * 的第51頁的位置。
*******************************************************************************/
void Lcd12864_Init()
{
uchar i;
LCD12864_RSET = 0;//硬件復(fù)位
for (i=0; i<100; i++);//讓內(nèi)部進(jìn)行復(fù)位
LCD12864_CS = 0;//打開片選,選中芯片
LCD12864_RSET = 1;//關(guān)閉復(fù)位
//----------------Start Initial Sequence(時序)-------//
//------程序初始化設(shè)置,具體命令可以看文件夾下---//
//--軟件初始化--//
LcdSt7565_WriteCmd(0xE2); //軟件復(fù)位:reset
for (i=0; i<100; i++); //延時一下
//--表格第8個命令,0xA0段(左右)方向選擇正常方向(0xA1為反方向)--//
// 0xA0對應(yīng)0-127,0xA1對應(yīng)4-131
LcdSt7565_WriteCmd(0xA0); //ADC select segment direction
//--表格第15個命令,0xC8普通(上下)方向選擇選擇反向,0xC0為正常方向--//
LcdSt7565_WriteCmd(0xC8); //Common direction
//--表格第9個命令,0xA6為設(shè)置字體為黑色,背景為白色---//
//--0xA7為設(shè)置字體為白色,背景為黑色---//
LcdSt7565_WriteCmd(0xA6); //reverse display
//--表格第10個命令,0xA4像素正常顯示,0xA5像素全開--//
LcdSt7565_WriteCmd(0xA4); //normal display
//--表格第11個命令,0xA3偏壓為1/7,0xA2偏壓為1/9--//
LcdSt7565_WriteCmd(0xA2); //bias set 1/9
//--表格第19個命令,這個是個雙字節(jié)的命令,0xF800選擇增壓為4X;--//
//--0xF801,選擇增壓為5X,其實(shí)效果差不多--//
LcdSt7565_WriteCmd(0xF8); //Boost ratio set
LcdSt7565_WriteCmd(0x01); //x4
//--表格第18個命令,這個是個雙字節(jié)命令,高字節(jié)為0X81,低字節(jié)可以--//
//--選擇從0x00到0X3F。用來設(shè)置背景光對比度。---/
LcdSt7565_WriteCmd(0x81); //V0 a set
LcdSt7565_WriteCmd(0x23);
//--表格第17個命令,選擇調(diào)節(jié)電阻率--//
LcdSt7565_WriteCmd(0x25); //Ra/Rb set
//--表格第16個命令,電源設(shè)置。--//
LcdSt7565_WriteCmd(0x2F);
for (i=0; i<100; i++);
//--表格第2個命令,設(shè)置顯示開始位置--//
LcdSt7565_WriteCmd(0x40); //start line
//--表格第1個命令,開啟顯示--//
LcdSt7565_WriteCmd(0xAF); // display on
for (i=0; i<100; i++);
}
/*******************************************************************************
* 函 數(shù) 名 : LCD12864_ClearScreen
* 函數(shù)功能 : 清屏12864
* 輸 入 : 無
* 輸 出 : 無
*******************************************************************************/
void Lcd12864_ClearScreen(void)
{
uchar i, j;
for(i=0; i<8; i++)//行--64行分為8頁【8個bit位容易操作】
{
//--表格第3個命令,設(shè)置Y的坐標(biāo)--//
//--Y軸有64個,一個坐標(biāo)8位,也就是有8個坐標(biāo)--//
//所以一般我們使用的也就是從0xB0到0x07【設(shè)置頁地址0xB0+(0-7)】,就夠了--//
LcdSt7565_WriteCmd(0xB0+i);
//--表格第4個命令,設(shè)置X坐標(biāo)--//
//--當(dāng)你的段初始化為0xA1時【4-131】,X坐標(biāo)從0x10,0x04到0x18,0x04,一共128位--//
//--當(dāng)你的段初始化為0xA0時【0-127】,X坐標(biāo)從0x10,0x00到0x18,0x00,一共128位--//
//--在寫入數(shù)據(jù)之后X坐標(biāo)的坐標(biāo)是會自動加1的,我們初始化使用0xA1所以--//
//--我們的X坐標(biāo)從0x10,0x00開始---//
LcdSt7565_WriteCmd(0x10);
LcdSt7565_WriteCmd(0x00);
//--X軸有128位,就一共刷128次,X坐標(biāo)會自動加1,所以我們不用再設(shè)置坐標(biāo)--//
for(j=0; j<128; j++)
{
LcdSt7565_WriteData(0x00); //如果設(shè)置背景為白色時,清屏選擇0XFF
}
}
}
st7565.h
#ifndef __ST7565_H
#define __ST7565_H
#include<reg51.h>
#include<intrins.h>
//---重定義關(guān)鍵詞---//
#ifndef uchar
#define uchar unsigned char
#endif
#ifndef uint
#define uint unsigned int
#endif
//--定時使用的IO口--//
#define DATA_PORT P0
sbit LCD12864_CS = P3^2;
sbit LCD12864_RSET = P3^3;
sbit LCD12864_RS = P2^6;
sbit LCD12864_RW = P2^7;
sbit LCD12864_RD = P2^5;
//--定義全局函數(shù)--//
void LcdSt7565_WriteCmd(cmd);
void LcdSt7565_WriteData(dat);
void Lcd12864_Init();
void Lcd12864_ClearScreen(void);
#endif
2.網(wǎng)上找到6*8ASCII碼字庫
nios ii 之5110液晶屏(6*8、8*16 ASCII字符,16*16 漢字,常用圖標(biāo),圖案,超全字庫+函數(shù)代碼)_6*8 ascii-CSDN博客
3.編寫函數(shù)顯示數(shù)值
我們在編寫下面代碼遇到的問題:
1)我們需要將模取高位和低位的時候需要分別使用一個變量組裝起來
2)字庫中對應(yīng)的ASCII是十六進(jìn)制,記得加上0x
3)當(dāng)我們遇到問題的時候一個模塊一個模塊的檢驗(yàn)
//在屏幕的(x,y)坐標(biāo)處,顯示c這個字符
//(x,y)表示像素點(diǎn)的坐標(biāo)值,所以x范圍是0-127,y的范圍是0-63
//注意,因?yàn)轱@示文字是以整頁為單位的,為了簡單起見必須頁對齊顯示
//因此給的y值必須頁首地址,就是0 8 16 24 等數(shù)值
void ascii_display(unsigned char x,unsigned char y,unsigned char c){
unsigned char i=0;
unsigned char x1,x2;
//【第一步,設(shè)置顯示的x和y坐標(biāo)】
//y坐標(biāo),其實(shí)就是page address
Lcdst7565_WriteCmd(0xB0+y/8);//因?yàn)橹荒苷擄@示,所以我們要除8才能保證
//x坐標(biāo),只要在范圍內(nèi)別超出就可以了
x1=(x>>4) & 0x0f; //顯示高4位
x2=x& 0x0f; //顯示低4位
//因?yàn)槲覀円褂?次發(fā)送才可以將數(shù)據(jù)發(fā)出
Lcdst5765_Write_Cmd(0x10+x1);
Lcdst7565_Write_Cmd(0x00+x2);
//【第二步,找到c對應(yīng)的字?!? //ASCII_6_8[x-20][0] 字模的第一個字節(jié)
//【第三步,將字模丟到顯存中去】
for(i=0;i<6;i++){
//因?yàn)槲覀冏謳焓菑摹?0”開始,所以要-20
//注意點(diǎn):我們是十六進(jìn)制,所以是0x20
Lcdst7565_Write_Cmd(ASCII_6_8[c-0x20][i]);
}
遺留問題:
(1)初始化和字模不匹配,造成字是反的
(2)初始化不對,造成x坐標(biāo)是從右往左的
4.解決遺留問題
1.修改初始化代碼從左往右顯示
(1)先修改初始化函數(shù)中的顯示方向代碼
//--表格第8個命令,0xA0段(左右)方向選擇正常方向(0xA1為反方向)--//
// 0xA0對應(yīng)0-127,0xA1對應(yīng)4-131
LcdSt7565_WriteCmd(0xA0); //ADC select segment direction
(2)修改清屏函數(shù)
//--表格第4個命令,設(shè)置X坐標(biāo)--//
//--當(dāng)你的段初始化為0xA1時【4-131】,X坐標(biāo)從0x10,0x04到0x18,0x04,一共128位--//
//--當(dāng)你的段初始化為0xA0時【0-127】,X坐標(biāo)從0x10,0x00到0x18,0x00,一共128位--//
//--在寫入數(shù)據(jù)之后X坐標(biāo)的坐標(biāo)是會自動加1的,我們初始化使用0xA1所以--//
//--我們的X坐標(biāo)從0x10,0x00開始---//
LcdSt7565_WriteCmd(0x10);
LcdSt7565_WriteCmd(0x00);
(3)修改顯示數(shù)值的函數(shù)
4.顯示跨頁(16*16)
(1)超過8*8的字符如何顯示
(2)常見漢字字模大小是16*16
zimo.h
#ifndef __ZIMO_H__
#define __ZIMO_H__
unsigned char code zimo_zhu[] =
{0x80,0xA0,0x90,0x8E,0x88,0x88,0x88,0xFF,0x88,0x88,0x88,0x88,0x88,0x80,0x80,0x00,
0x20,0x20,0x10,0x08,0x04,0x02,0x01,0xFF,0x01,0x02,0x04,0x08,0x10,0x20,0x20,0x00,};
unsigned char code zimo_you[] =
{0x04,0x04,0x04,0x84,0xE4,0x3C,0x27,0x24,0x24,0x24,0x24,0xE4,0x04,0x04,0x04,0x00,
0x04,0x02,0x01,0x00,0xFF,0x09,0x09,0x09,0x09,0x49,0x89,0x7F,0x00,0x00,0x00,0x00,};
unsigned char code zimo_peng[] =
{0x00,0xFE,0x22,0xFE,0x00,0xFE,0x22,0xFE,0x00,0xFC,0x16,0x25,0x84,0xFC,0x00,0x00,
0x60,0x1F,0x22,0xBF,0x40,0x3F,0x82,0xFF,0x00,0x13,0x12,0x12,0x52,0x82,0x7E,0x00,};
#endif
自定義數(shù)值輸出
void hanzi_display(unsigned char x,unsigned char y,unsigned char zimo[]){
unsigned char i=0;
unsigned char x1,x2;
//先顯示上面一半
Lcdst7565_WriteCmd(0xB0+y/8);
//x坐標(biāo),只要在范圍內(nèi)別超出即可
x1=(x>>4)&0x0f;
x2=x&0x0f;
Lcdst7565_Write(0x10+x1);
Lcdst7565_Write(0x00+x2);
for(i=0;i<16;i++){ //因?yàn)槲覀兪?6*16,此時是顯示第一頁的0-15列
Lcdst7565_WriteData(zimo[i]);
}
//在顯示下面一半
Lcdst7565_WriteCmd(0xB0+y/8+1);
//x坐標(biāo),只要在范圍內(nèi)別超出即可
x1=(x>>4)&0x0f;
x2=x&0x0f;
Lcdst7565_Write(0x10+x1);
Lcdst7565_Write(0x00+x2);
for(i=16;i<32;i++){
Lcdst7565_WriteData(zimo[i]);
}
}
hanzi_display(0, 0, zimo_zhu);
hanzi_display(16, 0, zimo_you);
hanzi_display(32, 0, zimo_peng);
使用簡單的方式
#ifndef __ZIMO_H__
#define __ZIMO_H__
unsigned char code zimo_zhuyoupeng[3][32] =
{
// 朱
{0x80,0xA0,0x90,0x8E,0x88,0x88,0x88,0xFF,0x88,0x88,0x88,0x88,0x88,0x80,0x80,0x00,
0x20,0x20,0x10,0x08,0x04,0x02,0x01,0xFF,0x01,0x02,0x04,0x08,0x10,0x20,0x20,0x00,},
// 有
{0x04,0x04,0x04,0x84,0xE4,0x3C,0x27,0x24,0x24,0x24,0x24,0xE4,0x04,0x04,0x04,0x00,
0x04,0x02,0x01,0x00,0xFF,0x09,0x09,0x09,0x09,0x49,0x89,0x7F,0x00,0x00,0x00,0x00,},
// 鵬
{0x00,0xFE,0x22,0xFE,0x00,0xFE,0x22,0xFE,0x00,0xFC,0x16,0x25,0x84,0xFC,0x00,0x00,
0x60,0x1F,0x22,0xBF,0x40,0x3F,0x82,0xFF,0x00,0x13,0x12,0x12,0x52,0x82,0x7E,0x00,},
};
#endif
hanzi_display(16*0, 16, zimo_zhuyoupeng[0]);
hanzi_display(16*1, 16, zimo_zhuyoupeng[1]);
hanzi_display(16*2, 16, zimo_zhuyoupeng[2]);
11.LCD12864顯示圖片
1.思路分析
通過取字模軟件將圖片翻譯為一個十六進(jìn)制的數(shù)組
2.圖片數(shù)據(jù)獲取
1)取模軟件,轉(zhuǎn)換為bmp
2)查看像素
3)調(diào)節(jié)分辨率---》畫圖工具
3.寫顯示函數(shù)
// 在屏幕上顯示一個圖片,從屏幕左上角開始顯示
//因?yàn)槭钦麄€屏幕顯示,所以跟清屏函數(shù)差不多
void pic_display(unsigned char pic[])
{
uchar i, j;
uint k = 0;//遍歷數(shù)組,128*64/8=1024
for(i=0; i<8; i++)//每一個page
{
LcdSt7565_WriteCmd(0xB0+i); //y軸
LcdSt7565_WriteCmd(0x10); //高4位
LcdSt7565_WriteCmd(0x00);//低4位
//--X軸有128位,就一共刷128次,X坐標(biāo)會自動加1,所以我們不用再設(shè)置坐標(biāo)--//
for(j=0; j<128; j++)
{
LcdSt7565_WriteData(pic[k++]); //如果設(shè)置背景為白色時,清屏選擇0XFF
}
}
}
4.調(diào)試
pic_display(pic);
12.LCD9648
1.SPI傳輸數(shù)據(jù)
/*******************************************************************************
* 函 數(shù) 名 : lcd9648_spi_write_byte
* 函數(shù)功能 : LCD9648 SPI傳輸數(shù)據(jù)
* 輸 入 : dat:數(shù)據(jù)
* 輸 出 : 無
*******************************************************************************/
void lcd9648_spi_write_byte(u8 dat)
{
u8 i=0;
for(i=0;i<8;i++)//循環(huán)8次將一個字節(jié)傳輸
{
if((dat&0x80)!=0)
SDA = 1;
else
SDA = 0;
dat<<= 1;//先寫高位再寫低位
SCL = 0;
SCL = 1;//時鐘上升沿寫入數(shù)據(jù)
}
}
2.寫
1.寫數(shù)據(jù)
/*******************************************************************************
* 函 數(shù) 名 : lcd9648_write_dat
* 函數(shù)功能 : LCD9648寫數(shù)據(jù)
* 輸 入 : dat:數(shù)據(jù)
* 輸 出 : 無
*******************************************************************************/
void lcd9648_write_dat(u8 dat)
{
CS0 = 0;//使能
RS = 1;//選擇數(shù)據(jù)
lcd9648_spi_write_byte(dat);//發(fā)送數(shù)據(jù)
CS0 = 1;//失能
}
2.寫指令
/*******************************************************************************
* 函 數(shù) 名 : lcd9648_write_cmd
* 函數(shù)功能 : LCD9648寫命令
* 輸 入 : cmd:命令
* 輸 出 : 無
*******************************************************************************/
void lcd9648_write_cmd(u8 cmd)
{
CS0 = 0;//使能
RS = 0;//選擇命令
lcd9648_spi_write_byte(cmd);//發(fā)送命令
CS0 = 1;//失能
}
3.指令集
1.第1條指令:將數(shù)據(jù)字節(jié)寫入內(nèi)存
2.第二條指令:從內(nèi)存中讀取數(shù)據(jù)字節(jié)
根據(jù)頁地址 (PA) 寄存器和列地址 (CA) 寄存器寫入/讀取數(shù)據(jù)字節(jié)(命令 1,2)訪問顯示數(shù)據(jù) RAM。 PA 和 CA 也可以通過發(fā)出設(shè)置頁地址和設(shè)置列地址命令直接編程。
3.第三條指令:獲取當(dāng)前顯示器的狀態(tài)
BZ:BZ=1的時候,此時處于忙狀態(tài)。BZ=0時候,表示可以接收命令
MX:
DE:顯示使能標(biāo)志。當(dāng)表示可以使能DE=1,DE=0的時候表示不能使能
RST:復(fù)位標(biāo)志。RST=1的時候表示正在復(fù)位,RST=0的時候表示復(fù)位結(jié)束。
4.第四條指令:設(shè)置列地址
5.第五條指令:設(shè)置電源消耗設(shè)置
6.第六條指令:設(shè)置滾動一行命令
設(shè)置滾動行數(shù)。范圍:0~63 滾動行設(shè)置將顯示的圖像向上滾動 SL 行。圖標(biāo)輸出 CIC 不會受到“設(shè)置滾動線”命令的影響。
7.第七條指令:設(shè)置頁地址
地址是0-7(所以使用4位數(shù)進(jìn)行標(biāo)識)
8.第八條指令:設(shè)置 VLCD 電阻比
9.第9條指令:設(shè)置光對比度
10.第11條指令:將所有像素設(shè)置為開啟
11.第12條指令:設(shè)置顯示啟用
該命令用于對寄存器 DC[2] 進(jìn)行編程。當(dāng)DC[2]設(shè)置為1時,UC1701x將首先退出睡眠模式,恢復(fù)電源,然后打開COM驅(qū)動程序和SEG驅(qū)動程序。
12.第13條指令:設(shè)置顯示x方向
MX=0:表示按照默認(rèn)方向顯示---》0xa0
MX=1:表示按照相反的方向顯示--->0xa1
13.第14條指令:設(shè)置顯示y方向
D0-D2:用來顯示要設(shè)置的頁數(shù)(y軸方向)-----》0-7
MY=1:按照相反的方向顯示
MY=0:按照默認(rèn)的方向顯示
14.第15條指令:系統(tǒng)重置
該命令將激活系統(tǒng)重置。控制寄存器值將重置為其默認(rèn)值。 RAM 中的數(shù)據(jù)存儲不會受到影響。
15.第16條指令:設(shè)置不進(jìn)行操作
16.第17條指令:設(shè)置屏幕的顯示亮度(bias ratio:偏置比)
17.第18條指令:設(shè)置光標(biāo)更新模式
此命令用于設(shè)置光標(biāo)更新模式功能。當(dāng)光標(biāo)更新模式設(shè)置時,UC1701x 將使用寄存器 CA 的值更新寄存器 CR。列地址 CA 將隨著寫入 RAM 數(shù)據(jù)操作而增加,但無論 WA 設(shè)置是什么,地址環(huán)繞都將掛起。但是,列地址在讀取 RAM 數(shù)據(jù)操作中不會遞增。設(shè)置光標(biāo)更新模式可用于實(shí)現(xiàn)“讀后寫RAM”功能。重置游標(biāo)更新模式時,列地址 (CA) 將恢復(fù)為設(shè)置游標(biāo)更新模式命令之前的值。此對命令及其功能的目的是支持游標(biāo)實(shí)現(xiàn)的“讀后寫”功能。
18.第19條指令:重置光標(biāo)位置
19.第20/21號指令:設(shè)置靜態(tài)指示器關(guān)閉/打開
20.第22條指令:設(shè)置助推器比率
21.第23條指令:設(shè)置省電
22.第24條指令:設(shè)置高級程序控制 0
文章來源:http://www.zghlxwxcb.cn/news/detail-716852.html
23.第25條指令:設(shè)置高級程序控制1
?文章來源地址http://www.zghlxwxcb.cn/news/detail-716852.html
到了這里,關(guān)于【單片機(jī)】16-LCD1602和12864和LCD9648顯示器的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!