STM32 LCD1602 液晶显示屏
LCD1602常用指令有哪些呢?
STM32是怎样通过IIC去控制LCD1602液晶显示屏的呢?
回帖(1)
2022-1-26 11:18:00
STM32通过(软/硬IIC)控制LCD1602液晶显示屏(IIC转8位并口的PCF8574转接板的使用)原创
A0,A1,A2全部悬空,那么PCF8574的IIC地址为0x4e.(具体原因,看PCF8574说明)
//--------------------------------------------------------------------------------------------------//
下面是关于PCF8574连接LCD1602最重要的一张表:
可见PCF8574的P7---P0分别接LCD1602的DB7---DB4,背光,EN,R/W,R/S管脚。
P7
| P6
| P5
| P4
| P3
| P2
| P1
| P0
|
DB7
| DB6
| DB5
| DB4
| 背光
| EN(CS)
| R/W
| R/S
|
|
|
|
| 1背光开
0背光关
| 1使能
0禁止
| 1读
0写
| 1数据
0指令
|
写命令:输入RS=0,RW=0,E=高脉冲
写数据:输入RS=1,RW=0,E=高脉冲
读数据我们一般不用。P3=1背光开,P3=0背光关
unsigned char LCD_data = 0x08;//全局变量 缺省状态 00001000使背光开启 00000000背光关闭
LCD1602常用指令:(共11条,最常用的以下四条)
(1)0x01清屏
(2)0x28 4线传输模式,5×7字符,2排显示
(3)0x80 显示字符的初始地址.
(4)0x0c 打开显示屏,不显示光标,光标所在位置的字符不闪烁。
上面的是指令,如果是8线通信,表示DB7-DB0八根针,一次传入LCD1602。如果是4线通信,表示只用DB7-DB4四根针,一个8位指令需要传两次,第一次传高4位,第二次传低4位.
这里的LCD1602指令要和LCD1602 的控制管脚区命令分开,比如,PCF8574发出0x08,这个不是LCD1602的标准指令,这代表什么呢?表示高4位为0000(无意义),低4位数为1000对应:开背光,EN=0,R/W=写(非读),R/S=命令(非数据)。高4位是没有意义的,因为,高4位如果是数据或命令必须EN由0变1才能被LCD1602接受。
在举个例:
比如0x09代表:开背光,EN=0,写,传入的是数据,
比如0x0c代表:开背光,EN=1,写,传入的是命令。注意这个0x0c 和上面的LCD1602的指令0x0c 没有任何联系。
第一个0x0c 表示PCF8574发出8位一个字节00001100表示高4位没有意义,低4位表示:开背光,EN=1,写,指令。
第二个0x0c表示传送给LCD1602的命令,(功能是开显示,不显示光标,光标所在位置的字符不闪烁。)需要拆成高4位,低四位,各传1次,每次都要EN由0变1,LCD1602才能接收。
下面我们讨论一下:开背光,我们可以把这个LCD1602的管脚直接接高电平(表示背光一直亮)。就可以省一个PCF8574的管脚P3。
还有R/W我们可以把这个管脚直接接低电平,R/W=0表示我们只向LCD1602写入,不从LCD1602读(读状态位)。就又可以省一个PCF8574的管脚P1。
但是此时,因为不能读LCD1602状态位(不知道LCD1602是否为忙),所以不停发送指令和数据时,一定要注意控制好延时。
下面是写命令函数代码详解(见注释分析):
void LCD_WriteCMD(unsigned char cmd)
{
DelayUs(25);
LCD_data &=~(1<<(1-1));//RS=0;00001000最后一位设为0
LCD_data &=~(1<<(2-1));//RW=0;00001000倒数第二位设为0
I2C_WriteByte(LCD_data);//发送00001000说明开背光,EN=0,发送,命令,(这段程序的作用是LCD管脚位控)
LCD_data &= 0X0f; //清高四位00001000变为00001000
LCD_data |= cmd & 0xf0; //写指令高四位,先与f0得到为cmd高4+0000再和00001000或,得到cmd高4+1000
I2C_WriteByte(LCD_data);//发送cmd高四位,cmd高4+1000;
LCD_EN();
cmd = cmd<<4;//cmd低四位移到高四位准备发送。cmd低4+0000
LCD_data &= 0X0f; //清高四位 cmd高4+1000与00001111变成00001000;
LCD_data |= cmd & 0xf0; //写指令低四位cmd低4+0000与11110000得到cmd低4+0000;再或00001000得到cmd低4+1000
I2C_WriteByte(LCD_data);//发送cmd低4+1000;
LCD_EN();
}
下面是写数据函数代码,可以看出基本上和上面是一样的只有一点不一样就是函数第一句,RS=1代表写入的是数据。
void LCD_WriteDAT(unsigned char dat)
{
DelayUs(25);
LCD_data |= (1<<(1-1));//RS=1;代表写入的是数据。得到00001001
LCD_data &=~(1<<(2-1));//RW=0;写操作。
I2C_WriteByte(LCD_data);//写入00001001说明开背光,EN=0,发送,数据(这段程序的作用是LCD管脚位控)
LCD_data &= 0X0f; //清高四位00001001清高四位得到00001001
LCD_data |= dat & 0xf0; //写数据高四位最后得到dat高4+1001
I2C_WriteByte(LCD_data);//写入dat高4+1001
LCD_EN();
dat = dat<<4;//低4位移到高4位。
LCD_data &= 0X0f; //清高四位 得到0000+1001
LCD_data |= dat & 0xf0; //写数据低四位 得到低4+1001
I2C_WriteByte(LCD_data);发送低4+1001
LCD_EN();
}
程序说明,首先知道我们用的是LCD1602的4线连接方法,所有必须先发送命令0x28,代表001010××(最后两位任意),这个指令代表三个意思:(1)以后都是传输四线信号DB7,DB6,DB5和DB4(DB3-DB0不用),(2)5×7的字符,(3)两排显示。这个命令一发,以后每次命令和数据都必须发送两次,比如10011100,第一次先发高四位1001,再发低四位1100,注意,第一次发送完高四位EN 由0变1,后四位数据LCD1602读入,所以写指令逻辑是这样的:
(1),RS=1;代表写入的是数据,
(2),RW=0;代表下面是写操作,
(3),高四位->DB7---DB4,代表指令高四位写入
(4),EN由0变1,这时传入的高四位被1602接收。
(5),低四位->DB7----DB4,代表指令低四位写入。
(6),EN又0变1,这时传入的低四位被1602接收。
因为我们用这个转接板,STM32不能直接位控LCD1602,所以麻烦就在这里。每个位控信号(比如背景灯开/关,EN,R/W,R/S)都必须通过STM32的IIC通讯写8位到PCF8574,
转成P7 –DB7 ,P6-DB6,P5-DB5,P4-DB4,P3-背景灯,P2-EN,P1-R/W,P0-R/S.所以省了几根线,但是控制复杂很多,STM32通过IIC通信,经PCF8574转接板驱动LCD1602,虽然只用2根线即可通信,但是程序远没有在C51上简单,好懂。
回到正题,接着说程序过程:分两种方法,A,是用STM32 的硬件I2C,B,是用STM32模拟I2C通信,但程序过程差不多。
(1),编写GPIO初始化函数,(A情况下,增加I2C初始化)
(2),编写8位循环写入函数,
(3),编写写字节函数(每次写八位一个字节之前,都必须先写PCF8574从站地址,0x4e一次)
比如我们写指令0x28,过程是这样的,
第一步写0x4e,第二步写0x28.
(4),编写写命令函数
(5),编写写数据函数
(6),编写LCD初始化函数,分三部分:注意0x28必须第一,0x01必须最后,中间加命令随便。另外清屏需要时间,必须有延时.
A,写入指令0x28,(代表4线数据,5×7字符,2排显示)
B,写入指令0x80,(代表显示地址从80开始)
C,写入指令0x01,(清屏)
(7)准备工作结束,以下可以编写主程序。
(8)LCD初始化,
(9)发送显示起始地址:第一排0x80+0x00(第一排第一个字符),第二排0x80+0x40(第二行第一个字符)。
(10)发送显示的字符:比如显示“A”,直接发送A就可以。当然显示多个字符还要用到字符数组和指针进行循环。
最后说一下因为是IIC通信,每次发送都必须是有开始和结束的时序,每次每个字节传到pcf8574 ,pcf8574接收后,都要把SDA拉低,应答(ASK)。
启动:SCL高电平中间SDA高变低,紧接着SCL变低,
停止:SCL低电平变高电平后,SDA低变高,
通信多个连续字节,启动,停止一次即可。
再说一下使用STM32与LCD1602 (IIC软/硬)通讯时,用软硬I2C的区别,我做了实验,没有区别,只是一个模拟IIC记着在写指令和数据时,在合适的位置一定加start,和stop,这时IIC的基本通信原则,硬件IIC则必须有硬件IIC初始化,发送字符用标准发送程序。自带start和stop。
当我们用STM32 通过IIC控制LCD1602显示屏时,其实是很鸡肋的,虽然省了几个管脚,但是控制LCD1602的基础管脚:背光,EN,R/W,R/S,是隔山打牛。
写控制指令和数据,也是隔山打牛。因为这个转接板,PCF8574写LCD1602 用的4线通信,每次传输还要拆成高4位,低4位分两次传输。每次传输还要EN由0-1让LCD1602确认。如果没有读LCD1602状态,只用延时的话,时序控制比较困难,缺乏稳定。如果你用软IIC的,还要考虑IIC的通信时序(SCL和SDA配合),还有start 和stop。(现在硬件如此便宜)可以说得不偿失。我认为如果改一下接线方法:PCF8574的P7-P0如下:
P7 | P6 | P5 | P4 | P3 | P2 | P1 | P0 |
DB7 | DB6 | DB5 | DB4 | DB3 | DB2 | DB1 | DB0 |
另外 把LCD1602的 背光控制管脚接高电平,把R/W控制管脚接低电平,把EN控制管脚接stm32一个管脚比如PB5,R/S接stm32一个管脚比如PB4,这样其实是用了STM32的4个管脚见下图:
背光控制管脚(LCD1602) | RW管脚(LCD1602) |
接5V | 接地 |
PB6(STM32) | PB7(STM32) | PB5(STM32) | PB4(STM32) |
SCL(PCF8574) | SDA(PCF8574) | EN(LCD1602) | R/S(LCD1602) |
这样的话程序就简单可靠很多。
程序不便公开,在网上能搜索到的就是。
STM32通过(软/硬IIC)控制LCD1602液晶显示屏(IIC转8位并口的PCF8574转接板的使用)原创
A0,A1,A2全部悬空,那么PCF8574的IIC地址为0x4e.(具体原因,看PCF8574说明)
//--------------------------------------------------------------------------------------------------//
下面是关于PCF8574连接LCD1602最重要的一张表:
可见PCF8574的P7---P0分别接LCD1602的DB7---DB4,背光,EN,R/W,R/S管脚。
P7
| P6
| P5
| P4
| P3
| P2
| P1
| P0
|
DB7
| DB6
| DB5
| DB4
| 背光
| EN(CS)
| R/W
| R/S
|
|
|
|
| 1背光开
0背光关
| 1使能
0禁止
| 1读
0写
| 1数据
0指令
|
写命令:输入RS=0,RW=0,E=高脉冲
写数据:输入RS=1,RW=0,E=高脉冲
读数据我们一般不用。P3=1背光开,P3=0背光关
unsigned char LCD_data = 0x08;//全局变量 缺省状态 00001000使背光开启 00000000背光关闭
LCD1602常用指令:(共11条,最常用的以下四条)
(1)0x01清屏
(2)0x28 4线传输模式,5×7字符,2排显示
(3)0x80 显示字符的初始地址.
(4)0x0c 打开显示屏,不显示光标,光标所在位置的字符不闪烁。
上面的是指令,如果是8线通信,表示DB7-DB0八根针,一次传入LCD1602。如果是4线通信,表示只用DB7-DB4四根针,一个8位指令需要传两次,第一次传高4位,第二次传低4位.
这里的LCD1602指令要和LCD1602 的控制管脚区命令分开,比如,PCF8574发出0x08,这个不是LCD1602的标准指令,这代表什么呢?表示高4位为0000(无意义),低4位数为1000对应:开背光,EN=0,R/W=写(非读),R/S=命令(非数据)。高4位是没有意义的,因为,高4位如果是数据或命令必须EN由0变1才能被LCD1602接受。
在举个例:
比如0x09代表:开背光,EN=0,写,传入的是数据,
比如0x0c代表:开背光,EN=1,写,传入的是命令。注意这个0x0c 和上面的LCD1602的指令0x0c 没有任何联系。
第一个0x0c 表示PCF8574发出8位一个字节00001100表示高4位没有意义,低4位表示:开背光,EN=1,写,指令。
第二个0x0c表示传送给LCD1602的命令,(功能是开显示,不显示光标,光标所在位置的字符不闪烁。)需要拆成高4位,低四位,各传1次,每次都要EN由0变1,LCD1602才能接收。
下面我们讨论一下:开背光,我们可以把这个LCD1602的管脚直接接高电平(表示背光一直亮)。就可以省一个PCF8574的管脚P3。
还有R/W我们可以把这个管脚直接接低电平,R/W=0表示我们只向LCD1602写入,不从LCD1602读(读状态位)。就又可以省一个PCF8574的管脚P1。
但是此时,因为不能读LCD1602状态位(不知道LCD1602是否为忙),所以不停发送指令和数据时,一定要注意控制好延时。
下面是写命令函数代码详解(见注释分析):
void LCD_WriteCMD(unsigned char cmd)
{
DelayUs(25);
LCD_data &=~(1<<(1-1));//RS=0;00001000最后一位设为0
LCD_data &=~(1<<(2-1));//RW=0;00001000倒数第二位设为0
I2C_WriteByte(LCD_data);//发送00001000说明开背光,EN=0,发送,命令,(这段程序的作用是LCD管脚位控)
LCD_data &= 0X0f; //清高四位00001000变为00001000
LCD_data |= cmd & 0xf0; //写指令高四位,先与f0得到为cmd高4+0000再和00001000或,得到cmd高4+1000
I2C_WriteByte(LCD_data);//发送cmd高四位,cmd高4+1000;
LCD_EN();
cmd = cmd<<4;//cmd低四位移到高四位准备发送。cmd低4+0000
LCD_data &= 0X0f; //清高四位 cmd高4+1000与00001111变成00001000;
LCD_data |= cmd & 0xf0; //写指令低四位cmd低4+0000与11110000得到cmd低4+0000;再或00001000得到cmd低4+1000
I2C_WriteByte(LCD_data);//发送cmd低4+1000;
LCD_EN();
}
下面是写数据函数代码,可以看出基本上和上面是一样的只有一点不一样就是函数第一句,RS=1代表写入的是数据。
void LCD_WriteDAT(unsigned char dat)
{
DelayUs(25);
LCD_data |= (1<<(1-1));//RS=1;代表写入的是数据。得到00001001
LCD_data &=~(1<<(2-1));//RW=0;写操作。
I2C_WriteByte(LCD_data);//写入00001001说明开背光,EN=0,发送,数据(这段程序的作用是LCD管脚位控)
LCD_data &= 0X0f; //清高四位00001001清高四位得到00001001
LCD_data |= dat & 0xf0; //写数据高四位最后得到dat高4+1001
I2C_WriteByte(LCD_data);//写入dat高4+1001
LCD_EN();
dat = dat<<4;//低4位移到高4位。
LCD_data &= 0X0f; //清高四位 得到0000+1001
LCD_data |= dat & 0xf0; //写数据低四位 得到低4+1001
I2C_WriteByte(LCD_data);发送低4+1001
LCD_EN();
}
程序说明,首先知道我们用的是LCD1602的4线连接方法,所有必须先发送命令0x28,代表001010××(最后两位任意),这个指令代表三个意思:(1)以后都是传输四线信号DB7,DB6,DB5和DB4(DB3-DB0不用),(2)5×7的字符,(3)两排显示。这个命令一发,以后每次命令和数据都必须发送两次,比如10011100,第一次先发高四位1001,再发低四位1100,注意,第一次发送完高四位EN 由0变1,后四位数据LCD1602读入,所以写指令逻辑是这样的:
(1),RS=1;代表写入的是数据,
(2),RW=0;代表下面是写操作,
(3),高四位->DB7---DB4,代表指令高四位写入
(4),EN由0变1,这时传入的高四位被1602接收。
(5),低四位->DB7----DB4,代表指令低四位写入。
(6),EN又0变1,这时传入的低四位被1602接收。
因为我们用这个转接板,STM32不能直接位控LCD1602,所以麻烦就在这里。每个位控信号(比如背景灯开/关,EN,R/W,R/S)都必须通过STM32的IIC通讯写8位到PCF8574,
转成P7 –DB7 ,P6-DB6,P5-DB5,P4-DB4,P3-背景灯,P2-EN,P1-R/W,P0-R/S.所以省了几根线,但是控制复杂很多,STM32通过IIC通信,经PCF8574转接板驱动LCD1602,虽然只用2根线即可通信,但是程序远没有在C51上简单,好懂。
回到正题,接着说程序过程:分两种方法,A,是用STM32 的硬件I2C,B,是用STM32模拟I2C通信,但程序过程差不多。
(1),编写GPIO初始化函数,(A情况下,增加I2C初始化)
(2),编写8位循环写入函数,
(3),编写写字节函数(每次写八位一个字节之前,都必须先写PCF8574从站地址,0x4e一次)
比如我们写指令0x28,过程是这样的,
第一步写0x4e,第二步写0x28.
(4),编写写命令函数
(5),编写写数据函数
(6),编写LCD初始化函数,分三部分:注意0x28必须第一,0x01必须最后,中间加命令随便。另外清屏需要时间,必须有延时.
A,写入指令0x28,(代表4线数据,5×7字符,2排显示)
B,写入指令0x80,(代表显示地址从80开始)
C,写入指令0x01,(清屏)
(7)准备工作结束,以下可以编写主程序。
(8)LCD初始化,
(9)发送显示起始地址:第一排0x80+0x00(第一排第一个字符),第二排0x80+0x40(第二行第一个字符)。
(10)发送显示的字符:比如显示“A”,直接发送A就可以。当然显示多个字符还要用到字符数组和指针进行循环。
最后说一下因为是IIC通信,每次发送都必须是有开始和结束的时序,每次每个字节传到pcf8574 ,pcf8574接收后,都要把SDA拉低,应答(ASK)。
启动:SCL高电平中间SDA高变低,紧接着SCL变低,
停止:SCL低电平变高电平后,SDA低变高,
通信多个连续字节,启动,停止一次即可。
再说一下使用STM32与LCD1602 (IIC软/硬)通讯时,用软硬I2C的区别,我做了实验,没有区别,只是一个模拟IIC记着在写指令和数据时,在合适的位置一定加start,和stop,这时IIC的基本通信原则,硬件IIC则必须有硬件IIC初始化,发送字符用标准发送程序。自带start和stop。
当我们用STM32 通过IIC控制LCD1602显示屏时,其实是很鸡肋的,虽然省了几个管脚,但是控制LCD1602的基础管脚:背光,EN,R/W,R/S,是隔山打牛。
写控制指令和数据,也是隔山打牛。因为这个转接板,PCF8574写LCD1602 用的4线通信,每次传输还要拆成高4位,低4位分两次传输。每次传输还要EN由0-1让LCD1602确认。如果没有读LCD1602状态,只用延时的话,时序控制比较困难,缺乏稳定。如果你用软IIC的,还要考虑IIC的通信时序(SCL和SDA配合),还有start 和stop。(现在硬件如此便宜)可以说得不偿失。我认为如果改一下接线方法:PCF8574的P7-P0如下:
P7 | P6 | P5 | P4 | P3 | P2 | P1 | P0 |
DB7 | DB6 | DB5 | DB4 | DB3 | DB2 | DB1 | DB0 |
另外 把LCD1602的 背光控制管脚接高电平,把R/W控制管脚接低电平,把EN控制管脚接stm32一个管脚比如PB5,R/S接stm32一个管脚比如PB4,这样其实是用了STM32的4个管脚见下图:
背光控制管脚(LCD1602) | RW管脚(LCD1602) |
接5V | 接地 |
PB6(STM32) | PB7(STM32) | PB5(STM32) | PB4(STM32) |
SCL(PCF8574) | SDA(PCF8574) | EN(LCD1602) | R/S(LCD1602) |
这样的话程序就简单可靠很多。
程序不便公开,在网上能搜索到的就是。
举报
更多回帖