马上注册,看完整文章,学更多FPGA知识。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
至简设计系列_上位机控制LCD显示放大和缩小图片
--作者:肖肖肖
本文为明德扬原创及录用文章,转载请注明出处! 1.1 总体设计1.1.1 概述液晶显示器是一-种通过液晶和色彩过滤器过滤光源,在平面面板上产生图像的数字显示器。LCD 的构造是在两片平行的玻璃基板当中放置液晶盒,下基板玻璃上设置薄膜晶体管,.上基板玻璃上设置彩色滤光片,通过薄膜晶体管上的信号与电压改变来控制液晶分子的转动方向,从而达到控制每个像素点偏振光出射与否而达到显示目的。与传统的阴极射线管相比,LCD具有占用空间小,低功耗,低辐射,无闪烁,降低视觉疲劳等优点。现在LCD已渐替代CRT成为主流,价格也已经下降了很多,并已充分的普及。
1.1.2 设计目标
1. 在7寸LCD显示屏上实现明德扬LOGO图标的左上角显示和大写字母“E”图片的居中显示; 2. 可以选择使用上位机还是按键来控制“E”图片的放大和缩小; 3. 并且统计1秒时间图像的帧率。
1.1.3 系统结构框图系统结构框图如下所示: 图一 1.1.4模块功能
以下本工程所用到的所有模块中,除了PicZoomInAndOut模块都是明德扬提供的可用的IP模块,这些模块不允许修改避免调用IP模块使用时出现问题。
mdyPllAltera模块实现功能1. 将输入的50MHz时钟分频输出40MHz的时钟。
mdyRom模块实现功能1. 存储明德扬LOGO图标数据; 2. 存储大小字母“E”图像数据。
mdyCfg模块实现功能top_uart_cfg 1. 对接收的数据进行串并转换; 2. 对发送的数据进行并串转换。 mdyCfgCtrl 1. 对传输的指令进行解析。
mdyKey模块实现功能1. 检测按下的按键并输出对应按键有效的数值。
PicZoomInAndOut模块实现功能1. 规定了明德扬LOGO图标和大写字母“E”显示的区域; 2. 控制大写字母“E”显示的放大和缩小。
mdyLcd驱动模块实现功能1、 产生驱动LCD屏显示的时序。
mdyGetEdge模块实现功能1. 对信号的边沿进行检测。
mdyStatic_1S模块实现功能1. 统计一段时间内的某些信号的数据。
1.1.5顶层信号 信号名 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | LCD RGB信号,RGB格式为使用24位来表示一个像素,RGB分量都用8位表示,取值范围为0-255。 | | | | |
1.1.6参考代码- module top_mdyLcdPicZoomInAndOut(
- clk ,
- rst_n ,
- key ,
- uart_rxd ,
-
- uart_txd ,
- lcd_hs ,
- lcd_vs ,
- lcd_de ,
- lcd_dat ,
- lcd_clk
- );
- parameter PICTURE_W = 24 ;
- parameter KEY_W = 4 ;
- input clk ;//50MHz
- input rst_n ;
- input [KEY_W-1 :0] key ;
- input uart_rxd ;
-
- output uart_txd ;
- output lcd_hs ;
- output lcd_vs ;
- output lcd_de ;
- output [PICTURE_W-1:0] lcd_dat ;
- output lcd_clk ;
- wire uart_txd ;
- wire lcd_hs ;
- wire lcd_vs ;
- wire lcd_de ;
- wire [PICTURE_W-1:0] lcd_dat ;
- wire lcd_clk ;
- wire clk_0 ;
- wire [23:0] pic_data ;
- wire [10:0] req_x ;
- wire [ 9:0] req_y ;
- wire frame_start ;
- wire [KEY_W-1:0] key_vld ;
- wire frame_pos ;
- wire [63:0] uart_dout ;
- wire uart_dout_vld ;
- wire [63:0] cfgCtrl_dout ;
- wire cfgCtrl_dout_vld ;
- `include "mdyCfg_wire.v"
- /****************** PLL模块 *******************************/
- mdyPllAltera#(.C0_M(4),.C0_D(5)) u1_pll_40m(
- .areset (~rst_n ), //高电平有效
- .inclk0 (clk ),
- .c0 (clk_0 ),
- .c1 ( ),
- .c2 ( ),
- .c3 ( ),
- .c4 ( ),
- .locked ( )
- );
- /****************** LCD驱动模块 *******************************/
- mdyLcd#(.D_DLY(1)) u2_lcd_driver(
- .clk (clk_0 ),//40MHz
- .rst_n (rst_n ),
- .ack_data (pic_data ),
-
- .req_x (req_x ),
- .req_y (req_y ),
- .req_en ( ),
- .req_addr ( ),
-
- .hys (lcd_hs ),
- .vys (lcd_vs ),
- .lcd_de (lcd_de ),
- .lcd_rgb (lcd_dat ),
- .lcd_dclk (lcd_clk ),
-
- .frame_start (frame_start )
- );
- /****************** 功能模块 *******************************/
- PicZoomInAnDout u3_PicZoomInAnDout(
- .clk (clk_0 ),
- .rst_n (rst_n ),
- .mode (MODE_SELECT_en),
- .key_en (key_vld ),
- .cpu_ZoomIn (SOFTWARE_CTRL_in),
- .cpu_ZoomOut (SOFTWARE_CTRL_out),
- .req_h (req_x ),
- .req_v (req_y ),
- .pic_data (pic_data )
-
- );
- /********************* 按键模块 ****************************/
- mdyKey#(.DATA_W(24),.TIME_20MS(8_00_000)) u4_mdykey(
- .clk (clk_0 ),
- .rst_n (rst_n ),
- .key_in (key ),
- .key_vld (key_vld )
- );
- /********************* 边沿检测模块 ****************************/
- mdyGetEdge u5_GetEdge(
- .clk (clk_0 ),
- .rst_n (rst_n ),
- .cfg_init_value (0 ),
- .din (frame_start ),
- .dout_pos (frame_pos),
- .dout_neg ( ),
- .dout_pos_reg ( ),
- .dout_neg_reg ( )
- );
- /********************* 1s统计模块 ****************************/
- mdyStatic_1S u6_Static_1S(
- .clk (clk_0 ),
- .rst_n (rst_n ),
- .cfg_num_1s (50_000_000 ),
- .cfg_add_1s (1 ),
- .din_vld (frame_pos ),
- .sta_1s (DATA_FRAME_data ),//32bit
- .sta_rt ( )
- );
- /********************* 指令模块 ****************************/
- top_uart_cfg#(.BPS(4167)) u7_top_uart_cfg(
- .clk (clk_0 ),
- .rst_n (rst_n ),
- .cfg_head (16'h55d5 ),
- .rx (uart_rxd ),
- .tx (uart_txd ),
- .din (cfgCtrl_dout ),//s2p
- .din_vld (cfgCtrl_dout_vld ),
- .din_rdy ( ),
- .dout (uart_dout ),//p2s
- .dout_vld (uart_dout_vld )
- );
- mdyCfgCtrl u8_mdyCfgCtrl(
- `include "mdyCfg_inst.v"
- .clk (clk_0 ),
- .rst_n (rst_n ),
- .din (uart_dout ),
- .din_vld (uart_dout_vld ),
- .dout (cfgCtrl_dout ),
- .dout_vld (cfgCtrl_dout_vld )
- );
- /*************************************************/
- endmodule
复制代码
1.2 mdyPllAltera模块接口说明
1.2.1接口信号
1.2.2 使用说明本模块主要用于产生LCD驱动时序所需要的时钟,关于mdyPllAltera模块的使用详细介绍请看下方链接:
1.3 mdyRom模块设计
1.3.1接口信号
1.3.2设计思路本模块主要用于存储明德扬LOGO图标和大小字母“E”图像的数据,关于mdyRom模块的使用详细介绍请看下方链接:
1.4 mdyCfg模块接口说明
1.4.1接口信号
top_uart_cfg模块的接口信号:
mdyCfgCtrl模块的接口信号:
信号名 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 对图片的放大和缩小控制模式选择,复位值为0,表示按键控制;1,表示上位机控制。 | | | | | | | | |
1.4.2 使用说明本模块主要用于对传输的数据进行串并转换和解析传输的指令,关于mdyCfg模块的使用详细介绍请看下方链接: 关于具体的指令信息可以查看工程里的XML表格regTable_mdyLcdPicZoomInAndOut.xml: 上位机指令全长64bit,其中,
1.5 mdyKey模块接口说明
1.5.1接口信号
下面为使用独立按键时的接口信号: 信号名 | | | | | | | | | | | | | | | | | | | 按键有效指示信号,4’b0001表示按键S1按下,控制放大,4’b0010表示按键S2按下,控制缩小。 |
1.5.2使用说明本模块主要检测按下的按键并输出对应按键的有效指示信号,关于mdyKey模块的使用详细介绍请看下方链接:
1.6 PicZoomInAndOut模块接口说明
1.6.1接口信号
信号名 | | | | | | | | | | | | | | | 对图片的放大和缩小控制模式选择,复位值为0,表示按键控制;1,表示上位机控制。 | | | | 按键有效指示信号,4’b0001表示按键S1按下,控制放大,4’b0010表示按键S2按下,控制缩小。 | | | | | | | | | | | | | | | | | | | | |
1.6.2参考代码- module PicZoomInAnDout(
- clk ,
- rst_n ,
- mode ,
- key_en ,
- cpu_ZoomIn ,
- cpu_ZoomOut ,
-
- req_h ,//h_cnt - THB
- req_v ,//v_cnt - TVB
- pic_data
- );
- //LCD显示屏居中
- parameter HDE_CENTRE = 400 ;//800/2
- parameter VDE_CENTRE = 240 ;//480/2
- parameter DATA_W = 8;
- parameter KEY_W = 4;
- //输入信号定义
- input clk ;
- input rst_n ;
- input mode ;
- input cpu_ZoomIn ;
- input cpu_ZoomOut ;
- input [KEY_W-1 :0] key_en ;
- //输出信号定义
- input [10:0] req_h ;
- input [ 9:0] req_v ;
- output [23:0] pic_data ;
- //输出信号reg定义
- reg [23:0] pic_data ;
-
- //中间信号
- reg [15:0] logo_rom_addr ;
- reg logo_rom_area ;
- wire [7:0] logo_rom_data ;
- reg [17:0] e_rom_addr ;
- reg e_rom_area ;
- reg [2:0] e_rom_addr_low ;
- reg e_dataout ;
- wire [7:0] e_rom_data ;
-
- reg [ 2:0] size ;
- reg [ 2:0] size_ff0 ;
- wire [9:0] len_size ;
- wire [9:0] wid_size ;
- wire [9:0] e_x0 ;
- wire [9:0] e_x1 ;
- wire [9:0] e_y0 ;
- wire [9:0] e_y1 ;
- wire [9:0] x ;
- wire [9:0] y ;
- /******************************************************/
- always @(posedge clk or negedge rst_n)begin
- if(rst_n==1'b0)begin
- size <= 0;
- end
- else if(mode==1)begin
- if(cpu_ZoomOut)begin
- if(size!=3)
- size <= size + 1;
- end
- else if(cpu_ZoomIn)begin
- if(size!=0)
- size <= size - 1;
- end
- end
- else if(mode==0)begin
- if(key_en==4'b0010)begin
- if(size!=3)
- size <= size + 1;
- end
- else if(key_en==4'b0001)begin
- if(size!=0)
- size <= size - 1;
- end
- end
- end
- always @(posedge clk or negedge rst_n)begin
- if(rst_n==1'b0)begin
- size_ff0 <= 0;
- end
- else if(req_h==(HDE_CENTRE-200) && req_v==(VDE_CENTRE-150)) begin
- size_ff0 <= size;
- end
- end
- assign len_size = 400 >> size_ff0;//缩小多少倍
- assign wid_size = 300 >> size_ff0;
- assign e_x0 = (HDE_CENTRE-len_size[9:1]);
- assign e_x1 = (HDE_CENTRE+len_size[9:1]);
- assign e_y0 = (VDE_CENTRE-wid_size[9:1]);
- assign e_y1 = (VDE_CENTRE+wid_size[9:1]);
- assign x = (req_h-e_x0)<<size;
- assign y = (req_v-e_y0)<<size;
- always @(*)begin
- e_rom_area = req_h >=(e_x0+5) && req_h < e_x1 && req_v >= e_y0 && req_v < (e_y1+5);
- end
- always @(*)begin
- e_rom_addr = x + 400*y;
- end
- /******************************************************/
-
- //120*55
- always @(*)begin
- logo_rom_area = req_h >=0 && req_h < 119 && req_v >= 0 && req_v < 54;
- end
- always @(*)begin
- logo_rom_addr = req_h + 120*req_v;
- end
- /******************************************************/
- always @(posedge clk or negedge rst_n)begin
- if(rst_n==1'b0)begin
- e_rom_addr_low <= 0;
- end
- else begin
- e_rom_addr_low <= e_rom_addr[2:0];
- end
- end
- always @(*)begin
- if(e_rom_area)
- e_dataout = ~e_rom_data[7-e_rom_addr_low];
- else
- e_dataout = 1;
- end
- always @(posedge clk or negedge rst_n)begin
- if(rst_n==1'b0)begin
- pic_data <= 0;
- end
- else if(e_rom_area)begin
- pic_data <= {24{e_dataout}};
- end
- else if(logo_rom_area)begin
- pic_data <= {logo_rom_data[7:5],5'b11111,logo_rom_data[4:2],5'b11111,logo_rom_data[1:0],6'b111111} ;
- end
- end
- /******************************************************/
- mdyRom#(.MIF("../src/data/logo.mif"),.DEP(8192),.D_W(8)) u_fpga_rom(
- .address (logo_rom_addr ),
- .clock (clk ),
- .q (logo_rom_data )
- );
- mdyRom#(.MIF("../src/data/e.mif"),.DEP(16384),.D_W(8)) u_e_rom(
- .address (e_rom_addr[16:3] ),
- .clock (clk ),
- .q (e_rom_data )
- );
- endmodule
复制代码
1.7 mdyLcd驱动模块设计1.7.1接口信号 信号名 | | | | | | | | | | | | | | | | | | | 输出的LCD显示屏有效显示区域每一行某一像素点指示信号 | | | | | | | | | | | | | | | | | | | | | | | | LCD RGB信号,RGB格式为使用24位来表示一个像素,RGB分量都用8位表示,取值范围为0-255。 | | | | |
1.7.1使用说明本模块主要用于产生LCD显示屏的驱动时序,关于mdyLcd模块的使用详细介绍请看下方链接:
1.8 mdyGetEdge模块接口说明
1.8.1接口信号
1.8.2使用说明本模块主要用于检测特定信号的边沿,关于mdyGetEdge模块的使用详细介绍请看下方链接:
1.9 mdyStatic_1S模块接口说明
1.9.1接口信号
1.9.2使用说明本模块主要用于统计数据,关于mdyStatic_1S模块的使用详细介绍请看下方链接:
1.10 效果和总结
以下为工程上板后的现象效果图: mp801开发板——缩小0倍
mp801开发板——缩小1倍
mp801开发板——缩小2倍
mp801开发板——缩小3倍
感兴趣的朋友也可以访问明德扬论坛(http://www.fpgabbs.cn/)进行FPGA相关工程设计学习,也可以看一下我们往期的文章:
1.11 公司简介明德扬是一家专注于FPGA领域的专业性公司,公司主要业务包括开发板、教育培训、项目承接、人才服务等多个方向。点拨开发板——学习FPGA的入门之选。
MP801开发板——千兆网、ADDA、大容量SDRAM等,学习和项目需求一步到位。网络培训班——不管时间和空间,明德扬随时在你身边,助你快速学习FPGA。周末培训班——明天的你会感激现在的努力进取,升职加薪明德扬来助你。就业培训班——七大企业级项目实训,获得丰富的项目经验,高薪就业。专题课程——高手修炼课:提升设计能力;实用调试技巧课:提升定位和解决问题能力;FIFO架构设计课:助你快速成为架构设计师;时序约束、数字信号处理、PCIE、综合项目实践课等你来选。项目承接——承接企业FPGA研发项目。人才服务——提供人才推荐、人才代培、人才派遣等服务。
【设计教程下载】
至简设计系列_LCD显示放大和缩小图片.pdf
(1.17 MB, 下载次数: 896)
|