【JokerのZYNQ7020】BMP_SHOW_1080p。

2023-10-31 12:50
文章标签 show 1080p bmp zynq7020 joker

本文主要是介绍【JokerのZYNQ7020】BMP_SHOW_1080p。,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

软件环境:vivado 2017.4        硬件平台:XC7Z020


太丢脸了,实在太丢脸了,这篇日期是8月的文章,其实是我在8月的最后一天占了个坑,在9月才陆陆续续补上的,不然每月一更就破例了。出差在外果然是干什么都不方便啊。

本次!那就说说怎样在zynq7020上通过hdmi显示sd卡上的1080p图片。

因为这里只做图片显示输出,所以vdma只配置读通道就行。

接下来,video timing controller 功能类似于一个时序发生器,产生显示器输出所需要的时序信号,简化消隐区处理过程。第一页不使能探测模式。

第二页选择1080p。

 axi4-stream to video out把axi4-stream的视频信号转成标准行场信号输出,选择独立时钟。

 最后,1080p图像的hdmi时钟需要两个,1倍和5倍时钟,分别为148.5和742.5,如果是720p的图像,1倍和5倍的时钟则为74.25和371.25。


接下来是SDK部分,代码总共分为3部分,因为要注意的点还是比较多的,而且也比较零碎,所以分开来说,首先是main。

main.c

#include <stdio.h>
#include "xparameters.h"
#include "xsdps.h"
#include "xil_printf.h"
#include "ff.h"
#include "bmp.h"
#include "sleep.h"#define H_STRIDE            1920
#define H_ACTIVE            1920
#define V_ACTIVE            1080
#define VIDEO_LENGTH  (H_STRIDE*V_ACTIVE)#define VDMA_BASEADDR   XPAR_AXI_VDMA_0_BASEADDR
#define VIDEO_BASEADDR0 0x05000000
#define Buffer_Size 1920*1080*3static FATFS SD_Card_Dev; 
char *SD_Card_Path = "0:/";  u8 Original_Buf1[Buffer_Size] __attribute__ ((aligned(32)));
u8 Original_Buf2[Buffer_Size] __attribute__ ((aligned(32)));
u8 Original_Buf3[Buffer_Size] __attribute__ ((aligned(32)));
u8 Original_Buf4[Buffer_Size] __attribute__ ((aligned(32)));u8 Show_Buf1[Buffer_Size] __attribute__ ((aligned(32)));
u8 Show_Buf2[Buffer_Size] __attribute__ ((aligned(32)));
u8 Show_Buf3[Buffer_Size] __attribute__ ((aligned(32)));
u8 Show_Buf4[Buffer_Size] __attribute__ ((aligned(32)));void Xil_DCacheFlush(void);void Show_BMP_Picture( const unsigned char * addr, u32 size_x, u32 size_y)
{u32 x=0;u32 y=0;u32 r,g,b;for(y=0;y<size_y;y++){for(x=0;x<size_x;x++){r = *(addr++);g = *(addr++);b = *(addr++);Xil_Out32((VIDEO_BASEADDR0+((y*size_x)+size_x-x)*4),((r<<16)|(g<<8)|(b<<0)));}}Xil_DCacheFlush();
}void VDMA_init()
{int i;for(i=0;i<VIDEO_LENGTH;i++){Xil_Out32(VIDEO_BASEADDR0+i*4,0);}Xil_DCacheFlush();Xil_Out32((VDMA_BASEADDR + 0x000), 0x3);Xil_Out32((VDMA_BASEADDR + 0x05c), VIDEO_BASEADDR0);Xil_Out32((VDMA_BASEADDR + 0x060), VIDEO_BASEADDR0);Xil_Out32((VDMA_BASEADDR + 0x064), VIDEO_BASEADDR0);Xil_Out32((VDMA_BASEADDR + 0x058), (H_STRIDE*4));Xil_Out32((VDMA_BASEADDR + 0x054), (H_ACTIVE*4));Xil_Out32((VDMA_BASEADDR + 0x050), V_ACTIVE);
}int SD_init()
{FRESULT result;result = f_mount(&SD_Card_Dev,SD_Card_Path, 0);if (result != 0) {return XST_FAILURE;}return XST_SUCCESS;
}int main()
{VDMA_init();SD_init();BMP_Picture_Processor((u8 *)"1.bmp" , Original_Buf1 ,Buffer_Size);BMP_Picture_Processor((u8 *)"2.bmp" , Original_Buf2 ,Buffer_Size);BMP_Picture_Processor((u8 *)"3.bmp" , Original_Buf3 ,Buffer_Size);BMP_Picture_Processor((u8 *)"4.bmp" , Original_Buf4 ,Buffer_Size);u32 i;for(i = 0;i < Buffer_Size ;i++ ){Show_Buf1[i] = Original_Buf1[Buffer_Size-i-1];Show_Buf2[i] = Original_Buf2[Buffer_Size-i-1];Show_Buf3[i] = Original_Buf3[Buffer_Size-i-1];Show_Buf4[i] = Original_Buf4[Buffer_Size-i-1];}while(1){Show_BMP_Picture(Show_Buf1,1920,1080);sleep(2);Show_BMP_Picture(Show_Buf2,1920,1080);sleep(2);Show_BMP_Picture(Show_Buf3,1920,1080);sleep(2);Show_BMP_Picture(Show_Buf4,1920,1080);sleep(2);}return 0;
}

