非常详细的verilog写的LCD1602驱动

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

最近在网上找了很多用verilog驱动LCD1602的程序,但基本没有一个是完美运行,很多论坛所谓大神的代码综合时候一样很多缺陷,要知道每一个warning都有可能是导致最终失败的原因。于是乎只能自己下功夫,找到一个稍微靠谱的开发板配套例程,但是分频器模块编的叫一塌糊涂,主时钟分频后继续分频而且组合时序乱用,通过分频模块重新编写后基本无warning完美运行,仿真功能实现并且下载显示成功,后面附上了我的testbench,本人用的软件为ISE12.2,不过个人感觉quartus应该一样跑,下面是代码,需要在1602显示什么字符自己改显示函数就行,希望对大家有帮助。

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'b010*******;//读状态

parameter WRITERAM1=10'b1000000001;//写RAM

parameter WRITERAM2=10'b1000000010;//写RAM

parameter READRAM=10'b1100000000;//读RAM

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;//.

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

相关文档
最新文档