本帖最后由 FPGA课程 于 2024-10-9 17:14 编辑
软件版本:VIVADO2021.1
操作系统:WIN10 64bit
硬件平台:适用 XILINX A7/K7/Z7/ZU/KU 系列 FPGA
实验平台:米联客-MLK-H3-CZ08-7100开发板
板卡获取平台:https://milianke.tmall.com/
登录“米联客”FPGA社区 http://www.uisrc.com 视频课程、答疑解惑!
1概述在前文中,我们已经掌握了uifdma_vbuf3.0 ip的使用,本文实现一个综合性的实验,把摄像头的数据以BMP格式保存到TF卡中。 本文实验目的: 1:掌握uifdma_vbuf3.0的地址空间分配方法 2:利用多缓存机制,把内存中的图像以BMP格式保存到TF卡 2系统框图
3硬件电路分析硬件接口和子卡模块请阅读“附录1” 配套工程的FPGA PIN脚定义路径为soc_prj/uisrc/04_pin/ fpga_pin.xdc。 4搭建SOC系统工程
4.1PL图形化编
以上代码中OV5640数据格式转为RGB888输入到uifdma_dbuf的写端口,经过uifdma_dbuf后进入fdma,之后通过AXI_interconnect 进入到ZYNQ DDR中。 SDK代码中,PS(ARM)读取内存中保存的摄像头采样数据,并且通过HDMI实时显示。当按下快门按键的时候,点亮开发板的LED,同时把内存中的数据以BMP格式保存到SD卡中 。 下面具体看下关键几个IP的参数设置 1:uifdma_dbuf设置由于输入数据是视频数据流形式,所以需要使能视频传输功能,这里也只使用到了写通道,所以读通道也不需要使能。 一般对于摄像头采集,设置3帧缓存就够用。WBaseaddr缓存的基地址只要设置合适的值即可,这里设置0x08000000 =128MB,这样保留了低128MB给应用程序使用。 由于一幅图片的大小为1280*720*4= 3600Bytes 因此WDsizebits设置每个缓存的大小,2^23次方=8MBYTE够用。 在SDK中的地址空间分配对应如下: #define BUF_BASE_SIZE 0x08000000
#define BUF_RANG_SIZE 0x800000
#define BUF1_ADDR BUF_BASE_SIZE + BUF_RANG_SIZE*0;
#define BUF2_ADDR BUF_BASE_SIZE + BUF_RANG_SIZE*1;
#define BUF3_ADDR BUF_BASE_SIZE + BUF_RANG_SIZE*2;
2:uiFDMA设置Fdma的数据位宽可以设置128这样效率最高。
3:AXI Interconnect设置设置FIFO可以增加数据的吞吐能力
以上代码中,调用了米联客uispi7606 IP CORE采集模拟数据,并且把采集好的数据写入到uifdmadbuf中,为了方便实验中观察数据,把第八个通道的AD数据改成了计数器。实际项目中可以把这个替换成第八个通道的ADC数据。 4.2设置地址分配需要注意uifdma_dbuf的axi-lite接口地址,这个地址我们会在SDK 代码中用到读寄存器。
4.3添加PIN约束1:选中PROJECT MANAGERà Add SourcesàAdd or create constraints,添加XDC约束文件。
2:打开提供例程,复制约束文件中的管脚约束到XDC文件,或者查看原理图,自行添加管脚约束,并保存。 以下是添加配套工程路径下已经提供的pin脚文件。配套工程的pin脚约束文件在uisrc/04_pin路径 4.4编译并导出平台文件1:单击Block文件à右键àGenerate the Output ProductsàGlobalàGenerate。 2:单击Block文件à右键à Create a HDL wrapper(生成HDL顶层文件)àLet vivado manager wrapper and auto-update(自动更新)。 3:生成Bit文件。 4:导出到硬件: FileàExport HardwareàInclude bitstream 5:导出完成后,对应工程路径的soc_hw路径下有硬件平台文件:system_wrapper.xsa的文件。根据硬件平台文件system_wrapper.xsa来创建需要Platform平台。
5搭建Vitis-sdk工程创建soc_base sdk platform和APP工程的过程不再重复,如果不清楚请参考本章节第一个demo。 5.1创建SDK Platform工程
ZYNQ的SD1支持FAT文件系统,我们的ZYNQ SD1接到了TF卡上,因此可以把保存的图片放到TF卡中。为了使用文件系统,需要对库做一些设置:
5.2创建photograph_fdma——工程
6SDK程序分析
6.1 cam_photograph.c主程序
1:uifdma_dbuf 设置的地址空间
为了可以把uifdma_dbuf写入到DDR指定地址的数据读出来,首先需要对地址进行定义
- #define VIDEO_OUT_HSIZE 1280*4
- #define VIDEO_OUT_STRIDE 1280*4
- #define VIDEO_OUT_VSIZE 720
- #define IMG_SIZE VIDEO_OUT_HSIZE*VIDEO_OUT_VSIZE
- #define BUF_BASE_SIZE 0x10000000
- #define BUF_RANG_SIZE 0x800000
- #define BUF1_ADDR BUF_BASE_SIZE + BUF_RANG_SIZE*0;
- #define BUF2_ADDR BUF_BASE_SIZE + BUF_RANG_SIZE*1;
- #define BUF3_ADDR BUF_BASE_SIZE + BUF_RANG_SIZE*2;
- u8 *UIFDMA_DBUF[IMG_SIZE] __attribute__ ((aligned(256)));
复制代码
2:指针数字指向三个缓存地址
给分配的内存指针数字指向FPGA中uifdma_dbuf中设置的地址空间:
- UIFDMA_DBUF[0] = (u8*)BUF1_ADDR;
- UIFDMA_DBUF[1] = (u8*)BUF2_ADDR;
- UIFDMA_DBUF[2] = (u8*)BUF3_ADDR;
复制代码
3:设置VDMA的地址
- video_out_ReadCfg.FrameStoreStartAddr[0] = (INTPTR)UIFDMA_DBUF[0];
- video_out_ReadCfg.FrameStoreStartAddr[1] = (INTPTR)UIFDMA_DBUF[1];
- video_out_ReadCfg.FrameStoreStartAddr[2] = (INTPTR)UIFDMA_DBUF[2];
复制代码
4:启动采集和停止采集
- XGpio_DiscreteWrite(&rstn_5640, 1, 0x1);//启动采集
- XGpio_DiscreteWrite(&rstn_5640, 1, 0x0);//停止采集
复制代码
5:本方案核心程序核心程序中,不停读取按键的状态,当由按键按下,则当VDMA中断产生后,立马开始保存图片,这样做的目前是未来更好让图形静止在显示器中,模拟相机的拍照状态。另外在开发板上会有一个LED在保存图片的时候常亮。如果按键没有按下,则实时显示当前的摄像头图像。 - while(1){
- delay_cnt =0;
- if(button_down() && cap_button == 0)//read button when button io is 0 enable img grap
- cap_button =1;
- else if(wfram1_cap_done == 1)//wait vmda s2mm write channel intrrupt
- {
- XGpio_DiscreteWrite(&rstn_5640, 1, 0x0);//stop camera
- XGpio_DiscreteSet(&button_led, 1, AXI_GPIO_BIT1);//open led
- //set img name
- img_cnt++ ;
- sprintf(imgName, "%04u.bmp", img_cnt) ;
- printf("Write to SD Card...\r\n") ;
- //frush cache data all into ddr
- Xil_DCacheInvalidateRange((INTPTR) UIFDMA_DBUF[fdma_buf], IMG_SIZE) ;
- //write img to sdcard
- bmp_write(imgName, (char *)&BMODE_1280x720, (char *)UIFDMA_DBUF[fdma_buf], VIDEO_OUT_STRIDE) ;
- printf("Successfully Take img, img Name is %s\r\n", imgName) ;
- XGpio_DiscreteClear(&button_led, 1, AXI_GPIO_BIT1);//close led
- cap_button =0;//clear for next
- wfram1_cap_done =0;//clear for next
- XGpio_DiscreteWrite(&rstn_5640, 1, 0x1);//restar camera
- }
- }
复制代码
6.2pl_intr.c程序
该程序中响应来自uifdma_dbuf的中断,每当一帧图形发送完毕即产生一次PL中断,在PL中断中读取uifdma_dbuf的当前缓存号
- void PS_RX_intr_Handler(void *param)
- {
- fdma_buf = Xil_In32((UINTPTR)FDMA_DBUF_BASE_ADDR);
- }
复制代码
7方案演示
7.1硬件准备本实验需要用到 JTAG 下载器、USB 转串口外设,另外需要把核心板上的 2P 模式开关设置到 JTAG 模式,即 ON ON (注意新版本的 MLK-H3-CZ08-7100FC(米联客 7X 系列),支持 JTAG 模式,对于老版本的核心板,JTAG 调试 的时候一定要拔掉 TF 卡,并且设置模式开关为 OFF OFF)
7.2实验结果按下按键拍照,拍照当前照片静止
用读卡器读取TF卡保存的图片
可以看到我们录制的视频中拍照的结果对比
本实验也提供了 CEPX3,双目摄像头的采集方案
|