Sobel硬件实现的硬件代码分析(三)
生活随笔
收集整理的這篇文章主要介紹了
Sobel硬件实现的硬件代码分析(三)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
#include "xaxivdma.h" #include "xaxivdma_i.h" #include "xhls_sobel.h" #include "sleep.h"
#include"xparameters.h"
#define DISPLAY_VDMA XPAR_AXI_VDMA_0_BASEADDR + 0 //VDMA0在DDR中的映射
#define SOBEL_VDMA XPAR_AXI_VDMA_1_BASEADDR + 0 //VDMA1在DDR中的映射 #define DIS_X 1280 //顯示區(qū)域的行、場信號,設(shè)置顯示屏的大小 #define DIS_Y 720 #define SOBEL_ROW 512 //圖片顯示區(qū)域的大小 #define SOBEL_COL 512 #define SOBEL_S2MM 0x08000000 //sobel處理ip的接收數(shù)據(jù)的存儲地址 #define SOBEL_MM2S 0x0A000000 //sobel處理ip的處理完畢之后發(fā)送數(shù)據(jù)的存儲地址 #define DISPLAY_MM2S 0x0C000000 //僅可讀取的VDVA的數(shù)據(jù)發(fā)送地址 u32 *BufferPtr[3]; //定義一個32位無符號的緩存指針 static XHls_sobel sobel; //定義一個sobel結(jié)構(gòu)體 //函數(shù)聲明,該函數(shù)用于將數(shù)據(jù)刷入DDR void Xil_DCacheFlush(void); // 所有數(shù)據(jù)格式 為 AGBR,低位的透明度暫不起作用 extern const unsigned char gImage_lena[1048584];
/*
下面函數(shù)的作用是對控制sobel的數(shù)據(jù)來源與去向的VDMA進行操作配置,其流程為
1、將VDMA控制器復(fù)位,延時,然后進行鎖定
2、設(shè)置數(shù)據(jù)到DDR三幀緩存的地址0,4,8
3、設(shè)置顯示圖片的的行寬度,datasheet中說該信號indicate the horizontal size in bytes,一個像素點為4bytes
4、設(shè)置顯示圖片的的高,indicate verical size in lines of the data to transfer
然后同理設(shè)置從VDMA發(fā)送數(shù)據(jù)到SOBEL進行處理的圖像數(shù)據(jù)幀緩存
*/ void SOBEL_VDMA_setting(unsigned int width,unsigned int height,unsigned int s2mm_addr,unsigned int mm2s_addr) { //S2MM Xil_Out32(SOBEL_VDMA + 0x30, 0x4); //reset S2MM VDMA Control Register usleep(10); Xil_Out32(SOBEL_VDMA + 0x30, 0x0); //genlock Xil_Out32(SOBEL_VDMA + 0xAC, s2mm_addr);//S2MM Start Addresses Xil_Out32(SOBEL_VDMA + 0xAC+4, s2mm_addr); Xil_Out32(SOBEL_VDMA + 0xAC+8, s2mm_addr); Xil_Out32(SOBEL_VDMA + 0xA4, width*4);//S2MM Horizontal Size Xil_Out32(SOBEL_VDMA + 0xA0, height);//S2MM Vertical Size start an S2M Xil_Out32(SOBEL_VDMA + 0xA8, width*4);//S2MM Frame Delay and Stride Xil_Out32(SOBEL_VDMA + 0x30, 0x3);//S2MM VDMA Control Register // Xil_DCacheFlush(); //MM2S Xil_Out32(SOBEL_VDMA + 0x00,0x00000003); // enable circular mode Xil_Out32(SOBEL_VDMA + 0x5c,mm2s_addr); // start address Xil_Out32(SOBEL_VDMA + 0x60,mm2s_addr); // start address Xil_Out32(SOBEL_VDMA + 0x64,mm2s_addr); // start address Xil_Out32(SOBEL_VDMA + 0x58,(width*4)); // h offset Xil_Out32(SOBEL_VDMA + 0x54,(width*4)); // h size Xil_Out32(SOBEL_VDMA + 0x50,height); // v size //Xil_DCacheFlush(); } /*
本函數(shù)僅用于將數(shù)據(jù)發(fā)送到視頻數(shù)據(jù)流處理模塊,流程為:
1、設(shè)置成循環(huán)顯示模式,然后設(shè)置三幀數(shù)據(jù)緩存的起始地址
*/ void DISPLAY_VDMA_setting(unsigned int width,unsigned height,unsigned int mm2s_addr) { Xil_Out32((DISPLAY_VDMA + 0x000), 0x00000003); // enable circular mode Xil_Out32((DISPLAY_VDMA + 0x05c), mm2s_addr); // start address Xil_Out32((DISPLAY_VDMA + 0x060), mm2s_addr); // start address Xil_Out32((DISPLAY_VDMA + 0x064), mm2s_addr); // start address Xil_Out32((DISPLAY_VDMA + 0x058), (width*4)); // h offset (640 * 4) bytes Xil_Out32((DISPLAY_VDMA + 0x054), (width*4)); // h size (640 * 4) bytes Xil_Out32((DISPLAY_VDMA + 0x050), height); // v size (480) } /*
sobel數(shù)據(jù)輸入處理部分,ADDr是MM2S即數(shù)據(jù)從DDR到VDMA的數(shù)據(jù)通道,將數(shù)據(jù)寫入對應(yīng)位置后,將數(shù)據(jù)刷入DDR,
刷入的位置是將將數(shù)據(jù)發(fā)送到MM2S的起始位置
*/ void SOBEL_DDRWR(unsigned int addr,unsigned int cols,unsigned int rows) { u32 i=0; u32 j=0; u32 r,g,b; for(i=0;i<cols;i++) { for(j=0;j<rows;j++) { b= gImage_lena[(j+i*cols)*4+1]; //B-G-R g= gImage_lena[(j+i*cols)*4+2]; r= gImage_lena[(j+i*cols)*4+3]; Xil_Out32((addr+(j+i*cols)*4),((r<<24)|(g<<16)|(b<<8)|0x0)); } } Xil_DCacheFlush(); }
/*
sobel IP核的設(shè)置
1、設(shè)置處理圖片的寬和高,然后禁止自啟動模式,禁用中斷,
2、設(shè)置數(shù)據(jù)配套VDMA,然后將數(shù)據(jù)輸入DDR
3、啟動Sobel ip核
*/ void SOBEL_Setup() { //const int cols = 512; //const int rows = 512; XHls_sobel_SetRows(&sobel, SOBEL_COL); XHls_sobel_SetCols(&sobel, SOBEL_ROW); XHls_sobel_DisableAutoRestart(&sobel); XHls_sobel_InterruptGlobalDisable(&sobel); SOBEL_VDMA_setting(SOBEL_ROW,SOBEL_COL,SOBEL_S2MM,SOBEL_MM2S); SOBEL_DDRWR(SOBEL_MM2S,SOBEL_ROW,SOBEL_COL); //init_hls_sobel_dma(cols,rows, VIDEO_BASEADDR, HLS_VDMA_MM2S_ADDR); //DDRVideoWr(HLS_VDMA_MM2S_ADDR, cols,rows); XHls_sobel_Start(&sobel); }
//設(shè)置顯示屏背景色為全黑RGB=000 void Set_blackground(u32 size_x,u32 size_y,u32 disp_addr) { u32 i=0; u32 j=0; //u32 r,g,b; for(j=0;j<size_y;j++) { for(i=0;i<size_x;i++) { Xil_Out32((disp_addr+(i+j*size_x)*4),0); //black } } Xil_DCacheFlush(); } /*
圖片顯示,
顯示兩張,一張是原始圖片,另一張是出力軸的圖片,兩張根據(jù)type進行區(qū)別,將顯示數(shù)據(jù)從addr中讀出,然后將數(shù)據(jù)寫入到顯示區(qū)域,最后將數(shù)據(jù)刷入DDR
*/ void show_img(u32 x, u32 y, u32 disp_base_addr, const unsigned char * addr, u32 size_x, u32 size_y,u32 type) { //計算圖片 左上角坐標 u32 i=0; u32 j=0; u32 r,g,b; u32 start_addr=disp_base_addr; start_addr = disp_base_addr + 4*x + y*4*DIS_X; for(j=0;j<size_y;j++) { for(i=0;i<size_x;i++) { if(type==0) { b = *(addr+(i+j*size_x)*4+2); //08 g = *(addr+(i+j*size_x)*4+1); //60 r = *(addr+(i+j*size_x)*4); //01 } else { b = *(addr+(i+j*size_x)*4+1); //08 g = *(addr+(i+j*size_x)*4+2); //60 r = *(addr+(i+j*size_x)*4+3); //01 } Xil_Out32((start_addr+(i+j*DIS_X)*4),((r<<16)|(g<<8)|(b<<0)|0x0)); } } Xil_DCacheFlush(); } int main(void) { //Xil_DCacheFlush(); xil_printf("Starting the first VDMA "); int status = XHls_sobel_Initialize(&sobel, XPAR_HLS_SOBEL_0_S_AXI_CONTROL_BUS_BASEADDR); if(0 != status) { xil_printf("XHls_Sobel_Initialize failed "); } SOBEL_Setup(); DISPLAY_VDMA_setting(DIS_X,DIS_Y,DISPLAY_MM2S); Set_blackground(1280,720,DISPLAY_MM2S); /****************************** for(i=0;i<614400;i++) { Xil_Out32(VIDEO_BASEADDR0+i,0); } *******************************/ while(1) { //show_img(0,0,VIDEO_BASEADDR0,&gImage_beauty[0],563,600); //sleep(5); //show_img(0,0,VIDEO_BASEADDR0,&gImage_miz702_rgba[0],375,400); //sleep(5); show_img(0,0,DISPLAY_MM2S,(void*)SOBEL_S2MM,512,512,0); show_img(522,0,DISPLAY_MM2S,(void*)SOBEL_MM2S,512,512,1); } return 0; }
首先包含幾個頭文件,#include "xaxivdma.h"用于服務(wù)可讀寫操作的VDMA1,#include "xaxivdma_i.h"用于服務(wù)僅可讀取的VDMA0,sleep.h用于延時服務(wù),#include"xparameters.h"用于包含硬件IP的各種映射信息
總結(jié)
以上是生活随笔為你收集整理的Sobel硬件实现的硬件代码分析(三)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 面向对象之三大特性:继承,封装,多态
- 下一篇: 图像分类综述