main里需要说明的:
1.我有4张图需要显示,但是使用了8个数组,是因为从SD直接读取的内容是小端模式,指的是高位存的是低字节,低位是高字节,与我们使用习惯刚好是反的,所以除了4组存SD直接读取出来的图片信息外,另外4组就是为了把反了的图片翻过来,转正序用的。
2.也是由于1的关系,所以宏定义VIDEO_BASEADDR0预留的空间需要多一些,如果遇见无法正常显示,有可能是这里空间没留够,设定的值太小的问题。
3.aligned(32)是4字节对齐意思,r-g-b各占1字节,实际3字节就够,但4字节对齐存储传输,也方便与PL端传输接口对应。
4.show_bmp_picture根据存储图片数组内容,根据坐标显示rgb的,这个没啥好说的。
5.VDMA_init里,寄存器的定义和设置的值可以参考pg020_axi_vdma.pdf这个手册p15,可以看到,寄存器是小端模式,偏移也是4字节对齐的。

 接下来说道代码里面提及的几个寄存器,首先是00h,控制寄存器,复位、锁相同步、帧存模式、运行状态都与此相关。

设定值03-运行、循环模式。

 从5Ch~98h有最多32个寄存器可用于存放帧起始地址,32个寄存器划在两个bank上,根据MM2S_REG_INDEX来指定bank的值,每个bank上16个寄存器有相同的起始偏移地址,都是0x5C,举个例子,访问第1个寄存器时,MM2S_REG_INDEX给0,偏移地址0x5C,访问第17个寄存器时,MM2S_REG_INDEX给1,偏移地址0x5C。

58h,用于设定帧延迟和跨度,可以看出来,低2字节用于指定水平方向的跨度,[28:24]用于指定帧的延迟。

54h,与58h相似,用于指定水平方向尺寸,即每行多少字节需要传输,举个例子,1920*1080,如果每像素4字节,则应设置1920*4。

50h,用于设置垂直方向上总共有多少行数据,并启动VDMA传输,除此之外,当MM2S_VDMACR.RS=1时,对该寄存器写操作会将所有设定传给VDMA内部对应寄存器,所以,对于VDMA某通道配置时,必须,在最后设置50h寄存器。

bmp.c

