1602液晶IP核设计

1602为常见的液晶显示设备,本实验所用的规格为16x2字符型驱动,直观图如下所示。

本实验所用的规格为16x2字符型驱动

上图为本人已完成的LCD液晶驱动显示效果(可以显示任意字符串),由两行组成,可以显示英文字符,部分日语,也可以显示自定义的图像,Spartan-3E所用的1602 (Sitronix ST7066U graphics controller)与FPGA的接口如下所示:

信号说明:
其中SF_D为4位的数据接口位,LCD_E为液晶显示或者不显示控制位,LCD_RS为区分控制或数据信号标志位,当LCD_RS = ‘0’时,表示SF_D为控制信号,LCD_RS=’1’此时SF_D为数据位,LCD_RW为读写控制位,因为不需要从LCD液晶屏中读取数据所以可以简单的再复位操作时,将其清零即可。

可以看出,此1602的数据位为4位,故要写入8位命令时需要进行两次写入操作,写入数据的时序图如下所示,

写入数据的时序图

红线所画为两个字节数据写入所需的最小时差(这个需要特别注意)
根据Spartan-3E的GUIDE,可以知道1602工作的基本流程主要分为上电初始化、写命令、设置读写地址、传递数据三大过程,笔者统计了下这三大步骤中的等待时间最小值和最大值,其中最小值为40us,最大值为15ms,故笔者采取了将50MHZ的时钟分频为10KHZ,即时钟周期为100us的方法来简化设计。

在Spartan-3E的用户手册上详细讲解了如何对此液晶进行操作,笔者做了简单的摘要:
一) 上电初始化(目的是建立宽度为4 bit的数据接口)
1) 等待15ms或者更长时间
2) 写命令字0x3,保持LCD_E高电平12个周期(时钟频率为50MHZ时)
3) 等待4.1ms或者更长时间
4) 写命令字0x3,保持LCD_E高电平12个周期
5) 等待100us或者更长时间
6) 写命令字0x3,保持LCD_E高电平12个周期
7) 等待40us或者更长时间
8) 写命令字0x2,保持LCD_E高电平12个周期
9) 等待40us或者更长时间

二) 写命令
1) 发送功能设置命令(Function Set),0x28
2) 发送端口模式设置命令(Entry Mode Set),0x06,自动增加地址指针
3) 发送Display ON/OFF命令,0x0C,打开显示开关并禁止光标闪烁
4) 发送Clear Display命令,等待1.64ms或者更长时间

三) 设置读写地址和传递数据
指定起始地址,并给出一个或者多个数据,这一步是显示的关键,必须仔细设置控制位,笔者就是因为这个错误,白白花费了大半天的时间,具体方法是在写任何数据之前,发送Set DD RAM Address 命令,(写入7位的DD RAM地址,注意最高位为1)然后再写入数据。

简单介绍我所设计的LCD液晶IP核的思路,首先生成100us的时钟,然后根据初始化顺序,编写状态机。最终设计效果是在1602液晶屏上可以静态显示16*2的任意字符串—而这只需修改两个参数即可轻松实现。下面是部分代码展示。下图为代码说明。

图1所示为写16个字符的代码实现,图2所示为将普通的字符串转换为1602可显示的编码值的模块,图3所示为生成clk_100us的代码,

图1所示为写16个字符的代码实现,图2所示为将普通的字符串转换为1602可显示的编码值的模块,图3所示为生成clk_100us的代码,

代码展示

最终效果图是在屏幕上显示两行字符串:

最终效果图是在屏幕上显示两行字符串



参考代码:
module lcd1602(clk,rst,LCD_E,LCD_RW,LCD_RS,LCD_D); 
 input clk,rst; 
 output LCD_E,LCD_RW,LCD_RS; 
 output [7:0] LCD_D;  
reg LCD_E,LCD_RW,LCD_RS; 
 reg [7:0] LCD_D; 
   reg [9:0] state;  
reg [5:0] address;     
 parameter IDLE  =10'b0000000000;  
