显示字符驱动
1.用字符取模软件取模
00000000; 00000000; 00000000; 00000000; 00000000; 00000000; 00000000; 00000000; 00000000; 00000000; 00000000; 0003C000; 0003C000; 0003C000; 0007E000; 0007E000; 0006E000; 0006E000; 000CF000; 000CF000; 000C7000; 000C7000; 00187800; 00187800; 00187800; 00183800; 00303C00; 00303C00; 00303C00; 00301C00; 00601E00; 00601E00; 00601E00; 00600E00; 00E00E00; 00C00F00; 00C00F00; 00FFFF00; 01FFFF00; 01800780; 01800780; 01800780; 03800780; 030003C0; 030003C0; 030003C0; 070003C0; 060001E0; 060001E0; 060001E0; 0E0001E0; 0E0001F0; 1F0001F8; 7FC00FFE; 7FC00FFE; 00000000; 00000000; 00000000; 00000000; 00000000; 00000000; 00000000; 00000000; 00000000;/*"A",0*/
调用rom
ROM是只读存储器(Read-Only Memory)的简称,是一种只能读出事先所存数据的固态半导体存储器。其特性是一旦储存资料就无法再将之改变或删除。通常用在不需经常变更资料的电子或电脑系统中,并且资料不会因为电源关闭而消失。
rom初始化文档创建
新建文本文件在前面写上:
MEMORY_INITIALIZATION_RADIX=16;(进制)
MEMORY_INITIALIZATION_VECTOR=
把文件格式调成 .coe
调用rom的IP核
在配置的第四页加载rom的初始化文件(具体配置不多说明)
上代码吧
top.v
module top(ext_clk_25m,ext_rst_n,lcd_light_en,lcd_clk,lcd_hsy,lcd_vsy,lcd_r,lcd_g,lcd_b ); input ext_clk_25m; input ext_rst_n; output lcd_light_en; output lcd_clk; output lcd_hsy; output lcd_vsy; output [4:0] lcd_r; output [5:0] lcd_g; output [4:0] lcd_b; wire [31:0] rom_db; wire [5:0] rom_ab; lcd_controller uut_lcd_controller( .clk(ext_clk_25m), .rst_n(ext_rst_n), .lcd_light_en(lcd_light_en), .lcd_clk(lcd_clk), .lcd_hsy(lcd_hsy), .lcd_vsy(lcd_vsy), .lcd_r(lcd_r), .lcd_g(lcd_g), .lcd_b(lcd_b), .rom_db(rom_db), .rom_ab(rom_ab) ); rom_controller uut_rom_controller ( .clka(ext_clk_25m), // input clka .addra(rom_ab), // input [5 : 0] addra .douta(rom_db) // output [31 : 0] douta ); endmodule
lcd_controller.v
module lcd_controller(clk,rst_n,lcd_light_en,lcd_clk,lcd_hsy,lcd_vsy,lcd_r,lcd_g,lcd_b,rom_db,rom_ab ); input clk; input rst_n; input [31:0] rom_db; output [5:0]rom_ab; output lcd_light_en; output lcd_clk; output reg lcd_hsy; output reg lcd_vsy; output [4:0] lcd_r; output [5:0] lcd_g; output [4:0] lcd_b; parameter HSY_TH=9'D408-1'D1;//周期 parameter HSY_THS=9'D30 ;//脉冲宽度 parameter HSY_THB=9'D38 ;//后沿 parameter HSY_TEP=9'D320 ;//显示周期 parameter HSY_THE=9'D68 ;//同步周期 parameter HSY_THF=9'D20 ;//前沿 parameter VSY_TV=9'D262-1'D1;//周期 parameter VSY_TVS=9'D3 ;//脉冲宽度 parameter VSY_TVB=9'D15 ;//后沿 parameter VSY_TVD=9'D240 ;//显示周期 parameter VSY_TVF=9'D4 ;//前沿 //lcd背光常开 assign lcd_light_en=1'b1; //配置驱动时钟6.25mHz reg [1:0] lcd_cnt; always@(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin lcd_cnt<=1'b0; end else begin lcd_cnt<=lcd_cnt+1'b1; end end assign lcd_clk=lcd_cnt[1]; wire dchange ={lcd_cnt==2'd2}; //X和Y轴计数器 reg[8:0] xcnt; reg[8:0] ycnt; always@(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin xcnt<=1'b0; end else if(dchange==1'b1)begin if(xcnt==HSY_TH)begin xcnt<=1'b0; end else begin xcnt<=xcnt+1'b1; end end else; end always@(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin ycnt<=1'b0; end else if(dchange&&xcnt==HSY_TH)begin if(ycnt==VSY_TV)begin ycnt<=1'b0; end else begin ycnt<=ycnt+1'b1; end end else begin ycnt<=ycnt; end end //lcd显示的有效区域 reg valid; always@(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin valid<=1'b0; end else if(ycnt>=(VSY_TVS+VSY_TVB)&&ycnt<(VSY_TVS+VSY_TVB+VSY_TVD)&& xcnt>=(HSY_THS+HSY_THB)&&xcnt<(HSY_TEP+HSY_THB+HSY_THE))begin valid<=1'b1; end else begin valid<=1'b0; end end //LCD驱动行场同步信号产生逻辑 always@(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin lcd_hsy<=1'b1; end else if(xcnt==1'b0)begin lcd_hsy<=1'b0; end else if(xcnt>=HSY_THS)begin lcd_hsy<=1'b1; end else begin lcd_hsy<=lcd_hsy; end end always@(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin lcd_vsy<=1'b1; end else if(ycnt==1'b0)begin lcd_vsy<=1'b0; end else if(ycnt>=VSY_TVS)begin lcd_vsy<=1'b1; end else begin lcd_vsy<=lcd_vsy; end end assign rom_ab = ycnt-9'd18; reg [4:0]tmp_cnt; always@(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin tmp_cnt<=1'b0; end else if(valid==1'b0)begin tmp_cnt<=1'b0; end else if(xcnt>=(HSY_THS+HSY_THB)&&xcnt<(HSY_THS+HSY_THB+6'd32)&&dchange)begin tmp_cnt<=tmp_cnt+1'b1; end end reg [15:0]lcd_db_rgb; always@(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin lcd_db_rgb<=16'd0; end else if(ycnt>=(VSY_TVS+VSY_TVB)&&ycnt<(VSY_TVS+VSY_TVB+9'd64) &&xcnt>=(HSY_THS+HSY_THB)&&xcnt<(HSY_THS+HSY_THB+6'd32))begin if(dchange)begin //数字区域 if(rom_db[tmp_cnt]==1'b1)begin lcd_db_rgb<=16'h001f; end else begin lcd_db_rgb<=16'hf800; end end else; end else begin lcd_db_rgb<=1'b0; end end assign lcd_r =valid ? lcd_db_rgb[15:11]:5'd0; assign lcd_g =valid ? lcd_db_rgb[10:5]:6'd0; assign lcd_b =valid ? lcd_db_rgb[4:0]:5'd0; endmodule
实验结果:(这里拍照的时候调了相机的亮度)