基于FPGA的5寸LCD显示屏的显示控制
作者:lee神
1,图像处理基础知识
数字图像处理是指将图像信号转换成数字信号并利用计算机对其进行处理的过程。图像处理最早出现于 20 世纪 50 年代,当时的电子计算机已经发展到一定水平,人们开始利用计算机来处理图形和图像信息。数字图像处理作为一门学科大约形成于 20 世纪 60 年代初期。早期的图像处理的目的是改善图像的质量,它以人为对象,以改善人的视觉效果为目的。图像处理中,输入的是质量低的图像,输出的是改善质量后的图像,常用的图像处理方法有图像增强、复原、编码、压缩等。
数字图像处理常用方法:
1 )图像变换:由于图像阵列很大,直接在空间域中进行处理,涉及计算量很大。因此,往往采用各种图像变换的方法,如傅立叶变换、沃尔什变换、离散余弦变换等间接处理技术,将空间域的处理转换为变换域处理,不仅可减少计算量,而且可获得更有效的处理(如傅立叶变换可在频域中进行数字滤波处理)。目前新兴研究的小波变换在时域和频域中都具有良好的局部化特性,它在图像处理中也有着广泛而有效的应用。
2 )图像编码压缩:图像编码压缩技术可减少描述图像的数据量(即比特数),以便节省图像传输、处理时间和减少所占用的存储器容量。压缩可以在不失真的前提下获得,也可以在允许的失真条件下进行。编码是压缩技术中最重要的方法,它在图像处理技术中是发展最早且比较成熟的技术。
3 )图像增强和复原:图像增强和复原的目的是为了提高图像的质量,如去除噪声,提高图像的清晰度等。图像增强不考虑图像降质的原因,突出图像中所感兴趣的部分。如强化图像高频分量,可使图像中物体轮廓清晰,细节明显;如强化低频分量可减少图像中噪声影响。图像复原要求对图像降质的原因有一定的了解,一般讲应根据降质过程建立“降质模型”,再采用某种滤波方法,恢复或重建原来的图像。
4 )图像分割:图像分割是数字图像处理中的关键技术之一。图像分割是将图像中有意义的特征部分提取出来,其有意义的特征有图像中的边缘、区域等,这是进一步进行图像识别、分析和理解的基础。虽然目前已研究出不少边缘提取、区域分割的方法,但还没有一种普遍适用于各种图像的有效方法。因此,对图像分割的研究还在不断深入之中,是目前图像处理中研究的热点之一。
5 )图像描述:图像描述是图像识别和理解的必要前提。作为最简单的二值图像可采用其几何特性描述物体的特性,一般图像的描述方法采用二维形状描述,它有边界描述和区域描述两类方法。对于特殊的纹理图像可采用二维纹理特征描述。随着图像处理研究的深入发展,已经开始进行三维物体描述的研究,提出了体积描述、表面描述、广义圆柱体描述等方法。
6 )图像分类(识别):图像分类(识别)属于模式识别的范畴,其主要内容是图像经过某些预处理(增强、复原、压缩)后,进行图像分割和特征提取,从而进行判决分类。图像分类常采用经典的模式识别方法,有统计模式分类和句法(结构)模式分类,近年来新发展起来的模糊模式识别和人工神经网络模式分类在图像识别中也越来越受到重视。
随着计算机技术的发展,图像处理技术已经深入到我们生活中的方方面面,其中,在娱乐休闲上的应用已经深入人心。图像处理技术在娱乐中的应用主要包括:电影特效制作、电脑电子游戏、数码相机、视频播放、数字电视等。
电影特效制作:自从 20 世纪 60 年代以来,随着电影中逐渐运用了计算机技术,一个全新的电影世界展现在人们面前,这也是一次电影的革命。越来越多的计算机制作的图像被运用到了电影作品的制作中。其视觉效果的魅力有时已经大大超过了电影故事的本身。如今,我们已经很难发现在一部电影中没有任何的计算机数码元素。
电脑电子游戏:电脑电子游戏的画面,是近年来电子游戏发展最快的部分之一。从 1996 年到现在,游戏画面的进步简直可以用突飞猛进来形容,随着图像处理技术的发展,众多在几年前无法想象的画面在今天已经成为了平平常常的东西。
数码相机:所谓数码相机,是一种能够进行拍摄,并通过内部处理把拍摄到的景物转换成以数字格式存放图像的特殊照相机。与普通相机不同,数码相机并不使用胶片,而是使用固定的或者是可拆卸的半导体存储器来保存获取的图像。数码相机可以直接连接到计算机、电视机或者打印机上。在一定条件下,数码相机还可以直接接到移动式电话机或者手持 PC 机上。由于图像是内部处理的,所以使用者可以马上检查图像是否正确,而且可以立刻打印出来或是通过电子邮件传送出去。
视频播放与数字电视:家庭影院中的 VCD , DVD 播放器和数字电视中,大量使用了视频编码解码等图像处理技术,而视频编码解码等图像处理技术的发展,也推动了视频播放与数字电视象高清晰,高画质发展。
2,LCD显示的基本原理
   <ignore_js_op>
