在实际开发中,我们会经常使用到lcd屏,lcd屏的种类有很多种,对应的使用方法也有所不同,但是,在zynq 图像传输开发中,思路大体类似,下面介绍在zynq中,使用lcd显示ov5640图像方法。
1.1 概述
总体来说,搭建lcd显示的工程架构同之前搭建ov5640 hdmi显示的工程类似,采集输入端、vdma处理、显示输出端,这里变化的是显示输出端。
测试使用模块:ov5640摄像头,lcd (rgb或hdmi接口) 屏,米联客zynq开发板。这里需要说明lcd屏的分辨率是1024x600,ov5640使用的分辨率是640x480。
测试工程:测试工程是在摄像头采集的测试工程的基础上进行修改,下面仅说明区别,其他相同的部分,这里不在赘述。
为了做对比,我分别做了rgb /hdmi 接口lcd屏的640x480、640x480_1024x600测试历程。这里使用缩放ip,将640x480分辨率图像放大到1024x600。
lcd屏
测试工程
lcd(rgb接口)
640x480
640x480_1024x600 (使用缩放ip)
lcd(hdmi接口)
640x480
640x480_1024x600 (使用缩放ip)
1.2 验证测试效果
1.2.1 rgb接口lcd屏测试
(1)640x480分辨率输入,直接输出测试
可以看到图像显示仅占据一部分界面,这是因为输出分辨率大于输入分辨率。输入图像仅占据输出图像的一部分。
1)640x480分辨率输出
(2)640x480分辨率图像输入,采集图像经过hls ip处理放大到1024x600输出。
2)1024x600分辨率输出
1.2.2 hdmi接口的lcd屏测试
(1)640x480分辨率输入,直接输出测试
可以看到图像显示仅占据一部分界面,这是因为输出分辨率大于输入分辨率。输入图像仅占据输出图像的一部分。
(2)640x480分辨率图像输入,采集图像经过hls ip处理放大到1024x600输出。
2)1024x600分辨率输出
1.3 硬件工程
1.3.1 硬件平台搭建
1、vtc设置
由于lcd屏是1024x600,对于vtc中没有现成的参数配置,因此,这里我们使用axi4总线对vtc分辨率进行配置。
生成后的ip
选择自动连线,将vtc连接到总线上。然后,如图所示连接,并将s_axi_aclken给定值1。
2、zynq 时钟设置
zynq ip 提供的fclk_clk0用于axi 数据传输的时钟,这个时钟给定值要根据数据传输情况给定,不能设置太高也不能设置太低,否则会造成数据的堵塞,不会输出。通常我这里调试,640x480输出会给100m,1080p输出会给155m(实际输出是150m)。具体参考程序。
3、缩放ip设置
ov5640的有几种分辨率(640x480、720p),而lcd屏的分辨率是1024x600;如果直接使用5640的分辨率显示,使用640x480输出,则不会铺满整个lcd屏;或者使用720p输出,则720p分辨率大于1024x600,则lcd不能显示5640采集的全部图像;因此,使用了hls封装的缩放ip,可以将输出的分辨率调整为lcd屏分辨率1024x600。
使用的硬件工程,在ov5640 vdma图像传输的基础上进行修改。将hls生成的ip添加工程中,将video in to axi4-stream的输出接口与hls ip的输入接口连接,hls ip的输出接口与vdma的axis接口连接。
4、lcd接口设置
hdmi接口:对于hdmi接口的lcd屏,video out ip后面接hdmi_fpga_ml ip,将rgb信号转换为hdmi信号输出。
rgb接口:对于rgb接口的lcd屏,video out ip信号直接输出,这个ip输出的是rgb信号,同事需要注意,对驱动lcd屏的其他信号,如时钟、使能信号进行配置。
1.3.2 sdk工程
640x480显示工程对应的main.c主函数
#include i2c_16bit.h
#include xiicps.h
#include xil_io.h
#include xparameters.h
#include vtc_config.h
#define vdma_baseaddr xpar_axi_vdma_0_baseaddr
#define video_baseaddr0 0x01000000
#define video_baseaddr1 0x02000000
#define video_baseaddr2 0x03000000
#define h_active 1024
#define v_active 600
#define h_stride 1024
xiicps iic;
u32 i=0;
#define sum 2457600 //背景写黑 1280*720*4
void main()
{
//设置内存中的背景
for(i=0;i
xil_out16((video_baseaddr0 + i), 0x00);
xil_out16((video_baseaddr1 + i), 0x00);
xil_out16((video_baseaddr2 + i), 0x00);
}
// initialize ov5640 regesiter
i2c_config_init();
// config vtc
vtc_init(&vtc, vtc_dev_id, &vtc_timing, video_resolution_wsvga);
//xil_out32((vdma_baseaddr + 0x030), 0x108b);// enable circular mode
xil_out32((vdma_baseaddr + 0x030), 0x108b);// enable circular mode
xil_out32((vdma_baseaddr + 0x0ac), video_baseaddr0); // start address
xil_out32((vdma_baseaddr + 0x0b0), video_baseaddr1); // start address
xil_out32((vdma_baseaddr + 0x0b4), video_baseaddr2); // start address
xil_out32((vdma_baseaddr + 0x0a8), (h_stride*3)); // h offset (h_stride* 3) bytes
xil_out32((vdma_baseaddr + 0x0a4), (h_active*3)); // h size (h_active * 3) bytes
xil_out32((vdma_baseaddr + 0x0a0), v_active); // v size (v_active)
/*****************从ddr读数据设置**********************/
xil_out32((vdma_baseaddr + 0x000), 0x8b); // enable circular mode
xil_out32((vdma_baseaddr + 0x05c), video_baseaddr0); // start address
xil_out32((vdma_baseaddr + 0x060), video_baseaddr1); // start address
xil_out32((vdma_baseaddr + 0x064), video_baseaddr2); // start address
xil_out32((vdma_baseaddr + 0x058), (h_stride*3)); // h offset (h_stride * 3) bytes
xil_out32((vdma_baseaddr + 0x054), (h_active*3)); // h size (h_active * 3) bytes
xil_out32((vdma_baseaddr + 0x050), v_active); // v size (v_active)
while (1) ;
}
640x480_1024x600 (使用缩放ip) 显示工程对应的main.c主函数
#include i2c_16bit.h
#include xiicps.h
#include xil_io.h
#include xparameters.h
#include vtc_config.h
#include xhls_video_scaler_top.h
#define xpar_hls_video_scaler_top_device_id xpar_hls_video_scaler_top_0_device_id
#define vdma_baseaddr xpar_axi_vdma_0_baseaddr
#define video_baseaddr0 0x01000000
#define video_baseaddr1 0x02000000
#define video_baseaddr2 0x03000000
#define h_active 1024
#define v_active 600
#define h_stride 1024
xhls_video_scaler_top xhls_video_scaler;
xiicps iic;
void xhls_video_scaler_initialize(void)
{
int status;
status=xhls_video_scaler_top_initialize(&xhls_video_scaler, xpar_hls_video_scaler_top_device_id);
if(0!=status)
{
xil_printf(xpar_hls_video_scaler failed/n);
}
}
void xhls_video_scaler_setup(u16 row,u16 col,u16 drow,u16 dcol)
{
xhls_video_scaler_top_setrows(&xhls_video_scaler,row);
xhls_video_scaler_top_setcols(&xhls_video_scaler, col);
xhls_video_scaler_top_setdrows(&xhls_video_scaler, drow);
xhls_video_scaler_top_setdcols(&xhls_video_scaler, dcol);
xhls_video_scaler_top_interruptglobaldisable(&xhls_video_scaler);
xhls_video_scaler_top_enableautorestart(&xhls_video_scaler);
xhls_video_scaler_top_start(&xhls_video_scaler);
}
void main()
{
// initialize ov5640 regesiter
i2c_config_init();
// config vtc
vtc_init(&vtc, vtc_dev_id, &vtc_timing, video_resolution_wsvga);
//initialize xhls_video_scaler ip
xhls_video_scaler_initialize();
//set input and output resolution ratio
xhls_video_scaler_setup(480,640,600,1024);
//xil_out32((vdma_baseaddr + 0x030), 0x108b);// enable circular mode
xil_out32((vdma_baseaddr + 0x030), 0x108b);// enable circular mode
xil_out32((vdma_baseaddr + 0x0ac), video_baseaddr0); // start address
xil_out32((vdma_baseaddr + 0x0b0), video_baseaddr1); // start address
xil_out32((vdma_baseaddr + 0x0b4), video_baseaddr2); // start address
xil_out32((vdma_baseaddr + 0x0a8), (h_stride*3)); // h offset (h_stride* 3) bytes
xil_out32((vdma_baseaddr + 0x0a4), (h_active*3)); // h size (h_active * 3) bytes
xil_out32((vdma_baseaddr + 0x0a0), v_active); // v size (v_active)
/*****************从ddr读数据设置**********************/
xil_out32((vdma_baseaddr + 0x000), 0x8b); // enable circular mode
xil_out32((vdma_baseaddr + 0x05c), video_baseaddr0); // start address
xil_out32((vdma_baseaddr + 0x060), video_baseaddr1); // start address
xil_out32((vdma_baseaddr + 0x064), video_baseaddr2); // start address
xil_out32((vdma_baseaddr + 0x058), (h_stride*3)); // h offset (h_stride * 3) bytes
xil_out32((vdma_baseaddr + 0x054), (h_active*3)); // h size (h_active * 3) bytes
xil_out32((vdma_baseaddr + 0x050), v_active); // v size (v_active)
while (1) ;
}
1.4 小结
实际使用中,屏的分辨率和使用方法各有差异,但是使用的思路是类似的,这里给出的是rgb、hdmi接口屏的ov5640传输显示,大家可以根据自己实际使用情况进行调整。
Imagination与飞桨合作提出“软硬一体赋能芯片设计”理念
为什么说FB收购Oculus是个错误的决定?
蚂蚁回应被约谈:成立整改工作组
安卓8.0+高通骁龙835,配置不是一般的强悍,诺基亚9搞事情!
4G蓝牙网关具备哪些功能_SKYLAB
基于ZYNQ LCD显示OV5640图像测试方法
2018年彩电市场整体延续低迷走势 激光电视却逆势高速前行
2008年中国电池行业百强企业排名揭晓
MOS场效应管的基础知识
2019年智能家居十大关键词
基于USB总线接口的微波开关控制器
太阳能光伏发电对人体有辐射吗
plc开关量输入输出模块如何选择?
新能源车的全新支付体验,物联网+无感支付
MN073漏电流测量电流钳的产品特点和应用范围
铁氟龙管是什么材料 论pfa棒铁氟龙棒应用领域的优势
WIFI可能会出卖你的行踪 安全问题需要重视
胜宏科技一专利获中国专利优秀奖成绩
NetApp在INSIGHT 2023推出唯一跨本地和公共云的统一数据存储方案,强化其存储领先地位和创新能力
小米或成首家CDR企业_IPO市值或达750亿美元