Sobel硬件实现的硬件代码分析(三)
生活随笔
收集整理的這篇文章主要介紹了
Sobel硬件实现的硬件代码分析(三)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
#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 //顯示區域的行、場信號,設置顯示屏的大小 #define DIS_Y 720 #define SOBEL_ROW 512 //圖片顯示區域的大小 #define SOBEL_COL 512 #define SOBEL_S2MM 0x08000000 //sobel處理ip的接收數據的存儲地址 #define SOBEL_MM2S 0x0A000000 //sobel處理ip的處理完畢之后發送數據的存儲地址 #define DISPLAY_MM2S 0x0C000000 //僅可讀取的VDVA的數據發送地址 u32 *BufferPtr[3]; //定義一個32位無符號的緩存指針 static XHls_sobel sobel; //定義一個sobel結構體 //函數聲明,該函數用于將數據刷入DDR void Xil_DCacheFlush(void); // 所有數據格式 為 AGBR,低位的透明度暫不起作用 extern const unsigned char gImage_lena[1048584];
/*
下面函數的作用是對控制sobel的數據來源與去向的VDMA進行操作配置,其流程為
1、將VDMA控制器復位,延時,然后進行鎖定
2、設置數據到DDR三幀緩存的地址0,4,8
3、設置顯示圖片的的行寬度,datasheet中說該信號indicate the horizontal size in bytes,一個像素點為4bytes
4、設置顯示圖片的的高,indicate verical size in lines of the data to transfer
然后同理設置從VDMA發送數據到SOBEL進行處理的圖像數據幀緩存
*/ 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(); } /*
本函數僅用于將數據發送到視頻數據流處理模塊,流程為:
1、設置成循環顯示模式,然后設置三幀數據緩存的起始地址
*/ 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數據輸入處理部分,ADDr是MM2S即數據從DDR到VDMA的數據通道,將數據寫入對應位置后,將數據刷入DDR,
刷入的位置是將將數據發送到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核的設置
1、設置處理圖片的寬和高,然后禁止自啟動模式,禁用中斷,
2、設置數據配套VDMA,然后將數據輸入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); }
//設置顯示屏背景色為全黑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(); } /*
圖片顯示,
顯示兩張,一張是原始圖片,另一張是出力軸的圖片,兩張根據type進行區別,將顯示數據從addr中讀出,然后將數據寫入到顯示區域,最后將數據刷入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"用于服務可讀寫操作的VDMA1,#include "xaxivdma_i.h"用于服務僅可讀取的VDMA0,sleep.h用于延時服務,#include"xparameters.h"用于包含硬件IP的各種映射信息
總結
以上是生活随笔為你收集整理的Sobel硬件实现的硬件代码分析(三)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 面向对象之三大特性:继承,封装,多态
- 下一篇: springboot 使用的配置