雷竞技注册
技术文章

如何使用MCU接口16×2 LCD模块

2019年3月04日经过史蒂夫asrar

本文将讨论16x2液晶模块与单片机的接口细节。

本文将讨论一个基本的16x2 LCD模块与单片机的接口细节。

本文将看看一个基本的16×2液晶模块的引脚。然后,将讨论一些重要的说明,常见的液晶模块是兼容的HD44780LCD控制器/驱动芯片。最后,本文给出了一个AVR ATMEGA32单片机与16×2液晶显示器接口的C语言代码示例。

该模块引出线

1602年,一个是一个16字符、2行显示,类似于今天使用的许多其他16x2显示。每个字符以5列× 8行点阵或5列× 10行点阵的形式显示。应该正确地控制这些像素,以便我们能够显示所需的字符。使用微控制器直接控制所有这些像素并不容易,这就是为什么我们通常使用带有控制器/驱动芯片的LCD模块来方便地将LCD连接到处理器。一个常见的LCD驱动程序是HD44780。这些LCD模块的引脚通常如下图1所示。

图1。16×2液晶模块的通用引脚。图片礼貌AAC.

GND和Vcc (+ 5v)引脚为电源引脚。v销用于调节显示对比度。我们可以使用电位器将VEE连接到+5 V以下合适的正电压。Led+和Led-引脚用于打开显示器背光(分别连接到+ 5v和地)。

RS引脚是LCD控制器的寄存器选择器引脚。HD44780具有两个寄存器:指令寄存器(IR)和数据寄存器(DR)。RS引脚是一个控制引脚,指定IR或DR是否应连接到数据总线(DB0至DB7引脚)。当RS低时,选择IR,DB7-DB0被视为指令代码。例如,指令代码可以表示“显示清除”命令。当RS为高时,选择DR,DB7-DB0被视为数据。在这种情况下,DB7-DB0可以是表示诸如“A”的角色的代码。

R/W引脚指定我们是写入模块(R/W=0)还是从模块(R/W=1)读取。

E引脚(“Enable”)开始一个读/写操作,将在下一节讨论。

写操作的时序图

虽然我们可以同时从数据总线写入和读取数据,但写操作更为常见。这就是为什么在本节中,我们将研究写操作的时序图,如图2所示。不同参数的定义和期望值如表1所示。

图2。写操作时序图。图片礼貌日立

表格1礼貌的日立

时序图表明我们应该将RS和R / W引脚设置为适当的值并等待T作为(应该大于40ns)在设置E引脚到逻辑高之前。根据表,E信号应该有一个宽度(PW)大于230纳秒。

然后,E信号应该有一个从高到低的边缘,它开始写操作。请注意,tDSW在此边缘之前,数据必须是有效的。另外,在E下降沿后,控制信号和数据在t表示的一段时间内不应发生变化和tH在图中。另一个重要的问题是“启用周期时间”,它应该大于500ns。这表明,在开始执行下一个读或写操作之前,我们应该等待一段时间。

总之,E上的高到低转换启动数据读写,但必须满足某些定时条件。当将LCD模块与MCU连接时,我们必须考虑这些因素。

重要说明

您可以在此页面24中找到HD44780兼容LCD模块的完整列表数据表。在这里,我们将只使用其中的一些指令来做一些基本的操作。

清晰显示

此指令清除显示。您必须将RS和R/W设置为低逻辑,并执行写入操作,将十六进制值0x01应用到数据总线。此外,数据表声明“clear display”命令“在地址计数器中设置DDRAM地址0”。这是什么意思?

图3。礼貌的日立

显示数据RAM (DDRAM)是一种RAM,它存储我们发送到LCD模块的字符的ASCII码。DDRAM最多可以存储80个字符(它的容量为80×8位)。然而,这80个字符中只有一部分显示在LCD上。例如,在16×2 LCD的情况下,只有32个内存位置被显示。显示的DDRAM地址和LCD位置之间的关系如图4所示。

图4。礼貌的日立

根据图4,如果我们将一个特定的字符写入DDRAM地址0x00,它将显示在上面一行的第一个单元格中。类似地,如果我们向0x40地址写入一个字符,它将出现在下一行的第一个单元格中。

要转到DDRAM的一个特定地址,我们可以将所需的地址写入地址计数器(AC)。此外,AC决定了一个写操作输入的字符在LCD上的位置。

注意,lcd支持移位操作,可以更改图4中所示的关系。例如,将左移应用于图4的默认状态将得到图5。如需更多信息,请参考数据表。


图4。礼貌的日立

现在您熟悉DDRAM和AC,“清除显示”命令的描述应该对您有意义。“清除显示”命令“在地址计数器中设置DDRAM地址0”,因此,它将将光标返回到原始位置(上线的第一单元)。

回家

图6给出了此命令的代码及其描述。

图6。礼貌的日立

该命令还将光标返回到主位置,并将显示返回到其原始状态(如果它被移动)。对于这个命令,不需要考虑DB0。

输入模式设置

图7给出了该命令的详细信息。

图7。礼貌的日立

当“I / D”为1时,在写入操作之后,光标位置递增一个(它在显示器上移动到右侧)。当“I / D”为0时,光标位置由一个(它移动到左侧)递减。

S位指定是否移位显示(移位改变在LCD上显示的DDRAM地址)。当S为0时,显示不移位。对于移位选项(当S=1时),请参考数据表。

在许多情况下,我们希望在写操作之后,光标的位置递增,而显示器仍然保持不变(没有使用shift选项)。对于这样的应用程序,DB7-DB0的命令代码将是十六进制值0x06。