#include "bmp.h"
#include "ff.h"void Read_BMP_Header(uint8_t *header, BMP_HeaderTypeDef *bmp)
{bmp->fileHeader.bfType = ((*header) << 8) | (*(header + 1));header += 2;bmp->fileHeader.bfSize = ((*(header + 3)) << 24) | ((*(header + 2)) << 16) | ((*(header + 1)) << 8) | (*header);header += 8;bmp->fileHeader.bfOffBits = ((*(header + 3)) << 24) | ((*(header + 2)) << 16) | ((*(header + 1)) << 8) | (*header);header += 4;bmp->infoHeader.bitSize = ((*(header + 3)) << 24) | ((*(header + 2)) << 16) | ((*(header + 1)) << 8) | (*header);header += 4;bmp->infoHeader.biWidth = ((*(header + 3)) << 24) | ((*(header + 2)) << 16) | ((*(header + 1)) << 8) | (*header);header += 4;bmp->infoHeader.biHeight = ((*(header + 3)) << 24) | ((*(header + 2)) << 16) | ((*(header + 1)) << 8) | (*header);header += 6;bmp->infoHeader.biBitCount = ((*(header + 1)) << 8) | (*header);header += 2;bmp->infoHeader.biCompression = ((*(header + 3)) << 24) | ((*(header + 2)) << 16) | ((*(header + 1)) << 8) | (*header);header += 4;bmp->infoHeader.biSizeImage = ((*(header + 3)) << 24) | ((*(header + 2)) << 16) | ((*(header + 1)) << 8) | (*header);header += 4;bmp->infoHeader.biXPelsPerMeter = ((*(header + 3)) << 24) | ((*(header + 2)) << 16) | ((*(header + 1)) << 8) | (*header);header += 4;bmp->infoHeader.biYPelsPerMeter = ((*(header + 3)) << 24) | ((*(header + 2)) << 16) | ((*(header + 1)) << 8) | (*header);}void BMP_Picture_Processor(uint8_t *dir , uint8_t  * buf ,uint32_t len)
{FRESULT res;FIL fsrc;UINT  br;UINT  ofs;uint8_t buffer[1024];BMP_HeaderTypeDef BMP_Header;res = f_open(&fsrc, (const TCHAR*)dir, FA_READ);	//打开要读取的文件if(res == FR_OK)   //如果打开成功{res = f_read(&fsrc, buffer, sizeof(buffer), &br);	//读取BMP文件信息Read_BMP_Header(buffer, &BMP_Header);	//将BMP文件信息,按格式放进数组ofs = BMP_Header.fileHeader.bfOffBits;    //去掉文件信息才是像素数据res = f_lseek(&fsrc, ofs);if(res){return 0;}res = f_read(&fsrc, buf, len, &br);}f_close(&fsrc);  //关闭文件
}

bmp.c中主要包括两个函数,用Read_BMP_Header来对BMP格式图片的头信息进行解析,获取实际图像数据的起始点,然后通过f_lseek,定位到图像数据起始点,最后通过f_read读进buffer。

bmp.h

