【原创】闫若川FPGA:TFT LCD液晶屏 FPGA 代码

 【原创】TFT LCD液晶屏的FPGA代码

       随着FPGA的发展,尤其是ZYNQ和Cyclone V的出现,LCD液晶屏的显示在FPGA上的应用得到了 很大的发展。 用逻辑去写图片,毕竟不是强项。但是配合ARM进行显示,还是有很大的用处的。

      废话就不多说了,之前调试的FPGA的代码,现在发布出来供大家测试使用。

      我尽量做的灵活一些,只需要修改几个宏定义就可以拿来用了,我们用的是720P和1080P的,参数需要参考液晶屏厂给的LCD参数进行修改。这些都很简单了,不再多说了。

      ZYNQ接TFT的液晶屏,可以参考官方给的VDMA方案,也可以自己去做协议进去。不过个人感觉自己写的更好用一点,前端加个FIFO就搞定了,一秒传输100MBPS+是很轻松的。


下面是仿真的效果: 1
//**************************************************************** 2 //Editor : 闫若川 FPGA 3 //-------------------------------------------------------------------------------- 4 //Tool Version: 5 //Date : Tue Jul 3 16:07:00 2012 6 //Host : PC-20100713LAID running 64-bit major release 7 //Command : 8 //Design : tft_lcd_top 9 //Purpose : TFT LCD display code ,output test pixel 10 //Notice : MIPI code needs to be reconfigured 11 //-------------------------------------------------------------------------------- 12 module tft_lcd_top 13 #( 14 //******** 800 x 480 LCD screen 15 16 parameter HSYNC_NUM = 16'd720 ,//* 17 parameter HS_PULSE_WIDTH = 16'd33 ,//*// HSA 33 18 parameter H_BLACKING = 16'd133 ,//*// HSA + HBP 19 parameter H_FRONT_PORCH = 16'd100 ,//*// 20 parameter VSYNC_NUM = 16'd1280 ,//* 21 parameter VS_PULSE_WIDTH = 16'd2 ,// 22 parameter V_BLACKING = 16'd32 ,// 23 parameter V_FRONT_PORCH = 16'd20 //* 24 25 // parameter HSYNC_NUM = 16'd1280 , 26 // parameter H_BLACKING = 16'd46 , 27 // parameter H_FRONT_PORCH = 16'd210 , 28 // parameter HS_PULSE_WIDTH = 16'd20 , 29 // parameter VSYNC_NUM = 16'd720 , 30 // parameter V_BLACKING = 16'd23 , 31 // parameter V_FRONT_PORCH = 16'd22 , 32 // parameter VS_PULSE_WIDTH = 16'd10 33 34 //******** 480 x 272 LCD screen 35 ) 36 ( 37 clk , 38 reset_n , 39 //******** LCD 接口 40 ov_lcd_r , 41 ov_lcd_g , 42 ov_lcd_b , 43 o_lcd_hsync , 44 o_lcd_vsync , 45 o_lcd_dclk , 46 o_lcd_disp , 47 o_lcd_de , 48 o_lcd_pwm , 49 ov_addr , 50 //******** 51 o_rst_fifo , 52 o_lcd_de_pro , 53 iv_lcd_data 54 55 //********* 56 ); 57 58 59 input clk ; 60 input reset_n ; 61 //******** LCD 接口 62 output [7 :0] ov_lcd_r ; 63 output [7 :0] ov_lcd_g ; 64 output [7 :0] ov_lcd_b ; 65 output o_lcd_hsync ; 66 output o_lcd_vsync ; 67 output o_lcd_dclk ; 68 output o_lcd_disp ; 69 output o_lcd_de ; 70 output o_lcd_pwm ; 71 output [31 :0] ov_addr ; 72 //******** 73 output o_rst_fifo ; 74 output o_lcd_de_pro ; 75 input [31 :0] iv_lcd_data ; 76 reg o_lcd_de ; 77 reg [15 :0] count_clk ; 78 reg [7 :0] count_clkh ; 79 reg w_vsync ; 80 reg w_hsync ; 81 reg [31 :0] test_data ; 82 reg flag_run ; 83 reg [5 :0] count_vsync ; 84 reg flag_vsync ; 85 reg flag_black ; 86 reg flag_white ; 87 reg flag_1s ; 88 89 reg [15 :0] count_clk2 ; 90 reg [1 :0] hsync_dly ; 91 reg [1 :0] vsync_dly ; 92 reg [15 :0] count_hsync ; 93 reg de_signal ; 94 reg de_signal_pro ; 95 96 reg flag_r ; 97 reg flag_g ; 98 reg flag_b ; 99 100 assign o_lcd_dclk = clk ; 101 assign o_lcd_disp = 1'b1 ; 102 assign o_lcd_pwm = count_clk[15] ; 103 assign o_rst_fifo = w_vsync ; 104 assign ov_addr = 32'h3e4fff80 ; 105 106 assign ov_lcd_b = iv_lcd_data[7 :0 ] ; 107 assign ov_lcd_g = iv_lcd_data[15 :8 ] ; 108 assign ov_lcd_r = iv_lcd_data[23 :16] ; 109 110 111 //assign ov_lcd_b = flag_b ? 8'hff : 8'h0; 112 //assign ov_lcd_g = flag_g ? 8'hff : 8'h0; 113 //assign ov_lcd_r = flag_r ? 8'hff : 8'h0; 114 115 assign o_lcd_hsync = w_hsync ; 116 assign o_lcd_vsync = w_vsync ; 117 assign o_lcd_de_pro = de_signal_pro ; 118 119 always@(posedge clk or negedge reset_n) 120 if(!reset_n) 121 flag_r <= 1'b0 ; 122 else if(count_clk2 >= 16'd373 && count_clk2 <= 16'd373) 123 flag_r <= 1'b1 ; 124 else 125 flag_r <= 1'b0 ; 126 127 always@(posedge clk or negedge reset_n) 128 begin 129 if(!reset_n) 130 flag_g <= 1'b0 ; 131 else if(count_clk2 >16'd373 && count_clk2 <= 16'd613) 132 flag_g <= 1'b1 ; 133 else 134 flag_g <= 1'b0 ; 135 end 136 137 always@(posedge clk or negedge reset_n) 138 begin 139 if(!reset_n) 140 flag_b <= 1'b0 ; 141 else if(count_clk2 > 16'd613) 142 flag_b <= 1'b1 ; 143 else 144 flag_b <= 1'b0 ; 145 end 146 147 148 always@(posedge clk) 149 begin 150 hsync_dly <= {hsync_dly[0],w_hsync} ; 151 vsync_dly <= {vsync_dly[0],w_vsync} ; 152 end 153 154 always@(posedge clk or negedge reset_n) 155 begin 156 if(!reset_n) 157 count_clk <= 16'd0 ; 158 else 159 count_clk <= count_clk + 16'd1 ; 160 end 161 162 always@(posedge clk or negedge reset_n) 163 begin 164 if(~reset_n) 165 test_data <= 32'b0 ; 166 else if(vsync_dly == 2'b01 && count_vsync == 6'd20) 167 test_data <= test_data + 32'h55aa11 ; 168 else 169 test_data <= test_data ; 170 end 171 172 always@(posedge clk or negedge reset_n) 173 begin 174 if(~reset_n) 175 count_vsync <= 6'b0 ; 176 else if(vsync_dly == 2'b01) 177 count_vsync <= count_vsync + 6'b1 ; 178 else 179 count_vsync <= count_vsync ; 180 end 181 182 //******** 行内计数 183 always@(posedge clk or negedge reset_n) 184 begin 185 if(!reset_n) 186 count_clk2 <= 16'd0 ; 187 else if(count_clk2 == (HSYNC_NUM + H_BLACKING + H_FRONT_PORCH - 16'd1)) 188 count_clk2 <= 16'd0 ; 189 else 190 count_clk2 <= count_clk2 + 16'd1 ; 191 end 192 193 194 //******** 产生行信号 195 always@(posedge clk or negedge reset_n) 196 begin 197 if(!reset_n) 198 w_hsync <= 1'b0 ; 199 else if(count_clk2 == (HS_PULSE_WIDTH - 16'd1) ) 200 w_hsync <= 1'b1 ; 201 else if(count_clk2 == (HSYNC_NUM + H_BLACKING + H_FRONT_PORCH - 16'd1)) 202 w_hsync <= 1'b0 ; 203 else 204 w_hsync <= w_hsync ; 205 end 206 207 always@(posedge clk or negedge reset_n) 208 begin 209 if(!reset_n) 210 de_signal_pro <= 1'b0 ; 211 else if(count_clk2 == (H_BLACKING - 16'd2) && count_hsync >= V_BLACKING && count_hsync < (VSYNC_NUM + V_BLACKING) ) 212 de_signal_pro <= 1'b1 ; 213 else if(count_clk2 == (HSYNC_NUM + H_BLACKING - 16'd2)) 214 de_signal_pro <= 1'b0 ; 215 else 216 de_signal_pro <= de_signal_pro ; 217 end 218 219 220 always@(posedge clk or negedge reset_n) 221 begin 222 if(!reset_n) 223 o_lcd_de <= 1'b0 ; 224 else 225 o_lcd_de <= de_signal_pro ; 226 end 227 228 //******** 计数列信号 229 always@(posedge clk or negedge reset_n) 230 begin 231 if(!reset_n) 232 count_hsync <= 12'd0 ; 233 else if(count_hsync == (VSYNC_NUM + V_BLACKING + V_FRONT_PORCH)) 234 count_hsync <= 12'd0 ; 235 else if(hsync_dly == 2'b10) 236 count_hsync <= count_hsync + 12'd1 ; 237 else 238 count_hsync <= count_hsync ; 239 end 240 241 //******** 产生列信号 242 always@(posedge clk or negedge reset_n) 243 begin 244 if(!reset_n) 245 w_vsync <= 1'b0 ; 246 else if(count_hsync == (VSYNC_NUM + V_BLACKING + V_FRONT_PORCH - 16'd1) && count_clk2 == (HSYNC_NUM + H_BLACKING + H_FRONT_PORCH - 16'd2) ) 247 w_vsync <= 1'b0 ; 248 else if(count_hsync == VS_PULSE_WIDTH && count_clk2 == 16'd20 ) 249 w_vsync <= 1'b1 ; 250 else 251 w_vsync <= w_vsync ; 252 end 253 254 endmodule

 

注:转载请注明出处,否则保留追究法律责任的权利。如果觉得还有帮助的话,请记得推荐下!

 

posted @ 2018-07-04 14:00  闫若川FPGA  阅读(2748)  评论(1编辑  收藏  举报