先上原理图:
file:///d:/program files (x86)/360/roaming/360se6/User Data/temp/103700elfa7c7qxlf8qdew.jpg
我要在LCD上显示"OK!"字符,其中用到的复位按键reset是普通独立按键,内部下拉,高电平复位(按键按下时接的是VCC)。
出现了这样的问题:当按下reset复位按键时led会发光,LCD能显示字符,当按键松开时,灯灭,LCD不显示。
我想做到的是按下reset后,led亮,lcd不显示,松开后led灭,lcd显示。用ISim功能仿真是对的。
不知道哪儿出问题了,求各路大神指导一下!!!
代码如下:(代码可能有点长,主要看两个always语句就可以了,有些是LCD的初始化过程)
module lcd_disp(clk,reset,lcd_rs,
lcd_rw,lcd_e,lcd_d_w,flash_ce,led
);
input clk;//50MHz
input reset;
output led;//reset指示灯
output lcd_rs; //0--写指令,1--写数据
output lcd_rw; //读写数据,0--写
output lcd_e; //lcd使能 1--有效
output [3:0]lcd_d_w; //数据总线
output flash_ce; //D3-D0与flash复用,flash_ce = 1,不允许flash工作
assign flash_ce = 1;
reg lcd_rs,lcd_e;
reg led_r = 1'b0;
reg [3:0]lcd_d;
assign lcd_rw = 0; //严格按照时序操作,故不需要读忙信号,设置为只向LCD1602写数据
reg [19:0]delay_count; //延时控制计数器
reg [19:0]num_count;
parameter state1 = 6'b000_001;
parameter state2 = 6'b000_010;
parameter state3 = 6'b000_011;
parameter state4 = 6'b000_100;
parameter state5 = 6'b000_101;
parameter state6 = 6'b000_110;
parameter state7 = 6'b000_111;
parameter state8 = 6'b001_000;
parameter state9 = 6'b001_001;
parameter state10 = 6'b001_010;
parameter state11 = 6'b001_011;
parameter state12 = 6'b001_100;
parameter state13 = 6'b001_101;
parameter state14 = 6'b001_110;
parameter state15 = 6'b001_111;
parameter state16 = 6'b010_000;
parameter state17 = 6'b010_001;
parameter state18 = 6'b010_010;
parameter state19 = 6'b010_011;
parameter state20 = 6'b010_100;
parameter state21 = 6'b010_101;
parameter state22 = 6'b010_110;
parameter state23 = 6'b010_111;
parameter state24 = 6'b011_000;
parameter state25 = 6'b011_001;
parameter state26 = 6'b011_010;
parameter state27 = 6'b011_011;
parameter state28 = 6'b011_100;
parameter state29 = 6'b011_101;
parameter state30 = 6'b011_110;
parameter state31 = 6'b011_111;
parameter state32 = 6'b100_000;
parameter state33 = 6'b100_001;
parameter state34 = 6'b100_010;
parameter state35 = 6'b100_011;
parameter state36 = 6'b100_100;
parameter state37 = 6'b100_101;
parameter state38 = 6'b100_110;
parameter state39 = 6'b100_111;
parameter state40 = 6'b101_000;
parameter state41 = 6'b101_001;
parameter state42 = 6'b101_010;
parameter state43 = 6'b101_011;
parameter state44 = 6'b101_100;
parameter state45 = 6'b101_101;
parameter state46 = 6'b101_110;
parameter state47 = 6'b101_111;
parameter state48 = 6'b110_000;
parameter state49 = 6'b110_001;
parameter state50 = 6'b110_010;
parameter state51 = 6'b110_011;
parameter state52 = 6'b110_100;
parameter state53 = 6'b110_101;
reg [5:0]state; //状态标志信号
reg state_change; //状态改变信号
//============状态标识===========
always@(posedge clk or posedge reset)begin
if(reset)begin
state_change <= 1'b0;
delay_count <= 1'b1; //??
led_r <= 1'b1;
end
else if(delay_count == num_count - 1)begin
state_change <= 1'b1;
delay_count <= 1'b1;
end
else begin
led_r <= 1'b0;
state_change <= 1'b0;
delay_count <= delay_count + 1'b1;
end
end
//============状态切换============
always@(posedge state_change or posedge reset)begin
if(reset)begin /*LCD初始化过程*/
state <= state1;
num_count <= 20'd750_000; //延时15ms
end
else case(state)
/* state1~state3完成第一次控制指令写入,需要3次这样的控制指令写入才能写显示设置指令 */
state1:begin
state <= state2;
num_count <= 20'd4; //lcd_rs写有效要超前lcd_e使能信号40ns
lcd_rs <= 1'b0;
lcd_e <= 1'b0;//未使能
lcd_d <= 4'h3; //正常情况D7~D0应写0x38,但Spartan3E Kit Board上只用了D7~D4,故只写高位即可
end
state2:begin
state <= state3;
num_count <= 20'd12; //保持使能信号lcd_e为高电平时间大于等于230ns,此处取240ns
lcd_e <= 1'b1; //lcd_e使能信号有效
end
state3:begin
state <= state4;
num_count <= 20'd5000; //完成本次指令传输,lcd_e无效后,延时等待100us,lcd_d上数据才能改变
lcd_e <= 1'b0;
end
/* 第二次写指令 */
state4:begin
state <= state5;
num_count <= 20'd4; //lcd_rs写有效要超前lcd_e使能信号40ns
lcd_rs <= 1'b0;
lcd_e <= 1'b0;//未使能
lcd_d <= 4'h3; //正常情况D7~D0应写0x38,但Spartan3E Kit Board上只用了D7~D4,故只写高位即可
end
state5:begin
state <= state6;
num_count <= 20'd12; //保持使能信号lcd_e为高电平时间大于等于230ns,此处取240ns
lcd_e <= 1'b1; //lcd_e使能信号有效
end
state6:begin
state <= state7;
num_count <= 20'd5000; //完成本次指令传输,lcd_e无效后,延时等待100us,lcd_d上数据才能改变
lcd_e <= 1'b0;
end
state7:begin
state <= state8;
num_count <= 20'd4;
lcd_d <= 4'd2;
end
state8:begin
state <= state9;
num_count <= 20'd12;
lcd_e <= 1'b1;
end
state9:begin
state <= state10;
num_count <= 20'd5000;
lcd_e <= 1'd0;
end
//写传送功能设置命令控制字0x28(???),采用4位数据总线DB7~DB4,分两次传送
state10:begin
state <= state11;
num_count <= 20'd4; //40ns
lcd_rs <= 20'd0;
lcd_d <=4'h2; //先传高位 2H:0010B
end
state11:begin
state <= state12;
num_count <= 20'd12;
lcd_e <= 1'b1;
end
state12:begin
state <= state13;
num_count <= 20'd80;//两个4位数据之间的时间间隔大于1us --- 1.6us
lcd_e <= 1'd0;
end
state13:begin
state <= state14;
num_count <= 20'd4;
lcd_d <= 4'h8; //再传低位 8H:1000B
end
state14:begin
state <= state15;
num_count <= 20'd12;
lcd_e <= 1'b1;
end
state15:begin
state <= state16;
num_count <= 20'd5000;
lcd_e <= 1'b0;
end
//写入模式控制字0x06 也是分两次传送
state16:begin
state <= state17;
num_count <= 20'd4;
lcd_d <= 4'h0; // 0H:0000B
end
state17:begin
state <= state18;
num_count <= 20'd12;
lcd_e <= 1'b1;
end
state18:begin
state <= state19;
num_count <= 20'd80; // 1us
lcd_e <= 1'b0;
end
state19:begin
state <= state20;
num_count <= 20'd4;
lcd_d <= 4'h6; // 6H:0110B
end
state20:begin
state <= state21;
num_count <= 20'd12;
lcd_e <= 1'b1;
end
state21:begin
state <= state22;
num_count <= 20'd5000; //100us
lcd_e <= 1'b0;
end
//输入打开显示控制字0x0C
state22:begin
state <= state23;
num_count <= 20'd4;
lcd_d <= 4'h0; // 0H:0000B
end
state23:begin
state <= state24;
num_count <= 20'd12;
lcd_e <= 1'b1;
end
state24:begin
state <= state25;
num_count <= 20'd80; // 1us
lcd_e <= 1'b0;
end
state25:begin
state <= state26;
num_count <= 20'd4;
lcd_d <= 4'hC; // CH:1100B
end
state26:begin
state <= state27;
num_count <= 20'd12;
lcd_e <= 1'b1;
end
state27:begin
state <= state28;
num_count <= 20'd5000; //100us
lcd_e <= 1'b0;
end
state28:begin
state <= state29;
num_count <= 20'd10_000; //完成初始化、显示功能配置后延时2ms,等待写入显示字符
end
//写入DDRAM地址,确定显示位置 0x80(第一行),第二行(0x80+0x40)
state29:begin
state <= state30;
num_count <= 20'd4;
lcd_rs <= 1'b0;
lcd_e <= 1'b0;
lcd_d <= 4'h8; //8H:1000B
end
state30:begin
state <= state31;
num_count <= 20'd12;
lcd_e <= 1'b1;
end
state31:begin
state <= state32;
num_count <= 20'd80;
lcd_e <= 1'b0;
end
state32:begin
state <= state33;
num_count <= 20'd4;
lcd_d <= 4'h0; //0H:0000B
end
state33:begin
state <= state34;
num_count <= 20'd12;
lcd_e <= 1'b1;
end
state34:begin
state <= state35;
num_count <= 20'd5000;
lcd_e <= 1'b0;
end
//写入要显示的字符,字符编码参考数据手册 O--0x4F
&nb
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
一周热门 更多>