LCD1602无法显示

2019-07-16 00:42发布

不知道为什么我的LCD1602没有任何显示
有没有高人能帮我指点一二
代码如下/*************************************************  
//Module:       lcd1602  
//File Name:    lcd1602.v  
//Version:      2.0  
//Date:         2011.12.14   
//Author:       wang li  
//Code Type:    RTL  
//Description:  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 分
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。