您好,欢迎进入山西润盛进出口有限公司!

咨询服务热线

15383419322

文本LCD模块的控制FPGA

发布时间:2023-12-22 11:17人气:

文本LCD模块便宜且易于使用微控制器或FPGA进行接口。

这是一个1行x 16个字符的模块:

要控制LCD模块,您需要11个IO引脚来驱动8位数据总线和3个控制信号。3个控制信号是:

  • E:启用或“ LCD选择”。高活跃。
  • 读/写:读/写。0写入,1读取。
  • RS:寄存器选择,0表示命令字节,1表示数据字节。

大多数LCD模块都基于HD44780芯片或是兼容的。查阅Wikipedia以获取更多信息。

7位设计

让我们用FPGA板驱动LCD模块。这是我们设计的框图:

Pluto从PC串行端口接收数据,对其进行反序列化,然后将其发送到LCD模块。解串器与串行接口项目中的模块相同,因此此处仅对其进行实例化。

moduleLCDmodule(clk,RxD,LCD_RS,LCD_RW,LCD_E,LCD_DataBus); inputclk,RxD; outputLCD_RS,LCD_RW,LCD_E; output[7:0]LCD_DataBus; wireRxD_data_ready; wire[7:0]RxD_data; async_receiverdeserializer(.clk(clk),.RxD(RxD),.RxD_data_ready(RxD_data_ready),.RxD_data(RxD_data));

每当串行端口提供一个字节时,“ RxDdataready”将在一个时钟周期内处于活动状态。PC通过串口以8位模式向我们发送数据。理想情况下,我们需要从PC接收9位,以便我们可以驱动8位数据总线和LCD模块的“ RS”线。现在,让我们使用接收到的数据的MSB(第7位)来驱动“ RS”,并将仅7位发送到数据总线。

assignLCD_RS=RxD_data[7]; assignLCD_DataBus={1'b0,RxD_data[6:0]}; //sendsonly7bitstothemodule,paddedwitha'0'infronttomake8bits assignLCD_RW=0;

我们从不读取LCD模块,所以R / W线是接地的。最后一个麻烦是“ E”信号需要长时间激活,即220ns。从FPGA的角度来看,这很长,因为我使用的是25MHz时钟(周期为40ns)。因此,“ E”至少需要驱动5.5个时钟。在这里,我们使用一个计数器对时钟进行计数,将其驱动7个时钟。

reg[2:0]count; always@(posedgeclk)if(RxD_data_ready|(count!=0))count<=count+1;

“ E”信号是通过寄存器创建的,因此可以保证无干扰。

regLCD_E; always@(posedgeclk)LCD_E<=(count!=0);

波形如下所示:

HDL设计在这里。

软件方面

我们对LCD进行初始化并发送一些要显示的数据。

以下是初始化LCD模块并显示“ hello”的C代码。

voidmain(){ OpenComm();//initializetheLCDmodule WriteCommByte(0x38);//"FunctionSet"in8bitsmode WriteCommByte(0x0F);//"DisplayON"withcursorsON WriteCommByte(0x01);//"ClearDisplay",cantakeupto1.64ms,sothedelay Sleep(2);//display"hello" WriteCommByte('h'+0x80); WriteCommByte('e'+0x80); WriteCommByte('l'+0x80); WriteCommByte('l'+0x80); WriteCommByte('o'+0x80); CloseComm(); }

完整的代码在这里。

要获取有关HD44780指令集的更多信息,请在此处检查。

8位设计

主要缺点是较早的设计是我们仅向LCD数据总线发送7位。这是一个问题,因为无法再使用LCD模块的设置DD RAM地址命令。

一种简单的解决方法是使用转义符。我们选择了字符0x00。

新协议如下:

  • 要发送命令字节,请在其前面加上0x00。
  • 要发送数据字节,只需发送它,不需要前缀。

新的C代码是:

voidmain(){ OpenComm();//initializetheLCDmodule WriteCommByte(0x00);WriteCommByte(0x38);//"FunctionSet"in8bitsmode WriteCommByte(0x00);WriteCommByte(0x0F);//"DisplayON"withcursorsON WriteCommByte(0x00);WriteCommByte(0x01);//"ClearDisplay",cantakeupto1.64ms,sothedelay Sleep(2); WriteCommByte('h'); WriteCommByte('e'); WriteCommByte('l'); WriteCommByte('l'); WriteCommByte('o'); WriteCommByte(0x00);WriteCommByte(0xC0);//goonsecondhalfofLCD WriteCommByte('e'); WriteCommByte('v'); WriteCommByte('e'); WriteCommByte('r'); WriteCommByte('y'); WriteCommByte('o'); WriteCommByte('n'); WriteCommByte('e'); CloseComm(); }

新的HDL代码如下所示:

moduleLCDmodule(clk,RxD,LCD_RS,LCD_RW,LCD_E,LCD_DataBus); inputclk,RxD;outputLCD_RS,LCD_RW,LCD_E; output[7:0]LCD_DataBus; wireRxD_data_ready; wire[7:0]RxD_data; async_receiverdeserialer(.clk(clk),.RxD(RxD),.RxD_data_ready(RxD_data_ready),.RxD_data(RxD_data)); assignLCD_RW=0;assignLCD_DataBus=RxD_data; wireReceived_Escape=RxD_data_ready&(RxD_data==0); wireReceived_Data=RxD_data_ready&(RxD_data!=0);reg[2:0]count; always@(posedgeclk)if(Received_Data|(count!=0))count<=count+1; //activateLCD_Efor6clocks,soat25MHz,that's6x40ns=240ns regLCD_E; always@(posedgeclk)if(LCD_E==0) LCD_E<=Received_Data; else LCD_E<=(count!=6); regLCD_instruction; always@(posedgeclk)if(LCD_instruction==0) LCD_instruction<=Received_Escape; else LCD_instruction<=(count!=7); assignLCD_RS=~LCD_instruction; endmodule

HD44780规范显示,“ E”变低后,“ RS”必须在10ns内有效。因此,您会注意到这里“ E”仅被驱动6个时钟,并且“ LCDinstruction”标志仅在时钟7之后被复位,以提供25ns的空间。

That's all folks!轮到您尝试了。

  • 联系方式
  • 传 真:
  • 手 机:15383419322
  • 电 话:15383419322
  • 地 址:山西太原市杏花岭区解放路 175 号万达中心 A 座 33 楼 3301 室
友情链接
plc控制器
自动化设备
自动化设备
伺服驱动器
在线咨询

咨询电话:

15383419322

  • 微信扫码 关注我们

Copyright © 2022-2024 山西润盛进出口有限公司 版权所有 晋ICP备2021008479号-14

晋公网安备 14010702070906号

扫一扫咨询微信客服
15383419322