图1 VGA的显示时序
如图1所示,LCD的显示和VGA的显示时序基本一致,都是从屏幕的左上角开始(从左往右,从上往下)经过Hor_sync_time和H_back_porch时间,屏幕开始显示,到H_front_porch时间后结束一行的显示,然后回到下一行左侧,循环到屏幕的最后一行扫描。在竖直方向上,经过 ver_sync_time和v_back_porch时间竖直方向屏幕开始显示,到ver_front_porch竖直方向显示结束。一帧显示完成。
当屏幕的刷新频率快于人眼的视觉感知的频率我们将看不出屏幕的闪烁效果。
3,FPGA实现
本实验目的:
  本节目的是让大家了解LCD屏的显示原理,以及为后期我们的FPGA的数字图像处理打下基础。
模块划分:
<ignore_js_op>
图2 TFT5寸显示屏显示FPGA模块结构
 
<ignore_js_op>
图3 综合后FPGA的内部模块以及接口
从图2和图3可知,LCD屏显示控制有Key_filter、rgb_gen以及TFT_CTRL_800_480_16bit三大模块组成。Key_filter完成按键的消抖,rgb_gen完成屏幕显示的控制,TFT_CTRL_800_480_16bit模块完成TFT5寸屏幕的驱动。
本实验通过按键来完成对屏幕颜色输出的控制。
RGB565可以完成65536种颜色的输出。
硬件平台:
TFT5寸屏幕/或VGA显示屏
FPGA开发板
FPGA源码:
Rgb_gen 模块源码
  /*
Module name:   rgb_gen.v
Description:  
              
Data:          2018/01/25
Engineer:      
e-mail:        137194782@qq.com
微信公众号:  FPGA开源工作室
QQ资料群:    664712733
*/
`timescale 1ns/1ps
module rgb_gen(
       input clk,
                 input rst_n,
                 input [3:0] key_cnt,
                 
                 output reg [15:0] rgb_data,
                 input  [11:0] hcount,
       input  [11:0] vcount
       );
        parameter TFT_HS_end=10'd1,
                                 hdat_begin=10'd46,
                                 hdat_end=10'd846,
                                 hpixel_end=12'd1056,
                                 TFT_VS_end=10'd1,
                                 vdat_begin=10'd24,
                                 vdat_end=10'd504,
                                 vline_end=10'd524;
        parameter h_8 = 10'd100;
        parameter v_8 = 10'd60;
always @(posedge clk or negedge rst_n) begin
  if(!rst_n)
    rgb_data <= 16'h0000;
  else
    case(key_cnt)
      4'd0:rgb_data <= 16'hf800;    //red
                4'd1:rgb_data <= 16'h07e0;  //green
                4'd2:rgb_data <= 16'h001f;  //blue
                4'd3:rgb_data <= 16'hf81f;  //purple
                4'd4:rgb_data <= 16'hffe0;  //yellow
                4'd5:rgb_data <= 16'h07ff;  //cyan
                4'd6:rgb_data <= 16'hfc00;  //orange
                4'd7:rgb_data <= 16'hffff;   //white
                4'd8:rgb_data <= 16'h0000;  //black
                4'd9:begin
                  if((hcount[3] == 1'b1) ^ (vcount[3] == 1'b1))
                    rgb_data <= 16'hffff;
                  else
                    rgb_data <= 16'h0000;               //Lattices image 1
                end
                4'd10:begin
                  if((hcount[6] == 1'b1) ^ (vcount[6] == 1'b1))
                    rgb_data <= 16'hffff;
                  else
                    rgb_data <= 16'h0000;               //Lattices image 2
                end
                4'd11:begin
                  if(hcount == hdat_begin)
                    rgb_data <= 16'hf800;
                  else if(hcount == hdat_begin + h_8)
                    rgb_data <= 16'h07e0;
                  else if(hcount == hdat_begin + h_8*2)
                    rgb_data <= 16'h001f;
                  else if(hcount == hdat_begin + h_8*3)
                    rgb_data <= 16'hf81f;
                  else if(hcount == hdat_begin + h_8*4)
                    rgb_data <= 16'hffe0;
                  else if(hcount == hdat_begin + h_8*5)
                    rgb_data <= 16'h07ff;
                  else if(hcount == hdat_begin + h_8*6)  //color bar h
                    rgb_data <= 16'hfc00;
                  else if(hcount == hdat_begin + h_8*7)
                    rgb_data <= 16'hffff;
                  else
                    rgb_data <= rgb_data;
                end
                4'd12:begin
                  if(vcount == vdat_begin)
                    rgb_data <= 16'hf800;
                  else if(vcount == vdat_begin + v_8)
                    rgb_data <= 16'h07e0;
                  else if(vcount == vdat_begin + v_8*2)
                    rgb_data <= 16'h001f;
                  else if(vcount == vdat_begin + v_8*3)
                    rgb_data <= 16'hf81f;
                  else if(vcount == vdat_begin + v_8*4) //color bar v
                    rgb_data <= 16'hffe0;
                  else if(vcount == vdat_begin + v_8*5)
                    rgb_data <= 16'h07ff;
                  else if(vcount == vdat_begin + v_8*6)
                    rgb_data <= 16'hfc00;
                  else if(vcount == vdat_begin + v_8*7)
                    rgb_data <= 16'hffff;
                  else
                    rgb_data <= rgb_data;
                end
                4'd13:begin
                   rgb_data <= {5'b0,vcount[8:3],5'b0};  //Horizontal green gradual change
                end
                4'd14:begin
                   rgb_data <= {vcount[8:4],vcount[8:3],vcount[8:4]}; //vertical gray Gradient
                end
                4'd15:begin
                   rgb_data <= {hcount[8:4],11'b0};  //Horizontal red gradual change
                end
         endcase
end
 
endmodule
 
TFT_CTRL_800_480_16bit模块源码:
module TFT_CTRL_800_480_16bit(
        Clk33M,        //系统输入时钟33MHZ
        Rst_n,        //复位输入,低电平复位
        data_in,        //待显示数据
        hcount,                //TFT行扫描计数器
        vcount,                //TFT场扫描计数器
        TFT_RGB,        //TFT数据输出
        TFT_HS,                //TFT行同步信号
        TFT_VS,                //TFT场同步信号
        TFT_BLANK,
        TFT_VCLK,
        TFT_DE
);
                       
        //----------------模块输入端口----------------
        input  Clk33M;          //系统输入时钟33MHZ
        input  Rst_n;
        input  [15:0]data_in;     //待显示数据
 
        //----------------模块输出端口----------------
        output [11:0]hcount;
        output [11:0]vcount;
        output [15:0]TFT_RGB;  //TFT数据输出
        output TFT_HS;           //TFT行同步信号
        output TFT_VS;           //TFT场同步信号
        output TFT_BLANK;
        output TFT_DE;
        output TFT_VCLK;
 
        //----------------内部寄存器定义----------------
        reg [11:0] hcount_r;     //TFT行扫描计数器
        reg [11:0] vcount_r;     //TFT场扫描计数器
        //----------------内部连线定义----------------
        wire hcount_ov;
        wire vcount_ov;
        wire TFT_DE;//有效显示区标定
 
        //TFT行、场扫描时序参数表
        parameter TFT_HS_end=10'd1,
                                 hdat_begin=10'd46,
                                 hdat_end=10'd846,
                                 hpixel_end=12'd1056,
                                 TFT_VS_end=10'd1,
                                 vdat_begin=10'd24,
                                 vdat_end=10'd504,
                                 vline_end=10'd524;
        assign hcount=hcount_r;
        assign vcount=vcount_r;
       
        assign TFT_BLANK = Rst_n;
        assign TFT_VCLK = Clk33M;
 
        //**********************TFT驱动部分**********************
        //行扫描
        always@(posedge Clk33M or negedge Rst_n)
        if(!Rst_n)
                hcount_r<=12'd0;
        else if(hcount_ov)
                hcount_r<=12'd0;
        else
                hcount_r<=hcount_r+12'd1;
 
        assign hcount_ov=(hcount_r==hpixel_end);
 
        //场扫描
        always@(posedge Clk33M or negedge Rst_n)
        if(!Rst_n)
                vcount_r<=12'd0;
        else if(hcount_ov) begin
                if(vcount_ov)
                        vcount_r<=12'd0;
                else
                        vcount_r<=vcount_r+12'd1;
        end
        else
                vcount_r<=vcount_r;
               
        assign         vcount_ov=(vcount_r==vline_end);
 
        //数据、同步信号输出
        assign TFT_DE=((hcount_r>=hdat_begin)&&(hcount_r<hdat_end))
                                        &&((vcount_r>=vdat_begin)&&(vcount_r<vdat_end));
                                       
        assign TFT_HS=(hcount_r>TFT_HS_end);
        assign TFT_VS=(vcount_r>TFT_VS_end);
        assign TFT_RGB=(TFT_DE)?data_in:16'h000000;
               
endmodule
实验结果:
<ignore_js_op>
Red
<ignore_js_op>
Green
<ignore_js_op>
Blue
<ignore_js_op>
Color_bar_h
<ignore_js_op>
Lattices image 1
 
  最后欢迎大家关注我的微信公众号FPGA开源工作室。
<ignore_js_op>

转载:http://www.openhw.org/module/forum/thread-658800-1-1.html

基于FPGA的5寸LCD显示屏的显示控制的更多相关文章

  1. verilog实验1:基于FPGA蜂鸣器演奏乐曲并数码管显示

    一.实验任务 利用FPGA进行代码开发,使蜂鸣器演奏出乐曲<生日快乐>,将音调显示在数码管.原理为蜂鸣器为交流源蜂鸣器,在引脚上加一定频率的方波就可以发声,而且发声的频率由所加方波决定.这 ...

  2. 基于FPGA的数字秒表(数码管显示模块和按键消抖)实现

    本文主要是学习按键消抖和数码管动态显示,秒表显示什么的,个人认为,拿FPGA做秒表真是嫌钱多. 感谢 感谢学校和至芯科技,笔者专业最近去北京至芯科技培训交流了一周.老师的经验还是可以的,优化了自己的代 ...

  3. 基于FPGA的图像显示

    基于FPGA的图像显示 作者:lee神 这几天一直在调试FPGA的图像显示系统,今天终于成功,图像不在闪烁,也不再边框缺失. 基于FPGA的图像处理的第一课应该是基于FPGA的图像显示,只有图像正常显 ...

  4. 基于FPGA的VGA显示实验设计

    基于FPGA的VGA显示实验设计 成果展示(优酷视频): 视频: 基于FPGA的VGA显示技术(手机控制) http://v.youku.com/v_show/id_XNjk4ODE3ODUy.htm ...

  5. 基于FPGA的LCD+CMOS视频采集显示使用小结

    基于FPGA的LCD+CMOS视频采集显示 液晶显示器采用扫描模式,RGB888 电源采用:+5V供电 usb供电有时候会出现供电不足的问题 显示器接口有两种选择:16bit或24bit  分别对应 ...

  6. 基于FPGA的OLED真彩色动态图像显示的实现

    源:基于FPGA的OLED真彩色动态图像显示的实现 作为第3代显示器,有机电致发光器件(Organic Light Emitting Diode,OLED)由于其主动发光.响应快.高亮度.全视角.直流 ...

  7. 基于FPGA的数字识别的实现

    欢迎大家关注我的微信公众号:FPGA开源工作室     基于FPGA的数字识别的实现二 作者:lee神 1 背景知识 1.1基于FPGA的数字识别的方法 通常,针对印刷体数字识别使用的算法有:基于模版 ...

  8. 基于FPGA摄像头图像采集显示系统

    本系统主要由FPGA主控模块.图像采集模块.图像存储模块以及图像显示模块等模块组成.其中图像采集模块选择OV7670摄像头模块,完成对视频图像的采集和解码功能,并以RGB565标准输出RGB 5:6: ...

  9. [stm32] 一个简单的stm32vet6驱动的天马4线SPI-1.77寸LCD彩屏DEMO

    书接上文<1.一个简单的nRF51822驱动的天马4线SPI-1.77寸LCD彩屏DEMO> 我们发现用16MHz晶振的nRF51822驱动1.77寸的spi速度达不到要求 本节主要采用7 ...

随机推荐

  1. Java开发中所遇问题积累

    1.判断两个字符串是否相等时,如下,使用" == "无效: String name = "Jack"; if(name.equals("Jack&qu ...

  2. 把mysql数据库生成数据字典,直接可用

    便于查看数据库表.字段,做一个数据字典是很有必要的,下面只需要简单更改下配置就可以用了,样式也是挺好的. <?php header('content-type:text/html;charset ...

  3. PyQt5教程——菜单和工具栏(3)

    PyQt5中的菜单和工具栏 在这部分的PyQt5教程中,我们将创建菜单和工具栏.菜单式位于菜单栏的一组命令操作.工具栏是应用窗体中由按钮和一些常规命令操作组成的组件. 主窗口 QMainWindow类 ...

  4. SpringMVC的入门例子

    MVC框架是什么 模型-视图-控制器(MVC)是一个众所周知的以设计界面应用程序为基础的设计模式.它主要通过分离模型.视图及控制器在应用程序中的角色将业务逻辑从界面中解耦.通常,模型负责封装应用程序数 ...

  5. CSDN开源夏令营 基于Compiz的switcher插件设计与实现之compiz特效插件介绍及特效实现

    compiz自带的特效插件不够多,也不够强大.为了更好的体验compiz的特效,我们能够安装特效插件,在终端输入命令:sudo apt-get install compiz-plugins就能够下载特 ...

  6. openerp用wizard导入excel数据

    来自:http://blog.csdn.net/yumingbuzhongyao/article/details/18669183 作为一个quick note吧. OE里的csv导入数据功能形同摆设 ...

  7. POJ 1163 The Triangle DP题解

    寻找路径,动态规划法题解. 本题和Leetcode的triangle题目几乎相同一样的,本题要求的是找到最大路径和. 逆向思维.从底往上查找起就能够了. 由于从上往下能够扩展到非常多路径.而从下往上个 ...

  8. c#委托是什么?事件是不是一种委托?

    C#的委托是CTS(公共类型系统)规定的5中类型之一(类类型.结构类型.接口类型.枚举类型.委托类型).它类似于c或c++中的函数的指针,但函数指针只能引用静态方法,而委托既能引用静态方法,也能引用实 ...

  9. 插入UUID,出现Data truncation: Data too long for column 'id' at row 1

    ssc.udf.register("getuuid", () => UUID.randomUUID().toString) val stuPCountDF_tmp1=ssc. ...

  10. 在阿里云上进行Docker集群的自动弹性伸缩

    摘要: 在刚刚结束的云栖大会上,阿里云容器服务演示了容器的自动弹性伸缩,能够从容应对互联网应用的峰值流量.阿里云容器服务不仅支持容器级别的自动弹性伸缩,也支持集群节点级别的自动弹性伸缩.从而真正做到从 ...