HD44780 兼容
液晶模块 在之前的文章中,我们详细讨论了使用 HD44780 LCD 控制器/驱动器芯片的 LCD 模块。这些 LCD 模块的引脚排列如图 1 所示。
图 1.图片由AAC提供。
如您所见,有 3 个控制引脚(RS、R/W 和 E)以及 8 个数据引脚(DB7 至 DB0)。对于写操作,我们需要向这些引脚施加适当的电压,如下图 2 的时序图所示。
图 2. 由日立提供。
上述时序图的不同延迟值如下表给出:
表 1. 由日立提供。
有多种指令可用于配置 LCD 模块。您可以在本数据表的第 24 页上找到这些指令的完整列表。下面列出了一些重要的说明。
表2
设计构建模块:路径 1
我们想要显示消息“HELLO WORLD!” 在液晶显示屏上。让我们看看我们的数字系统需要哪些构建块来与 LCD 模块进行通信。我们需要一个 ROM 来存储消息字符的 ASCII 代码。如图 3 所示,ROM 的输出将连接到 LCD 模块的 8 个数据引脚。
图3
“你好,世界!” 消息有12个字符,我们可以使用12?8位ROM来存储消息。然而,我们考虑使用 16 ? 8 位 ROM 来存储消息,这样我们就可以显示长达 16 个字符的消息(LCD 行的长度)。
你可能想知道,如果我们的消息多有 16 个字符长,为什么上图显示的是 20 ? 8 位 ROM。这额外的四个字节将用于存储与 LCD 指令相关的数据,以便我们配置模块。例如,如表2所示,我们可以将十六进制值0x38应用于LCD数据引脚,以指定LCD模块应以8位长度接收/发送数据。就像字符代码一样,命令的十六进制值应用于数据引脚,因此,我们可以将它们存储在同一个 ROM 中。
在本文中,我们将使用四个命令(0x38、0x06、0x0C 和 0x01)来配置 LCD。您可以在表 2 中找到这些命令的简要说明。有关详细说明,请参阅本文。因此,我们有一个 20 ? 8 位 ROM,其中前四个字节是 0x38、0x06、0x0C 和 0x01。接下来的 16 个字节存储我们消息的 ASCII 代码。
考虑图2的时序图,我们观察到施加到DB7-DB0的数据在一定时间内不应改变,以便LCD可以成功读取它。因此,如图 3 所示,我们需要一组 D 型触发器 (DFF) 来在一段时间内保持 ROM 地址(以及 DB7-DB0)恒定。LCD 读取数据后,我们需要将地址值加一,以将下一个字符/命令应用到 LCD。因此,如图 4 所示,应在 DFF 之前放置一个多路复用器和增量器。
图4
使用多路复用器的选择输入,我们可以指定地址值是应保持不变 (S 1 = 0) 还是递增 (S 1 = 1)。多路复用器有第三个选项,允许我们将地址值重置为00000。这也可以通过重置 DFF 来实现。我们将所有这些块称为Path 1,如图所示。正如本文后面所讨论的,我们将使用S 1信号来控制Path 1模块 内的电路 。addr-reg信号 将用于监视Path 1的状态。
值得一提的是,虽然上图只显示了一个 DFF,但实际上有五个(因为 20 字节 ROM 需要 5 位地址总线)。
设计构建模块:实现延迟
如上所述,应用于 LCD 控制输入的波形应遵循图 2 的时序图。在 RW 和 RS 引脚改变状态后,我们必须等待 t AS才能将 E 引脚设置为逻辑高电平。然后,E 从高到低的转变启动写操作。然而,在 E 下降沿之前 (t DSW ) 和之后 (t H )的一段时间内,数据不应改变。
因此,为了成功地与 LCD 通信,我们必须实现延迟 t AS、t DSW和 t H。这可以通过
计数器来实现。由于我们有时需要停止计数器或重置它,因此我们将在计数器的 DFF 之前放置一个多路复用器。如下图 5 所示。
图5
这样,我们可以使用 S2 输入来控制计数器,而cnt_reg 输出将为我们提供计数器的状态,即所用时间的指示。根据时序图,我们需要三个不同的时间延迟:t AS =40 ns,t DSW =80 ns,t H =10 ns。注意到Mojo V3板的时钟频率为50 MHz(时钟周期为20 ns),我们可以计算出每个时间延迟所需的计数数。
然而,事实证明我的 16x2 LCD 需要更长的延迟才能运行。这可能是因为我使用相对较长的电线和面包板来测试我的设计。在本文中,我将实现 t AS =10 ms 和 t H =3 ms。我会将 E 信号保持为高电平 58 毫秒(PW EH = 58 毫秒)。我的设计应该能够处理更短的延迟。您可以做一些实验并根据您的设计调整这些数字。
计数器需要多少位?选择延迟后,总延迟将为 10+58+3 ms = 71 ms。考虑到 Mojo 的时钟周期 (20 ns),通过从 0 计数到 3,549,999 可以实现 71 ms 的延迟。因此,如图 5 所示,我们需要一个 22 位计数器。
设计构建模块:控制路径
我们需要的终构建块是一个适当控制路径 1 和路径 2 块的单元,以便为 LCD 模块生成所需的波形。这可以通过有限状态机(FSM)来实现,有限状态机接收addr_reg 和cnt_reg 信号(路径 1 和路径 2的状态)并生成适当的s1 和s2 信号。该 FSM 的初始设计如图 6 所示。
图6
请注意,该图仅显示了状态转换(未显示 FSM 的输出)。存在三种状态:在空闲 状态期间,信号获得其初始值。lcd_init 状态应用LCD配置命令;这就是为什么状态转换条件是 (addr_reg = 3 && cnt_reg = 3,550,000)。换句话说,我们有四个命令,当第四个命令(addr_reg = 3)应用于LCD 71 ms(cnt_reg = 3,550,000)时,我们应该进入lcd_print状态,将消息 数据发送到LCD。当我们到达 ROM 末尾 (addr_reg = 19) 时,我们应该等待 71 ms (cnt_reg = 3,550,000),然后转换到空闲状态 。
该项目的困难部分已基本完成。现在,我们只需要设计 FSM 并编写其 Verilog 代码即可。这些任务将在本文的下一部分中讨论。