parameter CLEAR  =10'b0000000001;  //清屏    
parameter RETURNCURSOR =10'b0000000010; //归home位   
 parameter SETMODE =10'b0000000111;    //输入方式设置,读写数据后ram地址增/减1;画面动/不动   
 parameter SWITCHMODE =10'b0000001111;   //显示状态设置,显示开/关;光标开/关;闪烁开/关    
parameter SHIFT  =10'b0000011100;    //光标画面滚动 画面/光标平移一位;左/右平移一位   
 parameter SETFUNCTION =10'b0000111100;  
 //工作方式设置 1:8/1:4位数据接口;两行/一行显示;5x10/5x7点阵   
 parameter SETCGRAM =10'b0001000000;  //设置CGRAM  
parameter SETDDRAM1 =10'b0010000001;  //设置DDRAM  
parameter SETDDRAM2 =10'b0010000010;  //设置DDRAM  
parameter READFLAG =10'b0100000000;  //读状态  
parameter WRITERAM1 =10'b1000000001;  //写RAM  
parameter WRITERAM2 =10'b1000000010;  //写RAM  
parameter READRAM =10'b1100000000;  //读RAM 








          








    void function(e,t){for(var n=t.getElementsByTagName("img"),a=+new Date,i=[],o=function(){this.removeEventListener&&this.removeEventListener("load",o,!1),i.push({img:this,time:+new Date})},s=0;s< n.length;s++)!function(){var e=n[s];e.addEventListener?!e.complete&&e.addEventListener("load",o,!1):e.attachEvent&&e.attachEvent("onreadystatechange",function(){"complete"==e.readyState&&o.call(e,o)})}();alog("speed.set",{fsItems:i,fs:a})}(window,document);








  parameter cur_inc       =1;  parameter cur_dec       =0;  parameter cur_shift     =1;  parameter cur_noshift   =0;  parameter open_display  =1;  parameter open_cur      =0;  parameter blank_cur     =0;  parameter shift_display =1;  parameter shift_cur     =0;  parameter right_shift   =1;  parameter left_shift    =0;  parameter LCD_Dwidth8    =1;  parameter LCD_Dwidth4    =0;  parameter twoline       =1;  parameter oneline       =0;  parameter font5x10      =1;  parameter font5x7       =0;  
/******************************************************************/  function [7:0] ddram;                 //写入需要的字符数据   input [5:0] n;   begin    case(n)    0:ddram=8'h48;//H    1:ddram=8'h65;//e    2:ddram=8'h6c;//l    3:ddram=8'h6c;//l    4:ddram=8'h6f;//o    5:ddram=8'h21;//!    6:ddram=8'h21;//!    7:ddram=8'hA0;//space    8:ddram=8'h7E;//->    9:ddram=8'hA0;//space    10:ddram=8'h5A;//Z    11:ddram=8'h52;//R    12:ddram=8'h74;//t    13:ddram=8'h65;//e    14:ddram=8'h63;//c    15:ddram=8'h68;//h    16:ddram=8'h77;//w    17:ddram=8'h77;//w    18:ddram=8'h77;//w  
  19:ddram=8'h2E;//. 








 var cpro_psid ="u2572954"; var cpro_pswidth =966; var cpro_psheight =120;














   20:ddram=8'h5A;//Z    21:ddram=8'h52;//R    22:ddram=8'hB0;//R    23:ddram=8'h74;//t    24:ddram=8'h65;//e    25:ddram=8'h63;//c    26:ddram=8'h68;//h    27:ddram=8'h2E;//.    28:ddram=8'h6E;//n    29:ddram=8'h65;//e    30:ddram=8'h74;//t    31:ddram=8'hA0;//space    default:  ddram=8'hxx;    endcase   end  endfunction 
/******************************************************************/ //分频模块  reg [16:0] clkcnt;  reg clkdiv;   always @ (posedge clk)  if(!rst)  clkcnt<=17'b0_0000_0000_0000_0000;  else  begin   if(clkcnt<17'b0_1001_1100_0100_0000) //16'b1001_1100_0100_0000    begin    clkcnt<=clkcnt+1;       clkdiv<=0;     end   else if(clkcnt==17'b1_0011_1000_0111_1111)       clkcnt<=17'b0_0000_0000_0000_0000;   else      begin    clkcnt<=clkcnt+1;     clkdiv<=1;     end  end 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值