文章目录

  • 1屏幕
  • 2行场扫描时序
  • 3分析
  • 4代码
    • 4-1产生9M驱动时钟
    • 4-2驱动部分
    • 4-3显示内容部分
    • 4-3顶层
  • 5结果
    • 5-1
    • 5-2
  • 6Testbench

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 beginif(cnt_h < H_TOTAL - 1'b1)                                               cnt_h <= cnt_h + 1'b1;                               else cnt_h <= 11'd0;  endend//场计数器对行计数(母)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) beginif(cnt_v < V_TOTAL - 1'b1)                                               cnt_v <= cnt_v + 1'b1;                               else cnt_v <= 11'd0;  endendendmodule

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 beginif(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;endend//彩条//   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//   endendmodule

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)

6Testbench

给予时钟激励,观察信号关系即可。

FPGA RGB565的LCD显示屏驱动(Verilog)相关推荐

  1. 基于FPGA的LCD1602显示屏驱动

    一.LCD1602显示原理 1.引脚功能 其内部功能框图如下图所示: 一般来说,LCD1602有16条引脚,各个厂家的LCD1602可能略有不同,但基本上一样,其16个引脚功能如下: LCD1602引 ...

  2. FPGA实现LCD显示屏显示彩条

    目录 总体设计 读显示屏ID 读显示屏ID代码 时钟分频 时钟分频代码 LCD显示 lcd显示模块 LCD驱动模块 lcd驱动代码 顶层模块 顶层模块代码 总体设计 系统总体分为五个模块,分别是:rd ...

  3. 晶联讯JLX12864G-086-PC-3S LCD显示屏 C51驱动代码

    晶联讯JLX12864G-086-PC-3S LCD显示屏 C51驱动代码 //7.1.2 例程:以下为串行方式显示汉字及 ASCII 字符的例程: //液晶屏型号:JLX12864G-086-PC- ...

  4. LCD显示--Ht1621b芯片显示屏驱动

    Ht1621b芯片显示屏驱动 关于HT1621b芯片的详细信息可以参考数据手册上的内容:百度文库HT1621b中文资料 CS : 片选输入接一上拉电阻当/CS 为高电平读写HT1621的数据和命令无效 ...

  5. 基于FPGA的iic主从机驱动实现 Verilog实现iic slave和iic master

    基于FPGA的iic主从机驱动实现 Verilog实现iic slave和iic master 顶层模块实现master对slave自定义的寄存器读取 带仿真模块 ID:153069768739840 ...

  6. FPGA接口_N25Q128型号的spi flash驱动verilog代码编写

    # N25Q128型号的spi flash驱动verilog代码编写 提示:使用正点原子达芬奇pro做的小例子,由于教程中无flash的读写,因此撰写记录 文章目录 # N25Q128型号的spi f ...

  7. 关于STM32驱动LCD显示屏,程序下载后白屏、乱码需要上电复位才能恢复正常问题的解决办法

    解决方法: 在显示屏初始化前加一定延时,比如100ms,因为单片机复位时间比LCD显示屏短,可能会造成显示屏未复位完就被单片机操作的问题,如果是CUBEMX配置的工程,需要找到生成代码关于显示屏初始化 ...

  8. linux的LCD的驱动编写

    Framebuffer设备 ​ Framebuffer 翻译过来就是帧缓冲,简称 fb,因 此大家在以后的 Linux 学习中见到"Framebuffer"或者"fb&q ...

  9. 全志 Tina Linux LCD显示屏调试指南 支持MIPI DSI RGB LVDS I8080 SPI等接口,开发板支持百问网T113 D1-H哪吒 DongshanPI-D1s V853

    1 概述 编写目的 本文档将介绍sunxi 平台Display Engine 模块中LCD 的调试方法. LCD 调试方法,调试手段. LCD 驱动编写. lcd0 节点下各个属性的解释. 典型LCD ...

最新文章

  1. CentOS网络配置
  2. Android stadio 调试太掉了
  3. 怎么查交集_胃镜要不要查?
  4. 高通平台点亮LCD个人总结
  5. 从手机App到网点交互请求的日志记录
  6. 打勾显示输入的密码 --EditText与setTransformationMethod
  7. 编程挑战:字符串的完美度
  8. The Everyman's Guide to How Network Packets Are Routed Across the Web
  9. java正则匹配的坑_java正则表达式入坑指南
  10. 在开发环境中,自己搭建一个ssl环境(小例子)
  11. was连接oracle rac集群,Oracle 学习之RAC(九) 集群负载均衡及故障转移
  12. 移动网络新漏洞影响2G 以来的所有蜂窝网络
  13. Support Vector Machines
  14. 学习总结 java基础
  15. java case when多分支判断_Apache Spark之单分支CaseWhen优化为IF
  16. 文字图片灰度化matlab,采用matlab将图像灰度化的方法
  17. 免费客户旅程(Customer Journey Mapping) 示例总汇
  18. 英雄联盟服务器维护2019.4.5,lol维护公告最新时间 英雄联盟11.9版本4月29日更新内容...
  19. 数学Ⅰ基础复习(六)
  20. [TypeScript]中字符和ASCII码转换

热门文章

  1. 【bioinfo】酶切法片段化建库相比超声打断建库引入softclip使用FADE软件识别/去除
  2. 【转载】缓存策略-Cache aside旁路缓存
  3. NOI题库4.3 1526 宗教信仰
  4. PB中的像素与PBU之间的转换
  5. 点云降采样--ApproximateVoxelGrid点云降采样
  6. Stable Diffusion 用2D图片制作3D动态壁纸
  7. 如何提高(编程)学习效率的三个心得感受
  8. 一个好玩有趣的Python手绘图形库(雷达图、柱状图、折线图...)
  9. 计通智能监控管理平台V7.0通过华为官方技术认证
  10. VR全景诚邀您走进2019中国北京世界园艺博览会(可在线体验)