完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
1、屏幕
使用像素:480*272的一块RGB565屏幕。 像素时钟:9Mhz 接口: lcd_bl:lcd背光 lcd_rgb[15:0]:色彩值 lcd_de:当计数器处于valid(有效)区域时应将其拉高,此时输出lcd_rgb[15:0]的值到屏幕的对应像素点上。 lcd_hs:可一直将其拉高没有影响 lcd_vs:可一直将其拉高没有影响 lcd_pclk:9M时钟 lcd_rst:lcd单独复位低电平有效 2、行场扫描时序 3、分析 1、利用ip核倍分频获得9M时钟。 2、使用子母两个计数器对驱动时钟进行计数。 3、子计数器的计数范围为0-524,所代表一个行扫描周期,满载时在下一个时钟周期清零,并使母计数器+1。 4、母计数器的计数范围为0-285,所代表一个场扫描周期,满载时在下一个时钟周期清零。 5、利用组合逻辑将子母俩个计数的计数值做范围限定,确定真正valid的范围。 6、当计数值处于真正valid的范围时,需要回传当前的坐标值,用户根据回传的坐标值设置RGB565的色彩值。 4、代码 4-1、产生9M驱动时钟 -其端口列表如下: module pll_9m ( areset,//注意:其为高电平复位 inclk0,//输入时钟 c0, //输出时钟 locked //稳定锁:当c0输出稳定时locked会从低电平变为高电平 ); 4-2、驱动部分 module lcd_driver( input lcd_clk, //lcd模块驱动时钟 input sys_rst_n, //复位信号 //下列信号与RGBLCD屏幕相连接 output lcd_hs, //LCD 行同步信号 output lcd_vs, //LCD 场同步信号 output lcd_de, //LCD 数据使能 output [15:0] lcd_rgb, //LCD RGB565颜色数据 output lcd_bl, //LCD 背光控制信号 output lcd_rst, //LCD 复位信号 output lcd_pclk, //LCD 采样时钟 //接口信号,此模块推出valid坐标值,并接收用户发来的RGB565的像素点颜色值 input [15:0] pixel_data, //像素点数据 output [10:0] pixel_xpos, //像素点横坐标 output [10:0] pixel_ypos //像素点纵坐标 ); //参数列表 parameter H_SYNC = 11‘d41; //行同步 parameter H_BACK = 11’d2; //行显示后沿 parameter H_DISP = 11‘d480; //行有效数据 parameter H_FRONT = 11’d2; //行显示前沿 parameter H_TOTAL = 11‘d525; //行扫描周期 parameter V_SYNC = 11’d10; //场同步 parameter V_BACK = 11‘d2; //场显示后沿 parameter V_DISP = 11’d272; //场有效数据 parameter V_FRONT = 11‘d2; //场显示前沿 parameter V_TOTAL = 11’d286; //场扫描周期 //子母两个计数器 reg [10:0] cnt_h; reg [10:0] cnt_v; //。。。 wire lcd_en; wire data_req; //对lcd屏幕的某些信号加以固定 assign lcd_bl = 1‘b1; assign lcd_rst = 1’b1; assign lcd_pclk = lcd_clk; assign lcd_hs = 1‘b1; assign lcd_vs = 1’b1; //当子母计数器的值处于valid范围内时,将lcd_de拉高,此时输出lcd_rgb[15:0]的值到屏幕的对应像素点上。 assign lcd_de = lcd_en; assign lcd_en = (((cnt_h 》 H_SYNC+H_BACK) && (cnt_h 《= H_SYNC+H_BACK+H_DISP)) &&((cnt_v 》 V_SYNC+V_BACK) && (cnt_v 《= V_SYNC+V_BACK+V_DISP))) ? 1‘b1 : 1’b0; //lcd_rgb[15:0]的值由用户(input)给予即为:pixel_data assign lcd_rgb = lcd_en ? pixel_data : 16‘d0; //。。。此处做一个简单的分析,lcd_de拉高,lcd_rgb[15:0]的值瞬间到达屏幕的对应像素点上。 // 我们最开始的分析是:cnt值-》产生坐标-》根据坐标确认有效范围-》再往范围里放颜色值 // 所以说我们在上面写的那个就是有效范围,由于触发器的特性,所以要提前一个时钟周期将坐标值送出,才来的及在lcd_en为1时候准确的送出颜色值 // 而一场是由很多行组成的,母计数器,要比子计数器慢。子计数器变很多次,母计数器才变一次。所以对子计数器需要提前一个时钟周期发送出坐标。 // PS:如果没懂的话也没关系,因为我也比较晕。但只要时序对,屏幕就能出现颜色然后进行simulation或者实物调试 assign data_req = (((cnt_h 》 H_SYNC+H_BACK-1’b1) && (cnt_h 《= H_SYNC+H_BACK+H_DISP-1‘b1)) //对子计数器需要提前一个时钟周期发送出坐标。 && ((cnt_v 》 V_SYNC+V_BACK) && (cnt_v 《= V_SYNC+V_BACK+V_DISP))) //母计数器不变 ? 1’b1 : 1‘b0; //当前像素点坐标 assign pixel_xpos = data_req ? (cnt_h - (H_SYNC + H_BACK - 1’b1)) : 11‘d0; assign pixel_ypos = data_req ? ((cnt_v - (V_SYNC + V_BACK - 1’b1)) - 1‘b1) : 11’d0; //这块为什么有个-1 在最下面的测试图片中可以看到解释 //行计数器对像素时钟计数(子) always @(posedge lcd_clk or negedge sys_rst_n) begin if (!sys_rst_n) cnt_h 《= 11‘d0; else begin if(cnt_h 《 H_TOTAL - 1’b1) cnt_h 《= cnt_h + 1‘b1; else cnt_h 《= 11’d0; end end //场计数器对行计数(母) always @(posedge lcd_clk or negedge sys_rst_n) begin if (!sys_rst_n) cnt_v 《= 11‘d0; else if(cnt_h == H_TOTAL - 1’b1) begin if(cnt_v 《 V_TOTAL - 1‘b1) cnt_v 《= cnt_v + 1’b1; else cnt_v 《= 11‘d0; end end endmodule 4-3、显示内容部分 module lcd_display( input lcd_clk, //lcd驱动时钟 input sys_rst_n, //复位信号 input [10:0] pixel_xpos, //像素点横坐标 input [10:0] pixel_ypos, //像素点纵坐标 output reg [15:0] pixel_data //像素点数据 ); localparam WHITE = 16’b11111_111111_11111; //RGB565 白色 localparam BLACK = 16‘b00000_000000_00000; //RGB565 黑色 localparam RED = 16’b11111_000000_00000; //RGB565 红色 localparam GREEN = 16‘b00000_111111_00000; //RGB565 绿色 localparam BLUE = 16’b00000_000000_11111; //RGB565 蓝色 localparam BROWN = 16‘h7800; //RGB565 棕色 //测试边框 always @(posedge lcd_clk or negedge sys_rst_n) begin if (!sys_rst_n) pixel_data 《= 16’hffff; else begin if(pixel_xpos == 11‘d1) pixel_data 《= GREEN; else if(pixel_xpos == 11’d480) pixel_data 《= GREEN; else if(pixel_xpos == 11‘d240) pixel_data 《= GREEN; else if(pixel_ypos == 11’d1) pixel_data 《= GREEN; else if(pixel_ypos == 11‘d272) pixel_data 《= GREEN; else if(pixel_ypos == 11’d136) pixel_data 《= GREEN; else pixel_data 《= BROWN; end end //彩条 // always @(posedge lcd_clk or negedge sys_rst_n) begin // if (!sys_rst_n) // pixel_data 《= 16‘hffff; // else begin // if((pixel_xpos 》= 1) && (pixel_xpos 《 (11’d480/5)*1)) // pixel_data 《= GREEN; // else if((pixel_xpos 》= (11‘d480/5)*1) && (pixel_xpos 《 (11’d480/5)*2)) // pixel_data 《= BLACK; // else if((pixel_xpos 》= (11‘d480/5)*2) && (pixel_xpos 《 (11’d480/5)*3)) // pixel_data 《= RED; // else if((pixel_xpos 》= (11‘d480/5)*3) && (pixel_xpos 《 (11’d480/5)*4)) // pixel_data 《= BLUE; // else // pixel_data 《= BROWN; // end // end endmodule 4-3、顶层 module lcd_rgb_colorbar( input sys_clk, input sys_rst_n, output lcd_hs, output lcd_vs, output lcd_de, output [15:0] lcd_rgb, output lcd_bl, output lcd_rst, output lcd_pclk ); wire lcd_clk_w; wire locked_w; wire rst_n_w; wire [15:0] pixel_data_w; wire [ 9:0] pixel_xpos_w; wire [ 9:0] pixel_ypos_w; //待PLL输出稳定之后,停止复位 assign rst_n_w = sys_rst_n & locked_w; pll_9m u_lcd_pll( //时钟分频模块 .inclk0 (sys_clk), .areset (~sys_rst_n), .c0 (lcd_clk_w), //lcd驱动时钟 .locked (locked_w) ); lcd_driver u_lcd_driver( //lcd驱动模块 .lcd_clk (lcd_clk_w), .sys_rst_n (rst_n_w), .lcd_hs (lcd_hs), .lcd_vs (lcd_vs), .lcd_de (lcd_de), .lcd_rgb (lcd_rgb), .lcd_bl (lcd_bl), .lcd_rst (lcd_rst), .lcd_pclk (lcd_pclk), .pixel_data (pixel_data_w), .pixel_xpos (pixel_xpos_w), .pixel_ypos (pixel_ypos_w) ); lcd_display u_lcd_display( //lcd显示模块 .lcd_clk (lcd_clk_w), .sys_rst_n (rst_n_w), .pixel_xpos (pixel_xpos_w), .pixel_ypos (pixel_ypos_w), .pixel_data (pixel_data_w) ); endmodule 5、结果 5-1 可以看到,测试中出现了列偏移(1-480)*(0~271),所以对代码进行修整 见上面代码中的这一句: 5-2 OK!(1-480)*(1~272) 6、Testbench 给予时钟激励,观察信号关系即可。 |
|
|
|
只有小组成员才能发言,加入小组>>
4514个成员聚集在这个小组
加入小组3337 浏览 0 评论
航顺(HK)联合电子发烧友推出“近距离体验高性能Cortex-M3,免费申请价值288元评估板
4266 浏览 1 评论
4292 浏览 0 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-23 18:00 , Processed in 0.741050 second(s), Total 76, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号