LCD1602

      今天搞定了LCD1602,在LCD1602上实现了用上下两行(共6个字符)显示汉字“程”。

  先初始化(包括功能设定指令、显示开关控制设置、清屏、进入模式设置指令、光标设置等);设定CGRAM,写自定义数据(需要显示多个自定义字符可以循环‘设定CGRAM,写自定义数据’)(注意要写入的地址以及行号);设定DDRAM,向显示屏写数据;

/*在CGRAM的00地址存入自定义汉字‘程’并显示
*/

module LCD(clk,rst,LCD_E,LCD_RW,LCD_RS,LCD);
    input clk,rst;
    output LCD_E,LCD_RW,LCD_RS;
    output [7:0] LCD;
    reg LCD_E,LCD_RW,LCD_RS;
    reg [7:0] LCD;
    
    reg [10:0] state;
    reg flag;
    reg [5:0] address;
    
    
    parameter IDLE        =11'b00000000000;
    parameter CLEAR        =11'b00000000001;        //清屏
    
    parameter RETURNCURSOR    =11'b00000000010;    //归home位
    
    parameter SETMODE    =11'b00000000100;        
    //输入方式设置,读写数据后ram地址增/减1;画面动/不动
    
    parameter SWITCHMODE    =11'b00000001000;    
    //显示状态设置,显示开/关;光标开/关;闪烁开/关
    
    parameter SHIFT        =11'b00000010000;        
    //光标画面滚动 画面/光标平移一位;左/右平移一位
    
    parameter SETFUNCTION    =11'b00000100000;    
    //工作方式设置 1:8/1:4位数据接口;两行/一行显示;5x10/5x7点阵
    
    parameter SETCGRAM    =11'b00001000000;        //设置CGRAM
    parameter SETDDRAM    =11'b00011000000;        //设置DDRAM
    parameter READFLAG    =11'b00100000000;        //
    parameter WRITERAM    =11'b01000000000;        //写RAM
    parameter READRAM        =11'b10000000000;        //读RAM
    
    parameter DATACGRAM    =11'b10000000111;        //写CGRAM
    parameter SETCGRAM1    =11'b00001000001;
    parameter SETCGRAM2    =11'b00001000010;
    parameter SETCGRAM3    =11'b00001000011;
    parameter SETCGRAM4    =11'b00001000100;
    parameter SETCGRAM5    =11'b00001000101;
    parameter SETCGRAM6    =11'b00001000110;
    parameter DATACGRAM1    =11'b10000001111;
    parameter DATACGRAM2    =11'b10000010111;
    parameter DATACGRAM3    =11'b10000011111;
    parameter DATACGRAM4    =11'b10000100111;
    parameter DATACGRAM5    =11'b10000101111;
    parameter DATACGRAM6    =11'b10000110111;
    
    parameter SETDDRAM1    =11'b00011000001;
    parameter WRITERAM1    =11'b01000000001;

    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 LCDwidth8       =1;
    parameter LCDwidth4       =0;
    parameter twoline          =1;
    parameter oneline          =0;
    parameter font5x10         =1;
    parameter font5x7          =0;

    
    //显示数据
    function [7:0] ddram;
        input [5:0] n;
        begin
            case(n)
            6'b001_000:ddram=8'b0000_0000;
            6'b001_001:ddram=8'b0000_0001;
            6'b001_010:ddram=8'b0000_0010;
            6'b001_011:ddram=8'b0000_0011;
            6'b001_100:ddram=8'b0000_0100;
            6'b001_101:ddram=8'b0000_0101;
            default:ddram=8'b0010_0000;
            endcase
        end
    endfunction
    

//自定义字符
    function [4:0] cgram1;
        input [3:0] n1;
        begin
            case(n1)
            4'd0:cgram1=5'b00001;
            4'd1:cgram1=5'b01110;
            4'd2:cgram1=5'b00010;
            4'd3:cgram1=5'b00010;
            4'd4:cgram1=5'b11111;
            4'd5:cgram1=5'b00010;
            4'd6:cgram1=5'b00110;
            4'd7:cgram1=5'b00111;
            default: ;
            endcase
        end
    endfunction


