• LCD1602写自定义字符的Verilog源码


    开发工具:Quartus II 9.1;

    仿真软件:Questa Sim 10.0c;

    硬件平台:Terasic DE2-115(EP2C35F672C6);

    外设:hd44780控制器lcd1602;

    3个工程文件:"lcd1602_cgram_controller.v" + "lcd1602_cgram_driver.v" + "lcd1602_cgram_driver_tsb.v";

    设计思路:

      底层直接操作lcd1602的模块为"*_controller.v"文件,三段式状态机,完成初始化液晶工作模式(无光标、5X8、2行...)、在CGRAM写入自定义的8个字符(源文件里条形图,可用于音频FFT波形图显示),完成CGRAM写数据之后进入通用的显示状态,每次显示完一个字符产生的ack信号;

      "_driver.v"完成循环调用显示8个自定义字符;

      "_driver_tsb.v"完成仿真时的驱动(原本是和"_driver.v"在同一个文件,为了方便后续综合,分开了);

    注意事项:

      系统工作频率为50MHz,lcd操作的指令、数据周期为2ms(1ms下也能用);

      CYCLONEII的芯片上电未复位之前的寄存器是0,因此程序下载到板子上的时候液晶是不显示的,没有复位引脚的需要自行设计软件复位;

      lcd_on,lcd_blon为DE2-115板子特有设计;

    源码1...

      1 `timescale 1 ns / 1 ps
      2 //`define SIM
      3 `define SYS_CLK 50_000_000
      4 //achieve lcd1602 cgram display
      5 //author wuyuehang1990
      6 //version 0.1
      7 module lcd1602_cgram_controller(
      8                                                     sys_clk,
      9                                                     sys_rst_n,
     10                                                     sys_dat_i,
     11                                                     sys_addr_i,
     12                                                     lcd_ack_o,
     13                                                     lcd_en,
     14                                                     lcd_rw,
     15                                                     lcd_rs,
     16                                                     lcd_bus,
     17                                                     lcd_on,
     18                                                     lcd_blon
     19                                                     );
     20 
     21 input sys_clk;
     22 input sys_rst_n;
     23 input [7:0] sys_dat_i;//CGRAM ONLY DISP 8 DIFFERENT FONTS//00~07
     24 input [7:0] sys_addr_i;//DDRAM ADDR
     25 output reg lcd_ack_o;
     26 //lcd interface
     27 output lcd_en;
     28 output lcd_rw;
     29 output reg lcd_rs;
     30 output reg [7:0] lcd_bus;
     31 //spec io
     32 output lcd_on;
     33 output lcd_blon;
     34 
     35 
     36 `ifdef SIM
     37         parameter ST_WIDTH = 64;
     38         parameter CLR = "CLR.....";
     39         parameter FUNC = "FUNC....";
     40         parameter ONOFF = "ON/OFF..";
     41         parameter ENTRY = "ENTRY...";
     42         parameter SETCGRAM = "SETCGRAM";
     43         parameter WRCGRAM = "WR_CGRAM";
     44         parameter SETDDRAM = "SETDDRAM";
     45         parameter WRDDRAM = "WR_DDRAM";
     46         parameter ACK = "ACK....."; 
     47 `else
     48         `define FSM 9
     49         parameter ST_WIDTH = `FSM;
     50         parameter CLR = `FSM'b0_0000_0001;//01
     51         parameter FUNC = `FSM'b0_0000_0010;//38(8BUS-2LINE)        37(8BUS-1LINE)
     52         parameter ONOFF = `FSM'b0_0000_0100;//0C(ON-SHINE)
     53         parameter ENTRY = `FSM'b0_0000_1000;//06(DISP_FIXED-CURSOR_SHIFT)
     54         parameter SETCGRAM = `FSM'b0_0001_0000;
     55         parameter WRCGRAM = `FSM'b0_0010_0000;
     56         parameter SETDDRAM = `FSM'b0_0100_0000;
     57         parameter WRDDRAM = `FSM'b0_1000_0000;
     58         parameter ACK = `FSM'b1_0000_0000;
     59         
     60 `endif
     61 
     62 //generate 1KHz(1ms)
     63 reg [19:0] cnt_1KHz=0;
     64 reg clk_1KHz=0;
     65 reg pulse1ms=0;
     66 
     67 always @ (posedge sys_clk) begin
     68 if(sys_rst_n == 1'b0)    begin
     69                                 cnt_1KHz <= 0;
     70                                 end
     71 else if(cnt_1KHz > 20'd99999) begin
     72                                                 cnt_1KHz <= 0;
     73                                                 end
     74 else begin
     75         cnt_1KHz <= cnt_1KHz + 1'd1;
     76         end
     77 end
     78 
     79 always @ (posedge sys_clk) begin
     80 if(cnt_1KHz < 20'd49999)    begin
     81                                         clk_1KHz <= 1'd1;
     82                                         end
     83 else begin
     84         clk_1KHz <= 1'd0;
     85         end
     86 end
     87 
     88 always @ (posedge sys_clk) begin
     89 if(cnt_1KHz == 20'd99999) pulse1ms <= 1'd1;
     90 else pulse1ms <= 1'd0;
     91 end
     92 
     93 //generate lcd_en,lcd_rw;
     94 assign lcd_en = clk_1KHz;
     95 assign lcd_rw = 1'b0;
     96 //generate spec io
     97 assign lcd_on = 1'b1;
     98 assign lcd_blon = 1'b1;
     99 
    100 //FSM
    101 reg [5:0] cnt64=0;//count 64 hex char
    102 reg [ST_WIDTH-1:0] c_st = FUNC;
    103 reg [ST_WIDTH-1:0] n_st = FUNC;
    104 //fsm-1
    105 always @ (posedge sys_clk) begin
    106 if(1'b0 == sys_rst_n)    c_st <= FUNC;
    107 else c_st <= n_st;
    108 end
    109 
    110 //fsm-2
    111 always @ (*) begin
    112         n_st = FUNC;
    113         case(c_st)
    114             FUNC:begin
    115                         n_st = (pulse1ms == 1'b1)?ONOFF:FUNC;
    116                         end
    117             ONOFF:begin
    118                         n_st = (pulse1ms == 1'b1)?ENTRY:ONOFF;
    119                         end
    120             ENTRY:begin
    121                         n_st = (pulse1ms == 1'b1)?CLR:ENTRY;
    122                         end
    123             CLR:begin
    124                         n_st = (pulse1ms == 1'b1)?SETCGRAM:CLR;
    125                         end
    126             SETCGRAM:begin
    127                                 n_st = (pulse1ms == 1'b1)?WRCGRAM:SETCGRAM;
    128                                 end
    129             WRCGRAM:begin
    130                                     if((pulse1ms == 1'b1) && (cnt64 == 6'd63))
    131                                             n_st = SETDDRAM;
    132                                     else if(pulse1ms == 1'b1)
    133                                             n_st = SETCGRAM;
    134                                     else 
    135                                             n_st = WRCGRAM;
    136                                 end
    137             SETDDRAM:begin
    138                                 n_st = (pulse1ms == 1'b1)?WRDDRAM:SETDDRAM;
    139                                 end
    140             WRDDRAM:begin
    141                                 n_st = (pulse1ms == 1'b1)?ACK:WRDDRAM;
    142                                 end
    143             ACK:begin
    144                     n_st  = SETDDRAM;
    145                     end
    146             default:begin
    147                         n_st = FUNC;
    148                         end
    149             endcase
    150 end
    151 
    152 //FSM-3
    153 //generate lcd_bus lcd_rs and lcd_ack
    154 
    155 always @ (posedge sys_clk) begin
    156 if(1'b0 == sys_rst_n) begin
    157                                 lcd_ack_o <= 0;
    158                                 lcd_rs <= 0;
    159                                 lcd_bus <= 8'h38;
    160                                 cnt64 <= 0;
    161                                 end
    162 else begin
    163         case(n_st)
    164         FUNC:begin
    165                     lcd_rs <= 0;
    166                     lcd_ack_o <= 0;
    167                     lcd_bus <= 8'h38;//3c(2-line-5*10)//38(2-line-5*8)
    168                     cnt64 <= 6'd63;
    169                     end
    170         ONOFF:begin
    171                     lcd_rs <= 0;
    172                     lcd_ack_o <= 0;
    173                     lcd_bus <= 8'h0d;//no cursor
    174                     cnt64 <= 6'd63;
    175                     end
    176         ENTRY:begin
    177                     lcd_rs <= 0;
    178                     lcd_ack_o <= 0;
    179                     lcd_bus <= 8'h06;
    180                     cnt64 <= 6'd63;
    181                     end
    182         CLR:begin
    183                     lcd_rs <= 0;
    184                     lcd_ack_o <= 0;
    185                     lcd_bus <= 8'h01;
    186                     cnt64 <= 6'd63;
    187                     end
    188         SETCGRAM:begin
    189                                 lcd_ack_o <= 0;
    190                                 lcd_rs <= 0;
    191                                 cnt64 <= (pulse1ms == 1'b1)?cnt64 + 1'd1:cnt64;
    192                                 lcd_bus <= {2'b01,cnt64};
    193                             end
    194         WRCGRAM:begin
    195                                 lcd_ack_o <= 0;
    196                                 lcd_rs <= 1;
    197                                 cnt64 <= cnt64;
    198                                 /*
    199                                 case(cnt64)
    200                                 6'd0,6'd1,6'd2,6'd3,6'd4,6'd5,6'd6,6'd7:lcd_bus <= 8'h00;//empty
    201                                 6'd8,6'd9,6'd10,6'd11,6'd12,6'd13:lcd_bus <= 8'h00;
    202                                 6'd14:lcd_bus <= 8'h1f;
    203                                 6'd15:lcd_bus <= 8'h00;//1step
    204                                 6'd16,6'd17,6'd18,6'd19,6'd20:lcd_bus <= 8'h00;
    205                                 6'd21,6'd22:lcd_bus <= 8'h1f;
    206                                 6'd23:lcd_bus <= 8'h00;//2step
    207                                 6'd24,6'd25,6'd26,6'd27:lcd_bus <= 8'h00;
    208                                 6'd28,6'd29,6'd30:lcd_bus <= 8'h1f;
    209                                 6'd31:lcd_bus <= 8'h00;//3step
    210                                 6'd32,6'd33,6'd34:lcd_bus <= 8'h00;
    211                                 6'd35,6'd36,6'd37,6'd38:lcd_bus <= 8'h1f;
    212                                 6'd39:lcd_bus <= 8'h00;//4step
    213                                 6'd40,6'd41:lcd_bus <= 8'h00;
    214                                 6'd42,6'd43,6'd44,6'd45,6'd46:lcd_bus <= 8'h1f;
    215                                 6'd47:lcd_bus <= 8'h00;//5step
    216                                 6'd48:lcd_bus <= 8'h00;
    217                                 6'd49,6'd50,6'd51,6'd52,6'd53,6'd54:lcd_bus <= 8'h1f;
    218                                 6'd55:lcd_bus <= 8'h00;//6step
    219                                 6'd56,6'd57,6'd58,6'd59,6'd60,6'd61,6'd62:lcd_bus <= 8'h1f;
    220                                 6'd63:lcd_bus <= 8'h00;//7step
    221                                 endcase
    222                                 */
    223                                 case(cnt64)
    224                                 6'd0,6'd1,6'd2,6'd3,6'd4,6'd5,6'd6:lcd_bus <= 8'h00;
    225                                 6'd7:lcd_bus <= 8'h1f;//s1
    226                                 6'd8,6'd9,6'd10,6'd11,6'd12,6'd13:lcd_bus <= 8'h00;
    227                                 6'd14:lcd_bus <= 8'h1f;
    228                                 6'd15:lcd_bus <= 8'h1f;//s2
    229                                 6'd16,6'd17,6'd18,6'd19,6'd20:lcd_bus <= 8'h00;
    230                                 6'd21,6'd22:lcd_bus <= 8'h1f;
    231                                 6'd23:lcd_bus <= 8'h1f;//s3
    232                                 6'd24,6'd25,6'd26,6'd27:lcd_bus <= 8'h00;
    233                                 6'd28,6'd29,6'd30:lcd_bus <= 8'h1f;
    234                                 6'd31:lcd_bus <= 8'h1f;//4step
    235                                 6'd32,6'd33,6'd34:lcd_bus <= 8'h00;
    236                                 6'd35,6'd36,6'd37,6'd38:lcd_bus <= 8'h1f;
    237                                 6'd39:lcd_bus <= 8'h1f;//5step
    238                                 6'd40,6'd41:lcd_bus <= 8'h00;
    239                                 6'd42,6'd43,6'd44,6'd45,6'd46:lcd_bus <= 8'h1f;
    240                                 6'd47:lcd_bus <= 8'h1f;//6step
    241                                 6'd48:lcd_bus <= 8'h00;
    242                                 6'd49,6'd50,6'd51,6'd52,6'd53,6'd54:lcd_bus <= 8'h1f;
    243                                 6'd55:lcd_bus <= 8'h1f;//7step
    244                                 6'd56,6'd57,6'd58,6'd59,6'd60,6'd61,6'd62:lcd_bus <= 8'h1f;
    245                                 6'd63:lcd_bus <= 8'h1f;//8step
    246                                 endcase
    247                             end
    248         SETDDRAM:begin
    249                                 lcd_ack_o <= 0;
    250                                 lcd_rs <= 0;
    251                                 lcd_bus <= sys_addr_i;
    252                                 cnt64 <= cnt64;
    253                                 end
    254         WRDDRAM:begin
    255                                 lcd_ack_o <= 0;
    256                                 lcd_rs <= 1;
    257                                 cnt64 <= cnt64;
    258                                 lcd_bus <= sys_dat_i;
    259                                 end
    260         ACK:begin
    261                                 lcd_ack_o <= 1;
    262                                 lcd_rs <= 0;
    263                                 lcd_bus <= lcd_bus;
    264                                 cnt64 <= cnt64;
    265                                 end
    266         default:begin
    267                                 lcd_ack_o <= 0;
    268                                 lcd_rs <= 0;
    269                                 lcd_bus <= 8'h38;
    270                                 cnt64 <= cnt64;
    271                                 end
    272         endcase
    273         end
    274 end
    275 
    276 endmodule

    源码2...

     1 `timescale 1 ns / 1 ps
     2 module lcd1602_cgram_driver(
     3                                                             sys_clk,
     4                                                             sys_rst_n,
     5                                                             lcd_en,
     6                                                             lcd_rw,
     7                                                             lcd_rs,
     8                                                             lcd_bus,
     9                                                             lcd_on,
    10                                                             lcd_blon
    11                                                             );
    12 input sys_clk;
    13 input sys_rst_n;
    14 output lcd_rs;
    15 output lcd_rw;
    16 output lcd_en;
    17 output lcd_on;
    18 output lcd_blon;
    19 output [7:0] lcd_bus;
    20 
    21 
    22 reg [7:0] sys_dat_i=0;
    23 reg [7:0] sys_addr_i=0;
    24 wire lcd_ack_o;
    25 
    26 
    27 always @ (posedge sys_clk) begin
    28 if(sys_rst_n == 1'b0) begin
    29                                 sys_dat_i <= 0;
    30                                 sys_addr_i <= 8'h80;
    31                                 end
    32 else if(lcd_ack_o == 1'b1) begin
    33                                             if(sys_dat_i == 8'd7)    begin
    34                                                                                 sys_dat_i <= 0;
    35                                                                                 sys_addr_i <= 8'h80;
    36                                                                                 end
    37                                             else begin
    38                                                     sys_dat_i <= sys_dat_i + 1'd1;
    39                                                     sys_addr_i <= sys_addr_i + 1'd1;
    40                                                     end
    41                                         end
    42 else begin
    43         sys_dat_i <= sys_dat_i;
    44         sys_addr_i <= sys_addr_i;
    45         end
    46 end
    47 
    48 
    49 
    50 lcd1602_cgram_controller                hal(
    51                                                     .sys_clk( sys_clk ),
    52                                                     .sys_rst_n( sys_rst_n ),
    53                                                     .sys_dat_i( sys_dat_i ),
    54                                                     .sys_addr_i( sys_addr_i ),
    55                                                     .lcd_ack_o( lcd_ack_o ),
    56                                                     .lcd_en( lcd_en ),
    57                                                     .lcd_rw( lcd_rw ),
    58                                                     .lcd_rs( lcd_rs ),
    59                                                     .lcd_bus( lcd_bus ),
    60                                                     .lcd_on( lcd_on ),
    61                                                     .lcd_blon( lcd_blon )
    62                                                     );
    63 
    64 endmodule

    源码3...

    `timescale 1 ns / 1 ps
    module lcd1602_cgram_driver_tsb();
    reg sys_clk;
    reg sys_rst_n;
    
    initial begin
    sys_clk=1;
    sys_rst_n=0;
    #100 sys_rst_n=1;
    end
    
    always begin
    #10 sys_clk=~sys_clk;
    end
    
    wire lcd_rw;
    wire lcd_rs;
    wire lcd_en;
    wire [7:0] lcd_bus;
    wire lcd_on;
    wire lcd_blon;
    
    lcd1602_cgram_driver                            api(
                                                                .sys_clk( sys_clk ),
                                                                .sys_rst_n( sys_rst_n ),
                                                                .lcd_en( lcd_en ),
                                                                .lcd_rw( lcd_rw ),
                                                                .lcd_rs( lcd_rs ),
                                                                .lcd_bus( lcd_bus ),
                                                                .lcd_on( lcd_on ),
                                                                .lcd_blon( lcd_blon )
                                                                );
                                                                
    endmodule
  • 相关阅读:
    点滴
    Type.GetType() 返回null的解决办法
    DDD中的实体
    开启博客之路
    Pytorch框架学习(1)张量操作
    GitHub学习之路1
    JavaScript学习之路1
    Java&Eclipse&Maven的折腾
    Ubuntu学习之路1
    Windos下的一些命令集合
  • 原文地址:https://www.cnblogs.com/loadomain/p/3224605.html
Copyright © 2020-2023  润新知