显示开/关控制

这个命令的详细信息如下。

图8。礼貌的日立

通过设置D位为1或0,我们可以分别打开和关闭显示。类似地,C位可以用来打开/关闭光标。B控制光标位置的闪烁能力。因此,如果我们将十六进制值0x0C作为指令写入DB7-DB0, LCD将打开,而光标将关闭。

函数集

下图提供了“函数集”命令的详细信息。

图9。礼貌的日立

DL位指定LCD模块的数据长度。如果DL=1,数据在数据总线(DB7到DB0)上以8位字的形式发送和接收。当DL=0时,数据以4位长度(DB7到DB4)发送和接收。为了简单起见,我们将在本文中使用8位选项。

N位表示显示行数。对于单行显示,N应该是0。对于两行以上的,N应该是1。

“F”决定了字符的字体,通常是0。

因此,当使用16×2 LCD接收和发送8位长度的数据时,DB7-DB0的“函数集”代码将是十六进制值0x38。

设置DDRAM地址

这条指令设置DDRAM的地址。它可以用于在LCD的特定单元中写入一个字符。例如,将十六进制值0x80发送到数据总线将使游标移动到上一行的第一个单元格。

图10。礼貌的日立

现在,我们将使用上面的命令来操作16×2液晶显示器。下表总结了上面讨论的命令。

表2

连接液晶显示器与AVR

现在,我们将编写一些函数来连接16×2 LCD到ATMEGA32。假设如图11所示,A端口连接LCD数据总线,B端口的前3个引脚用于控制LCD的RS、RW、E引脚。注意,图11中没有显示VSS、VDD和VEE的连接。

图11.

我们需要两个函数来编写命令和数据到LCD模块。在此之前,让我们定义以下三个常量:

const unsigned char rs_pin = 0x01;const unsigned char rw_pin = 0x02;const unsigned char e_pin = 0x04;

这些常量将在整个代码中用于指定连接到LCD控制引脚的PORTB引脚编号。例如,RS连接到图11中端口B的第一引脚,因此RS引脚为00000001。E连接到第三引脚,所以E_Pin是00000100。通过这种方式,我们可以很容易地修改常量,以适应使用不同引脚连接的未来项目的代码。我们可以使用以下功能向LCD发送指令:

Void lcd_write_struct (unsigned char struct) {delay_ms(2);PORTB = PORTB & (~ (RS_Pin));PORTB=PORTB & (~(RW_Pin));//它是写操作PORTB=PORTB & (~(E_Pin));//设置E为0(见图1)//将指令放到数据总线上PORTB=PORTB | (E_Pin);//设E为1(见图1)PORTB=PORTB & (~(E_Pin));//设置E为0生成下降边}

这里,“指令”是必须发送到LCD数据总线的命令代码。代码的第一行使用“delay.h”库中的delay_ms()函数引入2毫秒的延迟。我们需要给LCD一些时间来完成它当前的工作(如果有)。引入此延迟是为了考虑图2中的“启用周期时间”约束。类似地,我们可以编写一个函数来发送一个字符到LCD:

Void lcd_write_char (unsigned char c) {delay_ms(2);PORTB = PORTB | (RS_Pin);PORTB=PORTB & (~(RW_Pin));PORTB = PORTB & (~ (E_Pin));门= c;PORTB = PORTB | (E_Pin);PORTB = PORTB & (~ (E_Pin));}

“C”是必须发送到LCD数据总线的数据。以下函数通过从表2中发送一些命令初始化LCD。它还指定MCU的POLTA和PORTB作为输出。

void lcd_init(void){delay_ms(2);DDRA = 0xFF;ddrb = 0xff;lcd_write_instruc(0x06);//光标LCD_WRITE_INSTURC(0x0C)的增量模式;//显示屏,光标关闭LCD_WRITE_INSTRUC(0x38);// 8位数据总线,双线显示}

以下功能清除显示:

Void lcd_clear(Void) {delay_ms(2);lcd_write_instruc (0 x01);//清除display lcd_write_instrc (0x02);//返回显示到它的原始状态,如果它被移动。}

要将AC设置为给定地址,我们可以使用以下功能:

Void lcd_goto(unsigned char column, unsigned char row) {delay_ms(2);If (row==0) lcd_write_struct (0x80 + column); / /写入//查看图4和10 if(row==1) lcd_write_strucc (0xC0+ column);//参见图4和图10}

最后,要编写一个字符串,可以依次使用lcd_write_char()函数:

Void lcd_write_string(char *s) {delay_ms(2);While (*s != 0) {lcd_write_char(*s);s + +;}}

使用这些功能,我们可以具有LCD模块的基本功能。以下代码显示了示例的main()函数:

void main(void){lcd_init();lcd_clear();lcd_goto(0,0);lcd_write_string(“全部约”);lcd_goto(0,1);lcd_write_string(“电路”);虽然(1){继续;}}

使用CodeVision和Proteus工具编译和模拟上述代码的输出结果如图12所示。

图12.

值得提及以上执行上述代码的不同行的MCU延迟提供足够的延迟,以满足图2的不同时序约束,特别是与E信号相关的不同时间约束。事实上,我使用了上面的函数,甚至更快的32位MCU,但如果您遇到任何问题,您可以在代码的相应行中引入小延迟,以确保满足定时要求。


在本文中,我们研究了基本16×2 LCD模块的引脚。我们还检查了HD44780兼容LCD模块的一些最重要的说明。可以调整文章中给出的示例C代码以与来自其他供应商的MCU一起使用。

要查看我完整的文章列表,请访问这个页面

2的评论