#ifndef _bmp_H
#define _bmp_H
#include <stdio.h>typedef struct 
{uint16_t bfType;        //文件类型,BMP格式为字符串BMuint32_t bfSize;		//图片大小,单位为KBuint16_t bfReserved1;	//保留位uint16_t bfReserved2;	//保留位uint32_t bfOffBits;  	//从文件头到实际图像数据之间的字节偏移量
} BMP_FileHeaderTypeDef;typedef struct 
{uint32_t bitSize;		 //BMP_InfoHeaderTypeDef结构体所需要的字节数uint32_t biWidth;		 //图片宽度,像素位单位int32_t  biHeight;		 //图片高度,像素为单位。正为倒立,负为正向。uint16_t biPlanes;		 //颜色平面数,总为1uint16_t biBitCount;	 //比特数/像素。其值为:1、4、8、16、24或32uint32_t biCompression;  //数据压缩类型uint32_t biSizeImage;	 //图像大小uint32_t biXPelsPerMeter;//水平分辨率uint32_t biYPelsPerMeter;//垂直分辨率uint32_t biClrUsed;		 //颜色索引数uint32_t biClrImportant; //重要颜色索引数}BMP_InfoHeaderTypeDef;typedef struct
{BMP_FileHeaderTypeDef fileHeader;	//文件头BMP_InfoHeaderTypeDef infoHeader;	//图片信息头}BMP_HeaderTypeDef;void Read_BMP_Header(uint8_t *header, BMP_HeaderTypeDef *bmp);
void BMP_Picture_Processor(uint8_t *dir , uint8_t * buf ,uint32_t len);#endif

bmp.h中的结构体用于根据固定格式,即对应的字段长度,解析BMP图片头信息。

哦,对了,最后还有一点需要注意,这里的sd卡为fat文件系统,sdk中的bsp记得要勾选xilffs,否则无法读到文件。

这篇关于【JokerのZYNQ7020】BMP_SHOW_1080p。的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/315490

相关文章

07 v-if和v-show使用和区别

划重点: v-ifv-show 小葱拌豆腐 <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="

10400 -Game Show Math

这道题的话利用了暴力深搜,尽管给了20S,但是这样还会超时,所以就需要利用回溯进行减枝,因为是DFS,所以用一个数组vis[i][j]记录是否在状态i时候取到过j值,如果取到过的话,那么直接回溯(往后搜索已经没有意义了,之前到达这个状态的时候是无法得到结果的) 还有需要注意的地方就是题目的要求,每一步的结构都在(-32000,32000)之间,所以需要一步判断,如果在这个范围外直接回溯 最后一

show命令监控分析mysql实例信息

文章目录 思维导图show 查看数据库实例相关信息SHOW VARIABLES 分析数据库当前变量设置分析连接数据分析线程数分析慢查询变量分析缓存相关分析字符集相关 SHOW STATUS 数据库当前实时状态分析分析连接数据分析线程数分析慢查询分析查询缓存分析排序使用情况分析文件打开数mysql 锁分析 思维导图 show 查看数据库实例相关信息 查看当前实例所有数据库

做一个用python脚本生成bmp位图的小工具

需求 我有一些用代码生成位图的需求,例如给定一个坐标(x,y),通过一定的逻辑得到对应的颜色值。目的是以这样的方式得到一些用于调试的位图。 实现这个目的有多种方法,不过我最大的期望是—— “易用性” :我希望当我想生成一个位图时,所做的操作达到最小。这意味着: 首先,这个“工具”不是一个纯C++的工程,否则我每次想生成新位图时,都需要打开我的工程,修改代码后,重新编译。换句话说,生成图片的逻

Show,Attend and Tell: Neural Image Caption Generation with Visual Attention

简单的翻译阅读了一下 Abstract 受机器翻译和对象检测领域最新工作的启发,我们引入了一种基于注意力的模型,该模型可以自动学习描述图像的内容。我们描述了如何使用标准的反向传播技术,以确定性的方式训练模型,并通过最大化变分下界随机地训练模型。我们还通过可视化展示了模型如何能够自动学习将注视固定在显着对象上,同时在输出序列中生成相应的单词。我们通过三个基准数据集(Flickr9k,Flickr

你可能被 Vue 中的 v-show 骗了,它并没有像你想的那样切换 display 的属性

你好同学,我是沐爸,欢迎点赞、收藏、评论和关注! 在 Vue 中 v-show 是如何条件性地渲染内容的,你可能知道是通过切换 display 属性实现,但真的跟你想的一样吗? 一、你被骗了吗? v-show 和 v-if 指令都是用于条件性地渲染一块内容,但表达式的值为真时,显示内容,为假时,隐藏内容。 对于两者的区别,你应该也了如指掌:v-if 是真正的条件渲染;v-show 始终会被

前端框架vue3中的条件渲染(v-show,v-if,v-else-if,v-else)

目录 v-show: 需求: v-if 区别与v-show: v-if和v-show的选择: v-else-if和v-else 联合使用: v-show:         部分代码如图: <body><div id="root"><div ><h1>n的值为{{n}}</h1></div></div></body><script>new Vue({el:"#ro

RAW格式转化为BMP

首先先介绍C++中图像数据分配内存方法。   在计算机中图像是一个二维的数字点阵。 比较容易想到的是申请一个二维矩阵来存储图像 如: BYTE image[512][512]; 可以存储一幅512*512个像素的图像,每个像素用一个字节表示,一个字节能表示0-255共256个不同取值。所以这一二维数组比较合适存储灰度图像。   对于二维彩色图像,如果每个像素分别有R,G,B 3个颜色分量,则可以

mfc从本地加载bmp图片

HBITMAP hHitmap; hHitmap = (HBITMAP)LoadImage(AfxGetInstanceHandle(), 图片路径(CString), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); CBitmap mapPreview; mapPreview.Attach(hHitmap); BITMAP bitmap; int n = m

MySQL SQL性能分析 show profile

MySQL show profile 和 show profiles 命令用于展示SQL语句执行过程中的资源使用情况,包括CPU的使用,CPU上下文切换,IO等待,内存使用等,这个命令对于分析某个SQL的性能瓶颈非常有帮助,借助于show profile的输出信息,能让我们知道一个SQL在哪个阶段耗时最长,消耗资源最多,从而为SQL优化,提高SQL性能提供重要的依据。 原文地址: http