//自定义字符
    function [4:0] cgram2;
        input [3:0] n1;
        begin
            case(n1)
            4'd0:cgram2=5'b10111;//8'b0100_1001;//I
            4'd1:cgram2=5'b00100;//8'b0100_1100;//L
            4'd2:cgram2=5'b00100;//8'b0100_1111;//O
            4'd3:cgram2=5'b00100;//8'b0101_0110;//V
            4'd4:cgram2=5'b10100;//8'b0100_0101;//E
            4'd5:cgram2=5'b00111;//8'b0100_0100;//D
            4'd6:cgram2=5'b00000;//8'b0101_1001;//Y
            4'd7:cgram2=5'b01111;
            default: ;
            endcase
        end
    endfunction

//自定义字符
    function [4:0] cgram3;
        input [3:0] n1;
        begin
            case(n1)
            4'd0:cgram3=5'b11100;//8'b0100_1001;//I
            4'd1:cgram3=5'b00100;//8'b0100_1100;//L
            4'd2:cgram3=5'b00100;//8'b0100_1111;//O
            4'd3:cgram3=5'b00100;//8'b0101_0110;//V
            4'd4:cgram3=5'b00100;//8'b0100_0101;//E
            4'd5:cgram3=5'b11100;//8'b0100_0100;//D
            4'd6:cgram3=5'b00000;//8'b0101_1001;//Y
            4'd7:cgram3=5'b11110;
            default: ;
            endcase
        end
    endfunction    
    reg [15:0] clkcnt;
    
    
    //自定义字符
    function [4:0] cgram4;
        input [3:0] n1;
        begin
            case(n1)
            4'd0:cgram4=5'b01010;//8'b0100_1001;//I
            4'd1:cgram4=5'b01010;//8'b0100_1100;//L
            4'd2:cgram4=5'b10010;//8'b0100_1111;//O
            4'd3:cgram4=5'b00010;//8'b0101_0110;//V
            4'd4:cgram4=5'b00010;//8'b0100_0101;//E
            4'd5:cgram4=5'b00010;//8'b0100_0100;//D
            4'd6:cgram4=5'b00010;//8'b0101_1001;//Y
            4'd7:cgram4=5'b00010;
            default: ;
            endcase
        end
    endfunction
    
    
    //自定义字符
    function [4:0] cgram5;
        input [3:0] n1;
        begin
            case(n1)
            4'd0:cgram5=5'b10001;//8'b0100_1001;//I
            4'd1:cgram5=5'b00001;//8'b0100_1100;//L
            4'd2:cgram5=5'b01111;//8'b0100_1111;//O
            4'd3:cgram5=5'b00001;//8'b0101_0110;//V
            4'd4:cgram5=5'b00001;//8'b0100_0101;//E
            4'd5:cgram5=5'b00001;//8'b0100_0100;//D
            4'd6:cgram5=5'b11111;//8'b0101_1001;//Y
            4'd7:cgram5=5'b00000;
            default: ;
            endcase
        end
    endfunction
    
    
