一、前言
闲来无事,在X宝上搜寻了一套DE2-115的FPGA开发板以丰富业余生活。虽附带光盘里包含各外设及组件驱动及接口样例,但本着“不捣腾不痛快”的折腾精神,将DE2-115的各个外设重新整理并玩转一遍。
DE2-115全貌见下图,LCD1602是一个简单、实用的显示交互界面;DE2-115中的1602不支持中文字库。
二、接口说明
1602 LCD模块接口如下图所示,对几个信号做简要说明:
#4 (RS) - DB内容指示信号:0-当前DB数据为命令数据;1-当前DB数据为显示数据。
#5 (RW)- 读写指示信号:0-当前进行写操作;1-当前进行读操作。
#6 (E)- 片选使能指示信号:0-片选无效;1-片选有效。
#7~#14 (DB0~DB7)- 显示或命令读写数据。
三、接口时序
写时序如下图所示:由于LCD 1602配置接口没有时钟,接口时序需要严格遵守。
读时序
四、接口设计
1 //--====================================================================================-- 2 // THIS FILE IS PROVIDED IN SOURCE FORM FOR FREE EVALUATION, FOR EDUCATIONAL USE OR FOR 3 // PEACEFUL RESEARCH. DO NOT USE IT IN A COMMERCIAL PRODUCT . IF YOU PLAN ON USING THIS 4 // CODE IN A COMMERCIAL PRODUCT, PLEASE CONTACT [email protected] TO PROPERLY LICENSE 5 // ITS USE IN YOUR PRODUCT. 6 // 7 // Project : Verilog Common Module 8 // File Name : lcd_reg_intf.v 9 // Creator(s) : [email protected] 10 // Date : 2015/12/01 11 // Description : A Reg Timing for LCD1602 12 // 13 // Modification : 14 // (1) Initial design 2015-12-01 15 // 16 // 17 //--====================================================================================-- 18 19 module LCD_REG_INTF 20 ( 21 clk , 22 rst_n , 23 write , 24 read , 25 wdata , 26 reg_sel , 27 rdata , 28 ready , 29 lcd_rs , 30 lcd_rw , 31 lcd_en , 32 lcd_db_out , 33 lcd_db_oen , 34 lcd_db_in 35 ); 36 37 //PARA DECLARATION 38 parameter LCD_EN_SETUP_MIN = 16‘d40 ; 39 parameter LCD_EN_WIDTH_MIN = 16‘d230 ; 40 parameter LCD_EN_HOLD_MIN = 16‘d230 ; 41 42 parameter LCD_EN_CYCLE_MIN = (LCD_EN_SETUP_MIN + LCD_EN_WIDTH_MIN + LCD_EN_HOLD_MIN) ; 43 44 //INPUT DECLARATION 45 input clk ; //LCD clock 46 input rst_n ; //LCD clock reset (0: reset) 47 input write ; //LCD write enable(1: enable), only one clock pulse 48 input read ; //LCD read enable(1: enable), only one clock pulse 49 input reg_sel ; //LCD DATA SEL: 0-COMMAND | 1-DATA; 50 input [7:0] wdata ; //LCD write data 51 input [7:0] lcd_db_in ; //LCD INTF SIGNAL 52 53 //OUTPUT DECLARATION 54 output [7:0] rdata ; //LCD READ data 55 output ready ; //LCD ACCESS Ready 56 output lcd_rs ; //LCD INTF SIGNAL 57 output lcd_rw ; //LCD INTF SIGNAL 58 output lcd_en ; //LCD INTF SIGNAL 59 output [7:0] lcd_db_out ; //LCD INTF SIGNAL 60 output lcd_db_oen ; //LCD INTF SIGNAL 61 62 //--========================MODULE SOURCE CODE==========================-- 63 reg [15:0] lcd_timing_cnt ; 64 wire lcd_wr_cmd ; 65 wire lcd_cmd_idle ; 66 reg lcd_rs ; 67 reg lcd_rw ; 68 reg lcd_db_oen ; 69 reg lcd_en ; 70 reg [7:0] lcd_db_out ; 71 reg [7:0] rdata ; 72 73 //--=========================================-- 74 // LCD TIMING COUNT : 75 // Initial Value LCD_EN_CYCLE_MIN ; It count 76 // from 0 to LCD_EN_CYCLE_MIN when one access. 77 //--=========================================-- 78 assign lcd_wr_cmd = (write | read); 79 assign lcd_cmd_idle = (lcd_timing_cnt >= LCD_EN_CYCLE_MIN) ; 80 81 always @(posedge clk or negedge rst_n) 82 begin 83 if(rst_n == 1‘b0) 84 lcd_timing_cnt <= LCD_EN_CYCLE_MIN ; 85 else if (lcd_wr_cmd & lcd_cmd_idle) 86 lcd_timing_cnt <= 16‘b0 ; 87 else if (lcd_timing_cnt < LCD_EN_CYCLE_MIN) 88 lcd_timing_cnt <= lcd_timing_cnt + 16‘b1 ; 89 end 90 91 //--=========================================-- 92 // LCD INTERFACE SIGNAL : 93 // RS : 0-COMMAND | 1-DATA; 94 // RW : 0-WRITE | 1-READ; 95 // E : 0-Disable | 1-ENABLE; 96 //--=========================================-- 97 always @(posedge clk or negedge rst_n) 98 begin 99 if(rst_n == 1‘b0) 100 lcd_rs <= 1‘b0 ; 101 else if (lcd_wr_cmd & lcd_cmd_idle) 102 lcd_rs <= reg_sel ; 103 end 104 105 always @(posedge clk or negedge rst_n) 106 begin 107 if(rst_n == 1‘b0) 108 begin 109 lcd_rw <= 1‘b0 ; 110 lcd_db_oen <= 1‘b1 ; 111 end 112 else if (write & lcd_cmd_idle) 113 begin 114 lcd_rw <= 1‘b0 ; 115 lcd_db_oen <= 1‘b0 ; 116 end 117 else if (read & lcd_cmd_idle) 118 begin 119 lcd_rw <= 1‘b1 ; 120 lcd_db_oen <= 1‘b1 ; 121 end 122 end 123 124 always @(posedge clk or negedge rst_n) 125 begin 126 if(rst_n == 1‘b0) 127 lcd_en <= 1‘b0 ; 128 else if (lcd_timing_cnt <= LCD_EN_SETUP_MIN) 129 lcd_en <= 1‘b0 ; 130 else if (lcd_timing_cnt >= LCD_EN_SETUP_MIN + LCD_EN_WIDTH_MIN) 131 lcd_en <= 1‘b0 ; 132 else 133 lcd_en <= 1‘b1 ; 134 end 135 136 //--=========================================-- 137 // lcd_db_out : 138 // Update wdata when write enbale and keep it 139 // till en cycle end. 140 //--=========================================-- 141 always @(posedge clk or negedge rst_n) 142 begin 143 if(rst_n == 1‘b0) 144 lcd_db_out <= 8‘b0 ; 145 else if (write & lcd_cmd_idle) 146 lcd_db_out <= wdata; 147 else if (lcd_timing_cnt >= LCD_EN_CYCLE_MIN) 148 lcd_db_out <= 8‘b0 ; 149 end 150 151 //--=========================================-- 152 // rdata : 153 // Update rdata when lcd en cycle end. 154 //--=========================================-- 155 always @(posedge clk or negedge rst_n) 156 begin 157 if(rst_n == 1‘b0) 158 rdata <= 8‘h0 ; 159 else if (read & lcd_cmd_idle) //Specify an Error Code here. 160 rdata <= 8‘hFF; 161 else if (lcd_timing_cnt >= LCD_EN_CYCLE_MIN) 162 rdata <= lcd_db_in ; 163 end 164 165 endmodule 166 167
时间: 2024-09-29 17:43:48