不知道为什么我的LCD1602没有任何显示
有没有高人能帮我指点一二
代码如下/*************************************************
//Module: lcd1602
//File Name: lcd1602.v
//Version: 2.0
//Date: 2011.12.14
//Author: wang li
//Code Type: RTL
//Descrip
tion: LCD1602液晶显示
// clk——时钟输入(1位)
// rst——复位信号输入(1位)
// 输入看模块
**************************************************/
module lcd1602(clk,rst,LCD_RS,LCD_RW,LCD_E,LCD_DATA);
input clk; //时钟信号,50MHZ
input rst; //复位信号,低电平进行复位
output LCD_RS; //1602数据——H/命令——L 选择端
output LCD_RW; //1602写——L/读——H 选择端
output LCD_E; //1602使能引脚,1时读取信息,1->0(下降沿)执行命令
output [7:0] LCD_DATA; //1602数据传输端口
wire LCD_E;
reg [8:0] count;
reg clk_div1; //500个clk的周期,20ns*500=10us
reg clk_div2; //1000个,20us
reg [7:0] count1; //250个clk_div2的周期,20us*250=5000u=5ms
reg clk_buf;
//******************
//-----分频模块-----
//******************
always @(posedge clk or negedge rst)
begin
if(!rst) //rst=0
count<=0;
else
begin
if(count<250) //2500
begin
clk_div1<=0;
count<=count+1'b1;
end
else if(count>=500-1) //5000
count<=0;
else
begin
clk_div1<=1;
count<=count+1'b1;
end
end
end
always @(posedge clk_div1 or negedge rst)
begin
if(!rst)
clk_div2<=0;
else
clk_div2<=~clk_div2;
end
always @(posedge clk_div2 or negedge rst)
begin
if(!rst) //rst=0
begin
count1<=0;
clk_buf<=0; //
end
else
begin
if(count1<125) //2500
begin
clk_buf<=0;
count1<=count1+1'b1;
end
else if(count1>=250-1) //5000
count1<=0;
else
begin
clk_buf<=1;
count1<=count1+1'b1;
end
end
end
assign LCD_E=~clk_buf;
//**********************
//-----显示控制模块-----
//**********************
reg [4:0] state; //当前状态寄存器 ,10个状态
reg [5:0] address; //地址的位置,0~31,
reg [7:0] LCD_DATA;
reg LCD_RW,LCD_RS;
parameter
IDLE = 4'd0, //空闲
CLEAR = 4'd1, //清屏
SET_FUNCTION = 4'd2, //工作方式设置指令
SWITCH_MODE = 4'd3, //开关控制指令
SET_MODE = 4'd4, //输入方式设置
SET_DDRAM1 = 4'd5, //设定第一行DDRAM地址指令
WRITE_RAM1 = 4'd6, //向第一行写入的数码
SET_DDRAM2 = 4'd7, //设定第2行DDRAM地址指令
WRITE_RAM2 = 4'd8, //向第2行写入的数码
SHIFT = 4'd9, //设定显示屏或光标移动方向指令
STOP = 4'd10;
reg [7:0] Data_First [15:0];
reg [7:0] Data_Second [15:0];
initial
begin
Data_First[0] = "H";
Data_First[1] = "e";
Data_First[2] = "l";
Data_First[3] = "l";
Data_First[4] = "o";
Data_First[5] = "!";
Data_First[6] = " ";
Data_First[7] = "-";
Data_First[8] = ">";
Data_First[9] = " ";
Data_First[10]= "Z";
Data_First[11]= "R";
Data_First[12]= "t";
Data_First[13]= "e";
Data_First[14]= "c";
Data_First[15]= "h";
Data_Second[0] = "w";
Data_Second[1] = "w";
Data_Second[2] = "w";
Data_Second[3] = ".";
Data_Second[4] = "Z";
Data_Second[5] = "R";
Data_Second[6] = "-";
Data_Second[7] = "t";
Data_Second[8] = "e";
Data_Second[9] = "c";
Data_Second[10]= "h";
Data_Second[11]= ".";
Data_Second[12]= "n";
Data_Second[13]= " ";
Data_Second[14]= " ";
Data_Second[15]= " ";
end
//-----状态控制-----
always @(posedge clk_buf or negedge rst) // clk_div1 clk_buf
begin
if(!rst)
begin
state<=IDLE;
address<=6'd0;
LCD_DATA<=8'b0000_0000;
LCD_RS<=0;
LCD_RW<=0;
end
else
begin
case(state)
IDLE: //空闲状态
begin
LCD_DATA<=8'bzzzz_zzzz; //8'bzzzz_zzzz
state<=CLEAR;
end
CLEAR: //清屏指令 4'd1 0X01
begin
LCD_RS<=0;
LCD_RW<=0;
LCD_DATA<=8'b0000_0001; //指令
state<=SET_FUNCTION;
end
SET_FUNCTION: //工作方式设置 4'd2 0X38
begin
LCD_RS<=0;
LCD_RW<=0;
LCD_DATA<=8'b0011_1000; //38h
//第4位DL:0=数据总线为4位;1=数据总线为8位★★★
//第3位N:0=显示1行;1=显示2行★★★
//第2位F:0=5×7点阵/每字符;1=5×10点阵/每字符★★★
state<=SWITCH_MODE;
end
SWITCH_MODE: //显示开关控制指令 4'd3 0X08
begin
LCD_RS<=0;
LCD_RW<=0;
LCD_DATA<=8'b0000_1000; //08h
//第2位D:0=显示功能关;1=显示功能开★★★
//第1位C:0=无光标;1=有光标★★★
//第0位B:1=光标闪烁; 0=光标不闪烁★★★
state<=SET_MODE;
end
SET_MODE: //设定显示屏或光标移动方向指令 4'd4 0X06
begin
LCD_RS<=0;
LCD_RW<=0;
LCD_DATA<=8'b0000_0110; //06h
//第1位N:0=读或者写一个字符后,地址指针-1,光标-1
// 1=读或者写一个字符后,地址指针+1,光标+1★★★
//第0位S:0=当写一个字符,整屏显示不移动★★★
// 1=当写一个字符,整屏显示左移(N=1)或者右移(N=0),以得到光标不移动而屏幕移动的效果
state<=SHIFT;
end
SHIFT: //设定显示屏或光标移动方向指令 4'd9 0X0C
begin
LCD_RS<=0;
LCD_RW<=0;
LCD_DATA<=8'b0000_1100;
//第3位S/C;第2位R/L
// S/C R/L 设定情况
// 0 0 光标左移1格,且地址指针值减1
// 0 1 光标右移1格,且地址指针值加1 ★★★
// 1 0 显示器上字符全部左移一格,但光标不动
// 1 1 显示器上字符全部右移一格,但光标不动
state<=SET_DDRAM1;
end
SET_DDRAM1: //设定第一行DDRAM地址指令 4'd5 0X80+Adress
begin
LCD_RS<=0;
LCD_RW<=0;
//-----写入第一行显示起始地址:-----
// 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 第一行
LCD_DATA<=8'h80+8'd1; //第一行第1个位置
address<=6'd0;
state<=WRITE_RAM1;
// Data_First_Buf<=Data_First;
end
WRITE_RAM1: //向第一行写入的数码 4'd6 Data_First[address]
begin
if(address<=15) //表示写第一行
begin
LCD_RS<=1;
LCD_RW<=0;
LCD_DATA<=Data_First[address];
// Data_First_Buf<=(Data_First_Buf<<8); //左移
address<=address+1'b1;
state<=WRITE_RAM1;
end
else
begin
LCD_RS<=0;
LCD_RW<=0;
LCD_DATA<=8'h80+address;
state<=SET_DDRAM2;
end
end
SET_DDRAM2: //设定第2行DDRAM地址指令 4'd7 0XC0+Adress
begin
LCD_RS<=0;
LCD_RW<=0;
//-----写入第2行显示起始地址:-----
// 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 第二行
LCD_DATA<=8'hC0+8'd0; //第2行第1个位置
state<=WRITE_RAM2;
// Data_Second_Buf<=Data_Second;
address<=6'd0;
end
WRITE_RAM2: //向第2行写入的数码 4'd8 Data_First[address]
begin
if(address<=15) //表示写第一行
begin
LCD_RS<=1;
LCD_RW<=0;
LCD_DATA<=Data_Second[address];
// Data_Second_Buf<=(Data_Second_Buf<<8);
address<=address+1'b1;
state<=WRITE_RAM2;
end
else
begin
LCD_RS<=0;
LCD_RW<=0;
LCD_DATA<=8'hC0+address;
state<=STOP;
end
end
STOP: // 4'd10
begin
state<=STOP;
address<=6'd0;
LCD_RW<=1;
end
default:
state<=CLEAR;
endcase
end
end
endmodule
-
-
LCD1602.zip
下载积分: 积分 -1 分
3.37 MB, 下载次数: 19, 下载积分: 积分 -1 分
假如頻率錯誤的話 時序也會抓錯
评分
查看全部评分
一周热门 更多>