//自定义字符
    function [4:0] cgram6;
        input [3:0] n1;
        begin
            case(n1)
            4'd0:cgram6=5'b00000;//8'b0100_1001;//I
            4'd1:cgram6=5'b00000;//8'b0100_1100;//L
            4'd2:cgram6=5'b11110;//8'b0100_1111;//O
            4'd3:cgram6=5'b00000;//8'b0101_0110;//V
            4'd4:cgram6=5'b00000;//8'b0100_0101;//E
            4'd5:cgram6=5'b00000;//8'b0100_0100;//D
            4'd6:cgram6=5'b11111;//8'b0101_1001;//Y
            4'd7:cgram6=5'b00000;
            default: ;
            endcase
        end
    endfunction
    
    
    always @ (posedge clk)
    if(!rst)
    clkcnt<=16'b0000_0000_0000_0000;
    else
    begin
        if(clkcnt==16'b1001_1100_0100_0000)
            clkcnt<=16'b0000_0000_0000_0000;
        else 
            clkcnt<=clkcnt+1;
    end
    
    wire tc_clkcnt;
    assign tc_clkcnt=(clkcnt==16'b1001_1100_0100_0000)?1:0;
    
    reg clkdiv;
    always @ (posedge tc_clkcnt)
    if(!rst)
        clkdiv<=0;
    else
        clkdiv<=~clkdiv;
    
    reg clk_int;
    always @ (posedge clkdiv)
    if(rst==0)
        clk_int<=0;
    else
        clk_int<=~clk_int;
        
    always @ (negedge clkdiv)
    if(rst==0)
        LCD_E<=0;
    else
        LCD_E<=~LCD_E;
        
        
reg [3:0]cnt,cnt1,cnt2,cnt3,cnt4,cnt5,cnt6;
        
    always @ (posedge clk_int or negedge rst)
        if(!rst)
        begin
            state<=IDLE;
            address<=6'b001_000;
            flag<=0;
            cnt<=0;
            cnt1<=0;
            cnt2<=0;
            cnt3<=0;
            cnt4<=0;
            cnt5<=0;
            cnt6<=0;
        end
        else
        begin
            case(state)
            IDLE        :begin 
                            LCD<=8'bzzzz_zzzz;
                            if(flag==0)
                            begin
                                state<=SETFUNCTION;
                                flag<=1;
                            end
                            else
                                state<=SHIFT;
                         end
            CLEAR            :begin LCD_RS<=0;LCD_RW<=0;LCD<=8'b0000_0001;
                                    state<=SETMODE;end   
            SETMODE            :begin LCD_RS<=0;LCD_RW<=0;LCD[7:2]<=6'b000001;LCD[1]<=cur_inc;LCD[0]<=cur_noshift;
                                    state<=SETCGRAM1/*WRITERAM*/;end
            RETURNCURSOR    :begin LCD_RS<=0;LCD_RW<=0;LCD<=8'b00000010;
                                    state<=WRITERAM;end
            SWITCHMODE         :begin LCD_RS<=0;LCD_RW<=0;LCD[7:3]<=5'b00001;LCD[2]<=open_display;LCD[1]<=open_cur;LCD[0]<=blank_cur;
                                state<=CLEAR;end
            SHIFT            :begin LCD_RS<=0;LCD_RW<=0;LCD[7:4]<=4'b0001;LCD[3]<=shift_cur;LCD[2]<=left_shift;LCD[1:0]<=2'b00;
                                state<=IDLE;end
            SETFUNCTION        :begin LCD_RS<=0;LCD_RW<=0;LCD[7:5]<=3'b001;LCD[4]<=LCDwidth8;LCD[3]<=twoline;LCD[2]<=font5x10;LCD[1:0]<=2'b00;
                                state<=SWITCHMODE;end
            SETCGRAM1        :begin if(cnt1<=4'd7) begin LCD_RS<=0;LCD_RW<=0;LCD[7:3]<=5'b01000;LCD[2:0]<=cnt1;state<=DATACGRAM1/*IDLE*/;end //行号设置
                                     else begin state<=SETCGRAM2;cnt1<=0;end
                             end
            DATACGRAM1    :begin LCD_RS<=1;LCD_RW<=0;LCD[7:5]<=3'b000;LCD[4:0]<=cgram1(cnt1);cnt1<=cnt1+1;state<=SETCGRAM1; end//循环写入8行数据(5*8)
            SETCGRAM2        :begin if(cnt2<=4'd7) begin LCD_RS<=0;LCD_RW<=0;LCD[7:3]<=5'b01001;LCD[2:0]<=cnt2;state<=DATACGRAM2/*IDLE*/;end //行号设置
                                     else begin state<=SETCGRAM3;cnt2<=0;end
                             end
            DATACGRAM2    :begin LCD_RS<=1;LCD_RW<=0;LCD[7:5]<=3'b000;LCD[4:0]<=cgram2(cnt2);cnt2<=cnt2+1;state<=SETCGRAM2; end//循环写入8行数据(5*8)
            SETCGRAM3        :begin if(cnt3<=4'd7) begin LCD_RS<=0;LCD_RW<=0;LCD[7:3]<=5'b01010;LCD[2:0]<=cnt3;state<=DATACGRAM3/*IDLE*/;end //行号设置
                                     else begin state<=SETCGRAM4;cnt3<=0;end
                             end
            DATACGRAM3    :begin LCD_RS<=1;LCD_RW<=0;LCD[7:5]<=3'b000;LCD[4:0]<=cgram3(cnt3);cnt3<=cnt3+1;state<=SETCGRAM3; end//循环写入8行数据(5*8)
            SETCGRAM4        :begin if(cnt4<=4'd7) begin LCD_RS<=0;LCD_RW<=0;LCD[7:3]<=5'b01011;LCD[2:0]<=cnt4;state<=DATACGRAM4/*IDLE*/;end //行号设置
                                     else begin state<=SETCGRAM5;cnt4<=0;end
                             end
            DATACGRAM4    :begin LCD_RS<=1;LCD_RW<=0;LCD[7:5]<=3'b000;LCD[4:0]<=cgram4(cnt4);cnt4<=cnt4+1;state<=SETCGRAM4; end//循环写入8行数据(5*8)
            SETCGRAM5        :begin if(cnt5<=4'd7) begin LCD_RS<=0;LCD_RW<=0;LCD[7:3]<=5'b01100;LCD[2:0]<=cnt5;state<=DATACGRAM5/*IDLE*/;end //行号设置
                                     else begin state<=SETCGRAM6;cnt5<=0;end
                             end
            DATACGRAM5    :begin LCD_RS<=1;LCD_RW<=0;LCD[7:5]<=3'b000;LCD[4:0]<=cgram5(cnt5);cnt5<=cnt5+1;state<=SETCGRAM5; end//循环写入8行数据(5*8)
            SETCGRAM6        :begin if(cnt6<=4'd7) begin LCD_RS<=0;LCD_RW<=0;LCD[7:3]<=5'b01101;LCD[2:0]<=cnt6;state<=DATACGRAM6/*IDLE*/;end //行号设置
                                     else begin state<=SETDDRAM;cnt6<=0;end
                             end
            DATACGRAM6    :begin LCD_RS<=1;LCD_RW<=0;LCD[7:5]<=3'b000;LCD[4:0]<=cgram6(cnt6);cnt6<=cnt6+1;state<=SETCGRAM6; end//循环写入8行数据(5*8)
            SETDDRAM        :begin LCD_RS<=0;LCD_RW<=0;LCD<=8'b10000011;state<=WRITERAM;end
            SETDDRAM1    :begin LCD_RS<=0;LCD_RW<=0;LCD<=8'b11000011;state<=WRITERAM1;end
            WRITERAM        :begin
                            if(address<=6'b001_010)
                            begin
                                LCD_RS<=1;
                                LCD_RW<=0;
                                LCD<=ddram(address);
                                address<=address+1;
                                state<=WRITERAM;
                            end
                            else begin
                                state<=SETDDRAM1;
                                LCD_RS<=0;LCD_RW<=0;
                                end
                            end
            WRITERAM1    :begin
                            if(address<=6'b001_101)
                            begin
                                LCD_RS<=1;
                                LCD_RW<=0;
                                LCD<=ddram(address);
                                address<=address+1;
                                state<=WRITERAM1;
                            end
                            else
                            begin
                                state<=SHIFT;
                                address<=6'b001_000;
                                LCD_RS<=0;LCD_RW<=0;
                            end
                            end
            endcase
        end
endmodule


/*在CGRAM的00地址存入自定义字符并显示
//*/
//
//module LCD(clk,rst,LCD_E,LCD_RW,LCD_RS,LCD);
//    input clk,rst;
//    output LCD_E,LCD_RW,LCD_RS;
//    output [7:0] LCD;
//    reg LCD_E,LCD_RW,LCD_RS;
//    reg [7:0] LCD;
//    
//    reg [10:0] state;
//    reg flag;
//    reg [5:0] address;
//    
//    
//    parameter IDLE        =11'b00000000000;
//    parameter CLEAR        =11'b00000000001;        //清屏
//    
//    parameter RETURNCURSOR    =11'b00000000010;    //归home位
//    
//    parameter SETMODE    =11'b00000000100;        
//    //输入方式设置,读写数据后ram地址增/减1;画面动/不动
//    
//    parameter SWITCHMODE    =11'b00000001000;    
//    //显示状态设置,显示开/关;光标开/关;闪烁开/关
//    
//    parameter SHIFT        =11'b00000010000;        
//    //光标画面滚动 画面/光标平移一位;左/右平移一位
//    
//    parameter SETFUNCTION    =11'b00000100000;    
//    //工作方式设置 1:8/1:4位数据接口;两行/一行显示;5x10/5x7点阵
//    
//    parameter SETCGRAM    =11'b00001000000;        //设置CGRAM
//    parameter SETDDRAM    =11'b00011000000;        //设置DDRAM
//    parameter READFLAG    =11'b00100000000;        //
//    parameter WRITERAM    =11'b01000000000;        //写RAM
//    parameter READRAM        =11'b10000000000;        //读RAM
//    
//    parameter DATACGRAM    =11'b10000000111;        //写CGRAM
//
//    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 LCDwidth8       =1;
//    parameter LCDwidth4       =0;
//    parameter twoline          =1;
//    parameter oneline          =0;
//    parameter font5x10         =1;
//    parameter font5x7          =0;
//
////显示数据
//    function [7:0] ddram;
//        input [5:0] n;
//        begin
//            case(n)
//            6'b001_000:ddram=8'b0000_0000;
//            6'b001_001:ddram=8'b0000_0000;
//            6'b001_010:ddram=8'b0000_0000;
//            6'b001_011:ddram=8'b0000_0000;
//            6'b001_100:ddram=8'b0000_0000;
//            6'b001_101:ddram=8'b0000_0000;
//            6'b001_110:ddram=8'b0000_0000;
//            default:ddram=8'b0010_0001;
//            endcase
//        end
//    endfunction
//    
//    
////自定义字符
//    function [4:0] cgram;
//        input [3:0] n1;
//        begin
//            case(n1)
//            4'd0:cgram=5'b00_000;
//            4'd1:cgram=5'b00_000;
//            4'd2:cgram=5'b00_000;
//            4'd3:cgram=5'b00_000;
//            4'd4:cgram=5'b11_111;
//            4'd5:cgram=5'b11_111;
//            4'd6:cgram=5'b11_111;
//            4'd7:cgram=5'b11_111;
//            default: ;
//            endcase
//        end
//    endfunction
//    
//    reg [15:0] clkcnt;
//    
//    always @ (posedge clk)
//    if(!rst)
//    clkcnt<=16'b0000_0000_0000_0000;
//    else
//    begin
//        if(clkcnt==16'b1001_1100_0100_0000)
//            clkcnt<=16'b0000_0000_0000_0000;
//        else 
//            clkcnt<=clkcnt+1;
//    end
//    
//    wire tc_clkcnt;
//    assign tc_clkcnt=(clkcnt==16'b1001_1100_0100_0000)?1:0;
//    
//    reg clkdiv;
//    always @ (posedge tc_clkcnt)
//    if(!rst)
//        clkdiv<=0;
//    else
//        clkdiv<=~clkdiv;
//    
//    reg clk_int;
//    always @ (posedge clkdiv)
//    if(rst==0)
//        clk_int<=0;
//    else
//        clk_int<=~clk_int;
//        
//    always @ (negedge clkdiv)
//    if(rst==0)
//        LCD_E<=0;
//    else
//        LCD_E<=~LCD_E;
//        
//        
//reg [3:0]cnt;
//        
//    always @ (posedge clk_int or negedge rst)
//        if(!rst)
//        begin
//            state<=IDLE;
//            address<=6'b000_111;
//            flag<=0;
//            cnt<=0;
//        end
//        else
//        begin
//            case(state)
//            IDLE        :begin 
//                            LCD<=8'bzzzz_zzzz;
//                            if(flag==0)
//                            begin
//                                state<=SETFUNCTION;
//                                flag<=1;
//                            end
//                            else
//                                state<=SHIFT;
//                         end
//            CLEAR            :begin LCD_RS<=0;LCD_RW<=0;LCD<=8'b0000_0001;
//                                    state<=SETMODE;end   
//            SETMODE            :begin LCD_RS<=0;LCD_RW<=0;LCD[7:2]<=6'b000001;LCD[1]<=cur_inc;LCD[0]<=cur_noshift;
//                                    state<=SETCGRAM/*WRITERAM*/;end
//            RETURNCURSOR    :begin LCD_RS<=0;LCD_RW<=0;LCD<=8'b00000010;
//                                    state<=WRITERAM;end
//            SWITCHMODE         :begin LCD_RS<=0;LCD_RW<=0;LCD[7:3]<=5'b00001;LCD[2]<=open_display;LCD[1]<=open_cur;LCD[0]<=blank_cur;
//                                state<=CLEAR;end
//            SHIFT            :begin LCD_RS<=0;LCD_RW<=0;LCD[7:4]<=4'b0001;LCD[3]<=shift_cur;LCD[2]<=left_shift;LCD[1:0]<=2'b00;
//                                state<=IDLE;end
//            SETFUNCTION        :begin LCD_RS<=0;LCD_RW<=0;LCD[7:5]<=3'b001;LCD[4]<=LCDwidth8;LCD[3]<=twoline;LCD[2]<=font5x10;LCD[1:0]<=2'b00;
//                                state<=SWITCHMODE;end
//            SETCGRAM        :begin if(cnt<4'd8) begin LCD_RS<=0;LCD_RW<=0;LCD[7:3]<=5'b01000;LCD[2:0]<=cnt;state<=DATACGRAM/*IDLE*/;end //行号设置
//                                     else begin state<=SETDDRAM;cnt<=0;end
//                             end
//            DATACGRAM    :begin LCD_RS<=1;LCD_RW<=0;LCD[7:5]<=3'b000;LCD[4:0]<=cgram(cnt);cnt<=cnt+1;state<=SETCGRAM; end//循环写入8行数据(5*8)
//            SETDDRAM        :begin LCD_RS<=0;LCD_RW<=0;LCD<=8'b11000011;state<=WRITERAM;end
//            WRITERAM        :begin
//                            if(address<=6'b001_110)
//                            begin
//                                LCD_RS<=1;
//                                LCD_RW<=0;
//                                LCD<=ddram(address);
//                                address<=address+1;
//                                state<=WRITERAM;
//                            end
//                            else
//                            begin
//                                LCD_RS<=0;
//                                LCD_RW<=0;
//                                state<=SHIFT;
//                                address<=6'b001_000;
//                            end
//                            end
//            endcase
//        end
//endmodule
//



module LCD(clk,rst,LCD_E,LCD_RW,LCD_RS,LCD);
//    input clk,rst;
//    output LCD_E,LCD_RW,LCD_RS;
//    output [7:0] LCD;
//    reg LCD_E,LCD_RW,LCD_RS;
//    reg [7:0] LCD;
//    
//    reg [10:0] state;
//    reg flag;
//    reg [5:0] address;
//    
//    
//    parameter IDLE        =11'b00000000000;
//    parameter CLEAR        =11'b00000000001;        //清屏
//    
//    parameter RETURNCURSOR    =11'b00000000010;    //归home位
//    
//    parameter SETMODE    =11'b00000000100;        
//    //输入方式设置,读写数据后ram地址增/减1;画面动/不动
//    
//    parameter SWITCHMODE    =11'b00000001000;    
//    //显示状态设置,显示开/关;光标开/关;闪烁开/关
//    
//    parameter SHIFT        =11'b00000010000;        
//    //光标画面滚动 画面/光标平移一位;左/右平移一位
//    
//    parameter SETFUNCTION    =11'b00000100000;    
//    //工作方式设置 1:8/1:4位数据接口;两行/一行显示;5x10/5x7点阵
//    
//    parameter SETCGRAM    =11'b00001000000;        //设置CGRAM
//    parameter SETDDRAM    =11'b00010000000;        //设置DDRAM
//    parameter READFLAG    =11'b00100000000;        //
//    parameter WRITERAM    =11'b01000000000;        //写RAM
//    parameter READRAM    =11'b10000000000;        //读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 LCDwidth8       =1;
//    parameter LCDwidth4       =0;
//    parameter twoline          =1;
//    parameter oneline          =0;
//    parameter font5x10         =1;
//    parameter font5x7          =0;
//
//    function [7:0] ddram;
//        input [5:0] n;
//        begin
//            case(n)
//            6'b000_000:ddram=8'b0100_1100;//L
//            6'b000_001:ddram=8'b0100_1100;//L
//            6'b000_010:ddram=8'b0100_1100;//L
//            6'b000_011:ddram=8'b0100_1100;//L
//            6'b000_100:ddram=8'b0100_1100;//L
//            6'b000_101:ddram=8'b0100_1100;//L
//            endcase
//        end
//    endfunction
//    
//    reg [15:0] clkcnt;
//    
//    always @ (posedge clk)
//    if(!rst)
//    clkcnt<=16'b0000_0000_0000_0000;
//    else
//    begin
//        if(clkcnt==16'b1001_1100_0100_0000)
//            clkcnt<=16'b0000_0000_0000_0000;
//        else 
//            clkcnt<=clkcnt+1;
//    end
//    
//    wire tc_clkcnt;
//    assign tc_clkcnt=(clkcnt==16'b1001_1100_0100_0000)?1:0;
//    
//    reg clkdiv;
//    always @ (posedge tc_clkcnt)
//    if(!rst)
//        clkdiv<=0;
//    else
//        clkdiv<=~clkdiv;
//    
//    reg clk_int;
//    always @ (posedge clkdiv)
//    if(rst==0)
//        clk_int<=0;
//    else
//        clk_int<=~clk_int;
//        
//    always @ (negedge clkdiv)
//    if(rst==0)
//        LCD_E<=0;
//    else
//        LCD_E<=~LCD_E;
//        
//        
//    always @ (posedge clk_int or negedge rst)
//        if(!rst)
//        begin
//            state<=IDLE;
//            address<=6'b000_000;
//            flag<=0;
//        end
//        else
//        begin
//            case(state)
//            IDLE        :begin 
//                            LCD<=8'bzzzz_zzzz;
//                            if(flag==0)
//                            begin
//                                state<=SETFUNCTION;
//                                flag<=1;
//                            end
//                            else
//                                state<=SHIFT;
//                         end
//            CLEAR            :begin LCD_RS<=0;LCD_RW<=0;LCD<=8'b0000_0001;
//                                    state<=SETMODE;end   
//            SETMODE            :begin LCD_RS<=0;LCD_RW<=0;LCD[7:2]<=6'b000001;LCD[1]<=cur_inc;LCD[0]<=cur_noshift;
//                                    state<=WRITERAM;end
//            RETURNCURSOR    :begin LCD_RS<=0;LCD_RW<=0;LCD<=8'b00000010;
//                                    state<=WRITERAM;end
//            SWITCHMODE         :begin LCD_RS<=0;LCD_RW<=0;LCD[7:3]<=5'b00001;LCD[2]<=open_display;LCD[1]<=open_cur;LCD[0]<=blank_cur;
//                                state<=CLEAR;end
//            SHIFT            :begin LCD_RS<=0;LCD_RW<=0;LCD[7:4]<=4'b0001;LCD[3]<=shift_cur;LCD[2]<=left_shift;LCD[1:0]<=2'b00;
//                                state<=IDLE;end
//            SETFUNCTION        :begin LCD_RS<=0;LCD_RW<=0;LCD[7:5]<=3'b001;LCD[4]<=LCDwidth8;LCD[3]<=twoline;LCD[2]<=font5x10;LCD[1:0]<=2'b00;
//                                state<=SWITCHMODE;end
//            SETCGRAM        :begin LCD_RS<=0;LCD_RW<=0;LCD<=8'b01000000;state<=IDLE;end
//            SETDDRAM        :begin LCD_RS<=0;LCD_RW<=0;LCD<=8'b10000000;state<=WRITERAM;end
//            WRITERAM        :begin
//                            if(address<=6'b000_101)
//                            begin
//                                LCD_RS<=1;
//                                LCD_RW<=0;
//                                LCD<=ddram(address);
//                                address<=address+1;
//                                state<=WRITERAM;
//                            end
//                            else
//                            begin
//                                LCD_RS<=0;
//                                LCD_RW<=0;
//                                state<=SHIFT;
//                                address<=6'b000_000;
//                            end
//                            end
//            endcase
//        end
//endmodule
//                    
View Code
原文地址:https://www.cnblogs.com/habyjingloveDY/p/3152092.html