LCD1602驱动开发记录 顶层模块开发(1)

Dianthe ·
更新时间:2024-09-21
· 713 次阅读

说明书摘要 指令集

在这里插入图片描述
在这里插入图片描述

目前顶层开发到一半,只开发了写功能,读功能还未开发。另:目前指令逻辑直接在顶层中开发,代码写的比较草,状态机代码没有优化,因此顶层文件代码量超过了300行。。。。。后面可以将指令逻辑做个封装

顶层Verilog代码 //Name:Lcd_1602 //Author:Yang_Cheng_Yu //Date:2020/4/18 //==================defines===================== `define SIM module lcd1602( //================System Signal================ input clk, input rst_n, //================Interface==================== output RS, output RW, output E, inout[7:0] DB, input clr_req, input cur_back_req, input set_input_req, input disp_onoff_req, input shift_req, input set_function_req, input set_char_gen_addr_req, input set_data_save_addr_req, input set_rd_busy_req, input wr_ddram_req, input rd_ddram_req, input[7:0] data_wr ); //================parameters=================== `ifndef SIM `else `endif //addr parameter ADDR_CHAR_GEN_REG = 6'b01_0011; parameter ADDR_DISP_DATA_REG = 7'b011_0011; parameter ADDR_CNT = 7'b010_0101; //state machine localparam S_IDLE = 12'b000_0000_00001; localparam S_CLR = 12'b000_0000_00010; localparam S_CURSOR_BACK = 12'b000_0000_00100; localparam S_SET_INPUT = 12'b000_0000_01000; localparam S_DISPLAY_ONOFF = 12'b000_0000_10000; localparam S_SHIFT = 12'b000_0001_00000; localparam S_SET_FUNCTION = 12'b000_0010_00000; localparam S_SET_CHAR_GEN_ADDR = 12'b000_0100_00000; localparam S_SET_DATA_SAVE_ADDR = 12'b000_1000_00000; localparam S_RD_BUSY = 12'b001_0000_00000; localparam S_WR_DDRAM = 12'b010_0000_00000; localparam S_RD_DDRAM = 12'b100_0000_00000; //command localparam CMD_CLR = 10'b00_0000_0001; localparam CMD_CURSOR_BACK = 10'b00_0000_0010; localparam CMD_SET_INPUT = 10'b00_0000_0110;//默认光标右移 localparam CMD_DISPLAY_ONOFF = 10'b00_0000_1110;//默认开启整体显示,有光标,光标不闪烁 localparam CMD_SHIFT = 10'b00_0001_1100;//默认移动显示文字,向右移动 localparam CMD_SET_FUNCTION = 10'b00_0010_1100;//默认8位总线,双行显示,5*10点阵字符 localparam CMD_SET_CHAR_GEN_ADDR = {4'b0001,ADDR_CHAR_GEN_REG};//前6位是字符发生贮存器地址 localparam CMD_SET_DATA_SAVE_ADDR = {3'b001,ADDR_DISP_DATA_REG};//前7位是数据贮存器地址 localparam CMD_RD_BUSY = {3'b010,ADDR_CNT};//默认不忙 //================System regs================== reg[9:0] state; reg[1:0] delay; wire rs; wire rw; reg wr_req; wire wr_req_wire; assign wr_req_wire = wr_req; wire flag_wr_end; reg[9:0] cmd; wire[7:0] out_db; assign out_db = (state==S_RD_BUSY||state==S_RD_DDRAM)?8'hz:cmd[7:0]; assign DB=(state==S_RD_DDRAM||state==S_RD_BUSY)?8'hz:out_db; // assign {rs,rw,out_db} = (state!=S_RD_DDRAM)?cmd:10'bz; assign rs = (state==S_WR_DDRAM||state==S_RD_DDRAM)?1'b1:1'b0; assign rw = (state==S_RD_BUSY||state==S_RD_DDRAM)?1'b1:1'b0; wire[9:0] CMD_WR_DDRAM; wire[9:0] CMD_RD_DDRAM; assign CMD_WR_DDRAM = {2'b10,data_wr}; assign CMD_RD_DDRAM = {2'b11,8'hz}; //================Main Codes=================== lcd_write lcd_write_inst( //================System Signal================ .clk (clk), .rst_n (rst_n), //================Interface==================== .rs_in (rs), .RS (RS),//指令数据选择 .RW (RW), .E (E), .DB (DB), .wr_req (wr_req_wire), .data (out_db), .flag_wr_end (flag_wr_end) ); //state machine always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0) state <= S_IDLE; else case(state) S_IDLE:begin if(clr_req==1'b1) state <= S_CLR; else state <= S_IDLE; end S_CLR:begin if(flag_wr_end==1'b1) state <= S_IDLE; else state <= S_CLR; end S_CURSOR_BACK:begin if(flag_wr_end==1'b1) state <= S_IDLE; else state <= S_CURSOR_BACK; end S_SET_INPUT:begin if(flag_wr_end==1'b1) state <= S_IDLE; else state <= S_SET_INPUT; end S_DISPLAY_ONOFF:begin if(flag_wr_end==1'b1) state <= S_IDLE; else state <= S_DISPLAY_ONOFF; end S_SHIFT:begin if(flag_wr_end==1'b1) state <= S_IDLE; else state <= S_SHIFT; end S_SET_FUNCTION:begin if(flag_wr_end==1'b1) state <= S_IDLE; else state <= S_SET_FUNCTION; end S_SET_CHAR_GEN_ADDR:begin if(flag_wr_end==1'b1) state <= S_IDLE; else state <= S_SET_CHAR_GEN_ADDR; end S_SET_DATA_SAVE_ADDR:begin if(flag_wr_end==1'b1) state <= S_IDLE; else state <= S_SET_DATA_SAVE_ADDR; end // S_RD_BUSY:begin // if(flag_wr_end==1'b1) // state <= S_IDLE; // else // state <= S_RD_BUSY; // end S_WR_DDRAM:begin if(flag_wr_end==1'b1) state <= S_IDLE; else state <= S_WR_DDRAM; end // S_RD_DDRAM:begin // end default:state <= S_IDLE; endcase end //cmd always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0) state <= S_IDLE; else case(state) S_IDLE:begin cmd <= 10'b00_0000_0000; end S_CLR:begin cmd <= CMD_CLR; if(delay==2'd2) delay <= 'd0; else delay <= delay + 1'b1; if(delay==2'd1) wr_req <= 1'b1; else if(delay==2'd2) wr_req <= 1'b0; end S_CURSOR_BACK:begin cmd <= CMD_CURSOR_BACK; if(delay==2'd2) delay <= 'd0; else delay <= delay + 1'b1; if(delay==2'd1) wr_req <= 1'b1; else if(delay==2'd2) wr_req <= 1'b0; end S_SET_INPUT:begin cmd <= CMD_SET_INPUT; if(delay==2'd2) delay <= 'd0; else delay <= delay + 1'b1; if(delay==2'd1) wr_req <= 1'b1; else if(delay==2'd2) wr_req <= 1'b0; end S_DISPLAY_ONOFF:begin cmd <= CMD_DISPLAY_ONOFF; if(delay==2'd2) delay <= 'd0; else delay <= delay + 1'b1; if(delay==2'd1) wr_req <= 1'b1; else if(delay==2'd2) wr_req <= 1'b0; end S_SHIFT:begin cmd <= CMD_SHIFT; if(delay==2'd2) delay <= 'd0; else delay <= delay + 1'b1; if(delay==2'd1) wr_req <= 1'b1; else if(delay==2'd2) wr_req <= 1'b0; end S_SET_FUNCTION:begin cmd <= CMD_SET_FUNCTION; if(delay==2'd2) delay <= 'd0; else delay <= delay + 1'b1; if(delay==2'd1) wr_req <= 1'b1; else if(delay==2'd2) wr_req <= 1'b0; end S_SET_CHAR_GEN_ADDR:begin cmd <= CMD_SET_CHAR_GEN_ADDR; if(delay==2'd2) delay <= 'd0; else delay <= delay + 1'b1; if(delay==2'd1) wr_req <= 1'b1; else if(delay==2'd2) wr_req <= 1'b0; end S_SET_DATA_SAVE_ADDR:begin cmd <= CMD_SET_DATA_SAVE_ADDR; if(delay==2'd2) delay <= 'd0; else delay <= delay + 1'b1; if(delay==2'd1) wr_req <= 1'b1; else if(delay==2'd2) wr_req <= 1'b0; end S_RD_BUSY:begin cmd <= CMD_RD_BUSY; if(delay==2'd2) delay <= 'd0; else delay <= delay + 1'b1; if(delay==2'd1) wr_req <= 1'b1; else if(delay==2'd2) wr_req <= 1'b0; end S_WR_DDRAM:begin cmd <= CMD_WR_DDRAM; if(delay==2'd2) delay <= 'd0; else delay <= delay + 1'b1; if(delay==2'd1) wr_req <= 1'b1; else if(delay==2'd2) wr_req <= 1'b0; end // S_RD_DDRAM:begin // end default:begin cmd <= 10'b00_0000_0000; delay <= 'd0; end endcase end endmodule
作者:杨少侠qy



lcd1602 模块

需要 登录 后方可回复, 如果你还没有账号请 注册新账号
相关文章