[X]关闭
1

S04-CH07 Sobel算子硬件实现之硬件验证(二)

摘要: 本章介绍了上一章生成的SOBEL IP如何进行调用,如何正确的驱动HLS生成的IP,另外本章还介绍了一种全新的VDMA的操作方式,通过划分内存的方式对图片进行显示,这种方法可以延伸到以后的算法处理当中,是一种很方便的 ...

软件版本:VIVADO2017.4

操作系统:WIN10 64bit

硬件平台:适用米联客 ZYNQ系列开发板

米联客(MSXBO)论坛:www.osrc.cn答疑解惑专栏开通,欢迎大家给我提问!!

7.1 概述

       本章介绍了上一章生成的SOBEL IP如何进行调用,如何正确的驱动HLS生成的IP,另外本章还介绍了一种全新的VDMA的操作方式,通过划分内存的方式对图片进行显示,这种方法可以延伸到以后的算法处理当中,是一种很方便的操作方式。

7.2 系统硬件设计

       这一章我们通过调用HLS生成的Sobel算子的IP搭建一个Sobel边缘检测的硬件实现平台,解决大家一直疑惑和关心的如何使用HLS生成的IP。

       在搭建硬件系统之前,我们先用Image2LCD对一幅图像进行取模,后期我们通过SDK来对取模的图像送SOBEL处理,然后将处理后的结果和源图像一起显示。首先,我们打开Image2LCD软件,如下图所示对lena.jpg进行取模(lena.jpg可在上一章工程文件夹中的image文件夹中找到):

1、打开一幅图像

2、选择C语言数组

3、选择32位真彩色

4、输入宽度和高度(输入完成后,记得一定要点击旁边的三角形按钮,再看底部的提示信息是否正确,如果点击之后仍然底部的输出图像不对,则超过了软件的取模范围,请裁切图片再次取模)。

5、选择32位彩色

6、拖动颜色块,将其如上图所示排列

7、保存取模输出的C语言数组

7.3 硬件工程创建

本章节的硬件工程可直接用linux篇第二章图像显示系统进行修改,节省开发时间。

Step1:打开第二章的工程(选择对应自己硬件的工程)。

Step2:双击BD文件对其进行一些修改。

Step3:在Project Manager设置区单击Project settings。

Step4:添加SOBEL IP到工程中。

Step5:添加一个VDMA,并如下图所示配置。

Step6:单击Run connection Automation进行自动布线。

Step7:添加SOBEL IP,然后单击Run connection Automation。

Step8:按下图所示,完善连线。

Step9:双击Cock wizard,如下图配置。

Step10:选中BD文件,然后右单击,选择Reset Output Products…。

Step11:再次选中BD文件,选择Generate Output Products..。

Step12:选中BD文件,然后选择Create HDL Wrapper。

Step13:生成Bit文件。

 

7.4 导入到SDK

Bit文件之后,接下来就是修改SDK,添加相关的SOBEL的驱动。

Step1:在工程文件夹中删除原来的工程的文件夹,这是因为如果不删除原来的SDK工程的话,系统就不会自动生成相关HLS生成的IP自带的驱动,笔者就曾经遇到过这种问题。

Step2:单击File-Export-Export Hardware..。

Step3:单击File-Launch SDK。

Step4:新建一个名为VDMA_SOBEL的空的工程。

Step5:复制第一节中生成的图片C数组,然后在SDK中,选中工程,在Src下直接按Ctrl

+V将其复制到工程中来。

Step6:双击main.c,用如下程序进行替换。

#include "xaxivdma.h"

#include "xaxivdma_i.h"

#include "xhls_sobel.h"

#include "sleep.h"

 

#define DDR_BASEADDR        0x00000000

#define DISPLAY_VDMA       XPAR_AXI_VDMA_0_BASEADDR + 0

#define SOBEL_VDMA    XPAR_AXI_VDMA_1_BASEADDR + 0

#define DIS_X            1280

#define DIS_Y            720

#define SOBEL_ROW  512

#define SOBEL_COL  512

#define pi 3.14159265358

#define COUNTS_PER_SECOND (XPAR_CPU_CORTEXA9_CORE_CLOCK_FREQ_HZ)/64

 

#define SOBEL_S2MM 0x08000000

#define SOBEL_MM2S 0x0A000000

#define DISPLAY_MM2S 0x0C000000

 

u32 *BufferPtr[3];

static XHls_sobel sobel;

 

//函数声明

void Xil_DCacheFlush(void);

// 所有数据格式  RGBA,低位的透明度暂不起作用

extern const unsigned char gImage_lena[1048584];

 

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 + 0xA8, width*4);//S2MM Frame Delay and Stride

    Xil_Out32(SOBEL_VDMA + 0x30, 0x3);//S2MM VDMA Control Register

    Xil_Out32(SOBEL_VDMA + 0xA0, height);//S2MM Vertical Size  start an S2M

   // 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();

}

 

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)

}

 

void SOBEL_DDRWR(unsigned int addr,unsigned int cols,unsigned int lows)

{

u32 i=0;

u32 j=0;

u32 r,g,b;

for(i=0;i<cols;i++)

{

for(j=0;j<lows;j++)

{

b= gImage_lena[(j+i*cols)*4+1];

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();

}

 

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);

XHls_sobel_Start(&sobel);

}

 

 

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)


路过

雷人

握手

鲜花

鸡蛋
发表评论

最新评论

引用 wldshy 2020-1-19 01:13
不全

查看全部评论(1)

本文作者
2019-9-17 10:54
  • 1
    粉丝
  • 3377
    阅读
  • 1
    回复

关注米联客

扫描关注,了解最新资讯

联系人:汤经理
电话:0519-80699907
EMAIL:270682667@qq.com
地址:常州溧阳市天目云谷3号楼北楼201B

关注米联客

扫描关注,了解最新资讯

联系人:汤经理
电话:0519-80699907
EMAIL:270682667@qq.com
地址:常州溧阳市天目云谷3号楼北楼201B

关注米联客

扫描关注,了解最新资讯

联系人:汤经理
电话:0519-80699907
EMAIL:270682667@qq.com
地址:常州溧阳市天目云谷3号楼北楼201B
热门评论
排行榜