4条数据总线驱动LCD1602问题探讨

2019-07-15 23:32发布

先上原理图:
            file:///d:/program files (x86)/360/roaming/360se6/User Data/temp/103700elfa7c7qxlf8qdew.jpg 360截图20150908103659047.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
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。