在實(shí)際開發(fā)中,我們會(huì)經(jīng)常使用到LCD屏,LCD屏的種類有很多種,對(duì)應(yīng)的使用方法也有所不同,但是,在ZYNQ 圖像傳輸開發(fā)中,思路大體類似,下面介紹在ZYNQ中,使用LCD顯示OV5640圖像方法。
1.1 概述
總體來說,搭建LCD顯示的工程架構(gòu)同之前搭建OV5640 HDMI顯示的工程類似,采集輸入端、VDMA處理、顯示輸出端,這里變化的是顯示輸出端。
測試使用模塊:OV5640攝像頭,LCD (RGB或HDMI接口) 屏,米聯(lián)客ZYNQ開發(fā)板。這里需要說明LCD屏的分辨率是1024x600,OV5640使用的分辨率是640X480。
測試工程:測試工程是在攝像頭采集的測試工程的基礎(chǔ)上進(jìn)行修改,下面僅說明區(qū)別,其他相同的部分,這里不在贅述。
為了做對(duì)比,我分別做了RGB /HDMI 接口LCD屏的640x480、640x480_1024x600測試歷程。這里使用縮放IP,將640x480分辨率圖像放大到1024x600。
| LCD屏 | 測試工程 |
| LCD(RGB接口) | 640x480 |
| 640x480_1024x600 (使用縮放ip) | |
| LCD(HDMI接口) | 640x480 |
| 640x480_1024x600 (使用縮放ip) |
1.2 驗(yàn)證測試效果
1.2.1 RGB接口LCD屏測試
(1)640X480分辨率輸入,直接輸出測試
可以看到圖像顯示僅占據(jù)一部分界面,這是因?yàn)檩敵龇直媛蚀笥谳斎敕直媛?。輸入圖像僅占據(jù)輸出圖像的一部分。
1)640x480分辨率輸出
(2)640x480分辨率圖像輸入,采集圖像經(jīng)過HLS IP處理放大到1024x600輸出。
2)1024x600分辨率輸出
1.2.2 HDMI接口的LCD屏測試
(1)640X480分辨率輸入,直接輸出測試
可以看到圖像顯示僅占據(jù)一部分界面,這是因?yàn)檩敵龇直媛蚀笥谳斎敕直媛省]斎雸D像僅占據(jù)輸出圖像的一部分。
(2)640x480分辨率圖像輸入,采集圖像經(jīng)過HLS IP處理放大到1024x600輸出。
2)1024x600分辨率輸出
1.3 硬件工程
1.3.1 硬件平臺(tái)搭建
1、VTC設(shè)置
由于LCD屏是1024x600,對(duì)于VTC中沒有現(xiàn)成的參數(shù)配置,因此,這里我們使用AXI4總線對(duì)VTC分辨率進(jìn)行配置。

生成后的IP

選擇自動(dòng)連線,將VTC連接到總線上。然后,如圖所示連接,并將s_axi_aclken給定值1。


2、ZYNQ 時(shí)鐘設(shè)置
ZYNQ IP 提供的FCLK_CLK0用于AXI 數(shù)據(jù)傳輸?shù)臅r(shí)鐘,這個(gè)時(shí)鐘給定值要根據(jù)數(shù)據(jù)傳輸情況給定,不能設(shè)置太高也不能設(shè)置太低,否則會(huì)造成數(shù)據(jù)的堵塞,不會(huì)輸出。通常我這里調(diào)試,640X480輸出會(huì)給100M,1080P輸出會(huì)給155M(實(shí)際輸出是150M)。具體參考程序。

3、縮放IP設(shè)置
OV5640的有幾種分辨率(640x480、720P),而LCD屏的分辨率是1024x600;如果直接使用5640的分辨率顯示,使用640X480輸出,則不會(huì)鋪滿整個(gè)LCD屏;或者使用720P輸出,則720P分辨率大于1024x600,則LCD不能顯示5640采集的全部圖像;因此,使用了hls封裝的縮放IP,可以將輸出的分辨率調(diào)整為LCD屏分辨率1024x600。
使用的硬件工程,在OV5640 VDMA圖像傳輸?shù)幕A(chǔ)上進(jìn)行修改。將HLS生成的IP添加工程中,將Video In to AXI4-Stream的輸出接口與HLS IP的輸入接口連接,HLS IP的輸出接口與VDMA的AXIS接口連接。

4、LCD接口設(shè)置
HDMI接口:對(duì)于HDMI接口的LCD屏,Video Out IP后面接HDMI_FPGA_ML IP,將RGB信號(hào)轉(zhuǎn)換為HDMI信號(hào)輸出。

RGB接口:對(duì)于RGB接口的LCD屏,Video Out IP信號(hào)直接輸出,這個(gè)IP輸出的是RGB信號(hào),同事需要注意,對(duì)驅(qū)動(dòng)LCD屏的其他信號(hào),如時(shí)鐘、使能信號(hào)進(jìn)行配置。

1.3.2 SDK工程
640x480顯示工程對(duì)應(yīng)的main.c主函數(shù)
#include "I2C_16bit.h"
#include "xiicps.h"
#include "xil_io.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()
{
//設(shè)置內(nèi)存中的背景
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讀數(shù)據(jù)設(shè)置**********************/
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) 顯示工程對(duì)應(yīng)的main.c主函數(shù)
#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讀數(shù)據(jù)設(shè)置**********************/
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 小結(jié)
實(shí)際使用中,屏的分辨率和使用方法各有差異,但是使用的思路是類似的,這里給出的是RGB、HDMI接口屏的OV5640傳輸顯示,大家可以根據(jù)自己實(shí)際使用情況進(jìn)行調(diào)整。
編輯:hfy
-
lcd
+關(guān)注
關(guān)注
36文章
4597瀏覽量
176505 -
Zynq
+關(guān)注
關(guān)注
10文章
629瀏覽量
49325 -
RGB接口
+關(guān)注
關(guān)注
1文章
5瀏覽量
10624
發(fā)布評(píng)論請先 登錄
基于ZYNQ LCD顯示OV5640圖像測試方法
評(píng)論