求一个verilog写的LCD12864例程

2019-03-25 09:00发布

求一个verilog写的LCD12864例程 多谢了~ 此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
3条回答
zhouwuwei
2019-03-25 16:56
module LCD12864(
     input CLK,                        //系统时钟输入
     input RST_N,                //系统复位输入
     output reg LCD_RS,                //LCD的寄存器选择输出信号
     output LCD_RW,                //LCD的读、写操作选择输出信号
     output LCD_E,                //LCD使能信号
     output reg [7:0]LCD_D,        //LCD的数据总线(不进行读操作,故为输出)
     output PSB,
     output RST_LCD        
);

reg CLK_LCD;                        //LCD时钟信号
reg [23:0]cnt;

assign PSB = 1;
assign RST_LCD = 1;
// CLK频率为50MHz, 产生LCD时钟信号, 10Hz
always @(posedge CLK or negedge RST_N)
begin
     if (!RST_N)
     begin
         cnt <= 24'b0;
         CLK_LCD <= 0;
     end
     else if(cnt == 2499999)
     begin
         cnt <= 0;
         CLK_LCD <= ~CLK_LCD;
     end
     else
         cnt <= cnt +1'b1;
end

reg        [8:0] state;                                //State Machine code
parameter IDLE                 = 9'b00000000;                //初始状态,下一个状态为CLEAR
parameter SETFUNCTION        = 9'b00000001;                //功能设置:8位数据接口
parameter SETFUNCTION2        = 9'b00000010;               
parameter SWITCHMODE        = 9'b00000100;                //显示开关控制:开显示,光标和闪烁关闭
parameter CLEAR                = 9'b00001000;                //清屏
parameter SETMODE             = 9'b00010000;                //输入方式设置:数据读写操作后,地址自动加一/画面不动
parameter SETDDRAM            = 9'b00100000;                //设置DDRAM的地址:第一行起始为0x80/第二行为0x90
parameter WRITERAM            = 9'b01000000;                //数据写入DDRAM相应的地址
parameter STOP                = 9'b10000000;                //LCD操作完毕,释放其控制

reg flag;                //标志位,LCD操作完毕为0
reg [4:0]char_cnt;               
reg [7:0]data_disp;

assign LCD_RW = 1'b0;                                //没有读操作,R/W信号始终为低电平
assign LCD_E  = (flag == 1)?CLK_LCD:1'b0;        //E信号出现高电平以及下降沿的时刻与LCD时钟相同

always @(posedge CLK_LCD or negedge RST_N)        //只有在写数据操作时,RS信号才为高电平,其余为低电平
begin
     if(!RST_N)
         LCD_RS <= 1'b0;
     else if(state == WRITERAM)
         LCD_RS <= 1'b1;
     else
         LCD_RS <= 1'b0;
end

// State Machine
always @(posedge CLK_LCD or negedge RST_N)
begin
     if(!RST_N)
     begin
         state <= IDLE;
         LCD_D <= 8'bzzzzzzzz;
         char_cnt <= 5'b0;
         flag <= 1'b1;
     end
     else begin
         case(state)
             IDLE:
            begin
            state <= SETFUNCTION;
             LCD_D <= 8'bzzzzzzzz;
        end
         SETFUNCTION:
         begin
             state <= SETFUNCTION2;
             LCD_D <= 8'h30;                // 8-bit 控制界面,基本指令集动作
         end
         SETFUNCTION2:
         begin
             state <= SWITCHMODE;
             LCD_D <= 8'h30;                // 清屏               
        end
         SWITCHMODE:
         begin
             state <= CLEAR;
             LCD_D <= 8'h0c;                // 显示开关:开显示,光标和闪烁关闭
         end
         CLEAR:
         begin
             state <= SETMODE;
             LCD_D <= 8'h01;
         end
         SETMODE:
         begin
             state <= SETDDRAM;
             LCD_D <= 8'h06;                // 输入方式设置: 数据读写后,地址自动加1,画面不动
         end
         SETDDRAM:
         begin
             state <= WRITERAM;
             if(char_cnt == 0)                //如果显示的是第一个字符,则设置第一行的首字符地址
             begin
                 LCD_D <= 8'h80;                //Line1
             end
             else                        //第二次设置时,是设置第二行的首字符地址
             begin
                 LCD_D <= 8'h90;                //Line2
             end
         end
         WRITERAM:
         begin
             if(char_cnt <= 11)
             begin
                 char_cnt <= char_cnt + 1'b1;
                 LCD_D <= data_disp;
                 if( char_cnt == 11 )
                     state <= SETDDRAM;
                 else
                     state <= WRITERAM;
             end
             else if( char_cnt >= 12 && char_cnt <= 25)
             begin
                 LCD_D <= data_disp;
                 if(char_cnt == 25)
                 begin
                     state <= STOP;
                     char_cnt <= 5'b0;
                     flag <= 1'b0;
                 end
                 else
                begin
                     state <= WRITERAM;
                     char_cnt <= char_cnt + 1'b1;
                 end
             end
         end
         STOP: state <= STOP;
         default: state <= IDLE;
     endcase
end
end

always @(char_cnt)                        //输出的字符
begin
     case (char_cnt)
         6'd0: data_disp = "H";        //        第
         6'd1: data_disp = "e";        //        一
         6'd2: data_disp = "l";        //        行
         6'd3: data_disp = "l";        //        的
         6'd4: data_disp = "o";        //        显
         6'd5: data_disp = ",";        //        示
         6'd6: data_disp = "w";        //        内
         6'd7: data_disp = "o";        //        容
         6'd8: data_disp = "r";        //
         6'd9: data_disp = "l";        //        字符串变量形式
         6'd10: data_disp = "d";        //
         6'd11: data_disp ="!";        //               

        6'd12: data_disp = "w";        //        第二行的显示内容
         6'd13: data_disp = "w";        //
         6'd14: data_disp = "w";
         6'd15: data_disp = ".";        
         6'd16: data_disp = "o";
         6'd17: data_disp = "u";
         6'd18: data_disp = "r";
         6'd19: data_disp = "d";
         6'd20: data_disp = "e";
         6'd21: data_disp = "v";
         6'd22: data_disp = ".";
         6'd23: data_disp = "c";
         6'd24: data_disp = "n";
         default :   data_disp =  8'd32;
     endcase
end

endmodule

一周热门 更多>