問題由來
我們之前分享過了數(shù)碼管、OLED、LCD12864,最近群里小伙伴有需要STM32驅(qū)動LCD1602的源碼,咱們今天就分享一下,如何使用STM32驅(qū)動LCD1602液晶屏,授人以魚不如授人以漁,一起來看看怎么驅(qū)動LCD1602。
淘寶下單買一個:
LCD1602的意思就是每行可以顯示16個字符,一共可以顯示2行內(nèi)容。
- Keil 5
- 公眾號開源的最小系統(tǒng)核心板
- PC為Win10
- 3.3V LCD1206的型號為:1602A
LCD1602一共有16個引腳,具體定義如下:
本次實例選用的LCD1602背部如下所示,顯示的型號為:1602A
具體連接情況:
注意:程序下載之后,如果屏幕沒有任何內(nèi)容顯示,先別急著否定,可以嘗試調(diào)節(jié)一下與VO引腳相連的電位器,有時是因為對比度的原因?qū)е聸]有任何內(nèi)容顯示。
寫操作過程時序分析
-
根據(jù)向LCD1602液晶寫入的內(nèi)容是指令還是數(shù)據(jù),將RS引腳置低或置高。寫指令,將RS置低;寫數(shù)據(jù),將RS置高;
-
因為是寫操作,所以我們需要將R/W引腳置低;
-
做好寫數(shù)據(jù)之前的準備工作:先將E引腳置低,然后將要寫的內(nèi)容(一個字節(jié)數(shù)據(jù)),發(fā)送至DB0~DB7上;
封裝的改變DB0~DB7的函數(shù)如下:
void WriteData(u8 data)
{
GPIO_WriteBit(GPIOA, GPIO_Pin_6,(BitAction)((data & 0x80) >> 7 )); //D7
GPIO_WriteBit(GPIOA, GPIO_Pin_0,(BitAction)((data & 0x40) >> 6 ));
GPIO_WriteBit(GPIOC, GPIO_Pin_3,(BitAction)((data & 0x20) >> 5 ));
GPIO_WriteBit(GPIOC, GPIO_Pin_2,(BitAction)((data & 0x10) >> 4 ));
GPIO_WriteBit(GPIOC, GPIO_Pin_1,(BitAction)((data & 0x08) >> 3 ));
GPIO_WriteBit(GPIOC, GPIO_Pin_0,(BitAction)((data & 0x04) >> 2 ));
GPIO_WriteBit(GPIOC, GPIO_Pin_13,(BitAction)((data & 0x02) >> 1 ));
GPIO_WriteBit(GPIOB, GPIO_Pin_9,(BitAction)(data & 0x01)); //DB0
}
- 因為寫操作時,下降沿有效,所以我們先將E腳置高,延時一段時間之后,再置低,在此過程中,完成寫操作。
綜上所述,發(fā)送命令和數(shù)據(jù)的函數(shù)封裝如下:
/* 向LCD1602液晶寫入一字節(jié)命令,cmd-待寫入命令值 */
void LCD1602_Write_Cmd(u8 cmd)
{
LCD_RS_Clr();
LCD_RW_Clr();
LCD_EN_Clr();
WriteData(cmd);
LCD_EN_Set();
delay_ms(5);
LCD_EN_Clr();
}
/* 向LCD1602液晶寫入一字節(jié)數(shù)據(jù),dat-待寫入數(shù)據(jù)值 */
void LCD1602_Write_Dat(u8 dat)
{
LCD_RS_Set();
LCD_RW_Clr();
LCD_EN_Clr();
WriteData(dat);
LCD_EN_Set();
delay_ms(5);
LCD_EN_Clr();
}
因為要讓LCD1602顯示內(nèi)容,只需要往LCD1602發(fā)送數(shù)據(jù)即可,即只需要完成寫操作,不需要讀操作,所以我們只需要封裝上面寫指令和寫數(shù)據(jù)兩個函數(shù)即可,未封裝讀操作的函數(shù)。
LCD1602內(nèi)部提供了較為豐富的指令設(shè)置,比如:清顯示(清屏)、光標回原點、顯示開/關(guān)、光標開/關(guān)、顯示字符閃爍、光標移位、顯示移位等指令。
通過選擇相應(yīng)的指令設(shè)置,用戶可以實現(xiàn)多種字符顯示樣式。
查看上面指令表,我們可以知道清屏操作,只需要發(fā)送指令0x01即可。
利用上面封裝的寫指令void LCD1602_Write_Cmd(u8 cmd)
函數(shù),我們封裝清屏操作函數(shù)如下:
/* 清屏 */
void LCD1602_ClearScreen(void)
{
LCD1602_Write_Cmd(0x01);
}
發(fā)送此指令,DDRAM(display data RAM)中的內(nèi)容全部清除,顯示消失;地址計數(shù)器AC=0,自動增1模式;顯示歸位,光標或者閃爍回到原點(顯示屏左上角),但并不改變移位設(shè)置模式。
要顯示字符,首先要設(shè)定顯示的地址,即告訴LCD1602在哪里顯示字符,查找LCD1602數(shù)據(jù)手冊,我們知道內(nèi)部顯示地址(DDRAM)如下:
如果要顯示在第一行,第一個字符的位置,那么其地址就是0x00,要顯示在第二行,第一個字符位置,那么其地址就是0x40。
具體對應(yīng)關(guān)系如下:
顯示RAM起始地址,即光標位置,封裝函數(shù)如下:
/* 設(shè)置顯示RAM起始地址,亦即光標位置,(x,y)-對應(yīng)屏幕上的字符坐標 */
void LCD1602_Set_Cursor(u8 x, u8 y)
{
u8 addr;
if (y == 0)
addr = 0x00 + x;
else
addr = 0x40 + x;
LCD1602_Write_Cmd(addr | 0x80);
}
要想顯示具體的內(nèi)容,就要先設(shè)置在液晶上顯示的位置,即調(diào)用上面的函數(shù)void LCD1602_Set_Cursor(u8 x, u8 y)
,利用其設(shè)定顯示的坐標位置,然后調(diào)用寫數(shù)據(jù)函數(shù)void LCD1602_Write_Dat(u8 dat)
,這樣就完成了待顯示字符的寫入。
/* 在液晶上顯示字符串,(x,y)-對應(yīng)屏幕上的起始坐標,str-字符串指針 */
void LCD1602_Show_Str(u8 x, u8 y, u8 *str)
{
LCD1602_Set_Cursor(x, y);
while(*str != '\0')
{
LCD1602_Write_Dat(*str++);
}
}
比如我們想要在液晶屏第二行顯示小哈哥的個人網(wǎng)站的網(wǎng)址:www.xiaohage.com,需要的代碼如下:
LCD1602_Show_Str(0, 1, "www.xiaohage.com");
這里為什么寫入字符’1’,LCD1602正好可以顯示1呢?因為在LCD1602內(nèi)部有這樣一個CGROM和CGRAM中字符代碼與字符圖形對應(yīng)關(guān)系表:
上圖即為CGROM表,表的最左邊一列為允許用戶自定義字模的CGRAM空間。
表的橫行是其高4位地址,表的列是其低4位地址。
如果要顯示字符’1’,對應(yīng)的十六進制為0x31,即高四位為0011,低四位為xxxx0001,組合一起即為要顯示內(nèi)容的位置,具體如上表中框選位置。
再對照ASCII碼表,發(fā)現(xiàn)二者是一一對應(yīng)的,所以我們直接發(fā)送ASCII碼,即可對應(yīng)其實際的字符。
/* 初始化1602液晶 */
void LCD1602_Init(void)
{
LCD1602_Write_Cmd(0x38); //16*2顯示,5*7點陣,8位數(shù)據(jù)口
delay_ms(5);
LCD1602_Write_Cmd(0x0c); //開顯示,光標關(guān)閉
delay_ms(5);
LCD1602_Write_Cmd(0x06); //文字不動,地址自動+1
delay_ms(5);
LCD1602_Write_Cmd(0x01); //清屏
delay_ms(5);
}
總的來說,LCD1602的驅(qū)動還是挺簡單的,液晶屏的單價也不貴,唯一的缺點就是不能顯示中文,至于選取哪種液晶屏,各位可以根據(jù)需要自由選取哈。
一個專注于嵌入式知識分享,學(xué)習(xí)路上不迷路,歡迎關(guān)注。
想加技術(shù)交流群的,可以加我微信【chengxuyuanxiaoha】,讓我拉你進群。