14 - VDMA彩条显示实验

news2025/4/13 12:31:43

文章目录

  • 1 实验任务
  • 2 系统框图
  • 3 硬件设计
  • 4 软件设计

1 实验任务

本实验任务是PS端写彩条数据至DDR3内存中,然后通过PL端的VDMA IP核将彩条数据通过HDMI接口输出显示。

2 系统框图

本实验是用HDMI接口固定输出1080P的彩条图,所以:

  1. rgb2lcd模块实际是rgb2dvi模块
  2. AXI GPIO不存在,因为不需要读取LCD屏幕的ID
  3. 动态时钟配置改为PLL,输出固定频率,与AXI-Interconnect不连
  4. VTC输出固定时序,与AXI-Interconnect不连
    在这里插入图片描述

3 硬件设计

注意事项:

  1. VTC的clken引脚
    • 该引脚不连接,VTC也能正常工作
    • pg016中描述该引脚是"Video Core active-High Clock Enable",即高有效
    • 在Block Design中添加VTC后,clken引脚前边有个小圆圈,且双击该引脚,Polarity参数显示为ACTIVE_LOW,即低有效
    • 将该引脚接常量1,视频输出正常
    • 将该引脚接常量0,视频无法输出,VTC未工作
    • 结论:以文档为准,clken高电平有效
  2. rgb2dvi模块
    • 使用正点原子的rgb2dvi模块,数据的3个字节是G在中间,R和B在两头
    • 使用Digilent的rgb2dvi模块,数据的3个字节是B在中间,R和G在两头(调试时一脸懵逼)
      在这里插入图片描述

4 软件设计

注意事项:

  1. PS往DDR3写入数据后,要使用Xil_DCacheFlushRange刷新;
  2. run_triple_frame_buffer函数并非只能用于三帧缓存的情况,实际1-32帧缓存均可使用该函数(取名triple可能和VDMA模式使用三帧缓存有关);ReadSetup函数和WriteSetup函数会根据VDMA配置时选择的Frame Buffers数量设置相应数量的帧缓冲区起始地址;本实验选择Frame Buffers数量=1,PS端只往DDR3中写入一帧彩条图;
  3. XAxiVdma_DmaStop函数往VDMACR寄存器的bit0写0(Run / Stop controls the running and stopping of the VDMA channel. ),当前VDMA操作完成后停止(0 = Stop – VDMA stops when current (if any) VDMA operations are complete)
/***************************** Include Files *********************************/
#include "stdio.h"
#include "xparameters.h"
#include "xstatus.h"
#include "xaxivdma.h"
#include "vdma_api.h"
#include "xil_cache.h"
#include "xuartps.h"
#include "sleep.h"
/************************** Constant Definitions *****************************/
#define VDMA_DEVICE_ID		XPAR_AXIVDMA_0_DEVICE_ID
#define IMAGE_WIDTH			1920
#define IMAGE_HEIGHT		1080
#define MEMORY_BASEADDR		XPAR_PS7_DDR_0_S_AXI_BASEADDR

#define UART_DEVICE_ID		XPAR_XUARTPS_0_DEVICE_ID
#define UART_BASEADDR    	XPAR_XUARTPS_0_BASEADDR
/**************************** Type Definitions *******************************/

/***************** Macros (Inline Functions) Definitions *********************/

/************************** Function Prototypes ******************************/
s32  UartPsInit(XUartPs *UartPsInstPtr, XUartPsFormat* UartFormatPtr);

void GenPureColor(u8* DestAddr, u32 ImageWidth, u32 ImageHeight);
void GenColorBar(u8* DestAddr, u32 ImageWidth, u32 ImageHeight);
/************************** Variable Definitions *****************************/
XAxiVdma VdmaInst;
XUartPs UartInst;

int FrameBufferAddr = (MEMORY_BASEADDR + 0x02000000);

XUartPsFormat UartFormat = {
		XUARTPS_DFT_BAUDRATE,     // 115200
		XUARTPS_FORMAT_8_BITS,
		XUARTPS_FORMAT_NO_PARITY,
		XUARTPS_FORMAT_1_STOP_BIT
};
/*****************************************************************************/

int main()
{
	//
	int Status;
	u8* VdmaBufferAddr = (u8*)FrameBufferAddr;
	char cmd;

	// 串口初始化
	Status = UartPsInit(&UartInst, &UartFormat);
	if (Status != XST_SUCCESS) {
		printf("UART Initialization Failed.\n");
		return XST_FAILURE;
	}

	// 写入纯色图(用于确定RGB的字节位置)
//	GenPureColor(VdmaBufferAddr, (u32)IMAGE_WIDTH, (u32)IMAGE_HEIGHT);

	// 写入彩条图
	GenColorBar(VdmaBufferAddr, (u32)IMAGE_WIDTH, (u32)IMAGE_HEIGHT);

	//
	Status = run_triple_frame_buffer(&VdmaInst, VDMA_DEVICE_ID, IMAGE_WIDTH, IMAGE_HEIGHT, FrameBufferAddr, 0, 0);
	if (Status == XST_FAILURE) {
		printf("VDMA Run Failed.\n");
	}

	//
	printf("VDMA Control Ready (s=start, q=stop):\n");

    while (1) {
        if (XUartPs_IsReceiveData(UART_BASEADDR)) {
            cmd = XUartPs_ReadReg(UART_BASEADDR, XUARTPS_FIFO_OFFSET);

            if (cmd == 's') {  // 启动VDMA
                if (XAxiVdma_DmaStart(&VdmaInst, XAXIVDMA_READ) == XST_SUCCESS) {
                	printf("VDMA Start Succeeded.\n");
                } else {
                	printf("VDMA Start Failed.\n");
                }
            }
            else if (cmd == 'q') {  // 停止VDMA
            	XAxiVdma_DmaStop(&VdmaInst, XAXIVDMA_READ);
            	printf("VDMA Stop Succeeded.\n");
            }
        }
        usleep(10000); // 降低CPU占用
    }

	//
	return 0;
}
/*****************************************************************************/
s32 UartPsInit(XUartPs *UartInstPtr, XUartPsFormat* UartFormatPtr)
{
	//
	s32 Status;
	XUartPs_Config *UartConfigPtr;

	// 查找UART配置
	UartConfigPtr = XUartPs_LookupConfig(UART_DEVICE_ID);
	if(NULL == UartConfigPtr)
	{
		return XST_FAILURE;
	}

	// 初始化UART
	Status = XUartPs_CfgInitialize(UartInstPtr, UartConfigPtr, UartConfigPtr->BaseAddress);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	// 设置UART数据格式
	XUartPs_SetDataFormat(UartInstPtr, UartFormatPtr);

	// 设置UART操作模式
	XUartPs_SetOperMode(UartInstPtr, XUARTPS_OPER_MODE_NORMAL);

	//
	return XST_SUCCESS;
}
/*****************************************************************************/
void GenPureColor(u8* DestAddr, u32 ImageWidth, u32 ImageHeight)
{
    // 禁用缓存(如果目标内存是非缓存区域)
    Xil_DCacheDisable();

    for (u32 y = 0; y < ImageHeight; y++) {
        for (u32 x = 0; x < ImageWidth; x++) {
            // 计算当前像素的内存位置(3字节/像素)
        	u32 PixelOffset = (y * ImageWidth + x) * 3;
        	u8* PixelAddr = DestAddr + PixelOffset;

            // 写入RGB三个字节
        	PixelAddr[0] = 0x00;
        	PixelAddr[1] = 0x00;
        	PixelAddr[2] = 0xff;
        }
    }

    // 如果需要,刷新缓存
    Xil_DCacheFlushRange((INTPTR)DestAddr, ImageWidth * ImageHeight * 3);

    //
    return;
}

/*****************************************************************************/
void GenColorBar(u8* DestAddr, u32 ImageWidth, u32 ImageHeight)
{
    // 定义8种颜色(R, G, B顺序)
    const u8 color_bars[8][3] = {
        {0x00, 0x00, 0x00}, // 黑
        {0xff, 0xff, 0xff}, // 白
        {0xff, 0x00, 0x00}, // 蓝
        {0x00, 0xff, 0x00}, // 绿
        {0x00, 0x00, 0xff}, // 红
        {0xff, 0xff, 0x00}, // 青
        {0xff, 0x00, 0xff}, // 紫
        {0x00, 0xff, 0xff}  // 黄
    };

    // 计算每个色条的宽度
    u32 BarWidth = ImageWidth / 8;

    // 禁用缓存(如果目标内存是非缓存区域)
    Xil_DCacheDisable();

    for (u32 y = 0; y < ImageHeight; y++) {
        for (u32 x = 0; x < ImageWidth; x++) {
            // 计算当前色条索引
        	u32 BarIndex = x / BarWidth;

            // 计算当前像素的内存位置(3字节/像素)
        	u32 PixelOffset = (y * ImageWidth + x) * 3;
        	u8* PixelAddr = DestAddr + PixelOffset;

            // 写入RGB三个字节
        	PixelAddr[0] = color_bars[BarIndex][0];
        	PixelAddr[1] = color_bars[BarIndex][1];
        	PixelAddr[2] = color_bars[BarIndex][2];
        }
    }

    // 如果需要,刷新缓存
    Xil_DCacheFlushRange((INTPTR)DestAddr, ImageWidth * ImageHeight * 3);

    //
    return;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2333822.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PromptUp 网站介绍:AI助力,轻松创作

1. 网站定位与核心功能 promptup.net 可能是一个面向 创作者、设计师、营销人员及艺术爱好者 的AI辅助创作平台,主打 零门槛、智能化的内容生成与优化。其核心功能可能包括: AI艺术创作:通过输入关键词、选择主题或拖放模板,快速生成风格多样的数字艺术作品(如插画、海报…

金能电力:配电房为什么离不开绝缘胶板

在当今电力系统日益复杂、对供电稳定性与安全性要求极高的时代&#xff0c;每一个细节都关乎着电力供应的顺畅以及工作人员的生命安全。而配电房里常常被大家忽视的绝缘垫&#xff0c;实则起着至关重要的 “守护” 作用。今天&#xff0c;金能电力就来给大家详细讲讲配电房为什…

Python 深度学习实战 第1章 什么是深度学习代码示例

第1章&#xff1a;什么是深度学习 内容概要 第1章介绍了深度学习的背景、发展历史及其在人工智能&#xff08;AI&#xff09;和机器学习&#xff08;ML&#xff09;中的地位。本章探讨了深度学习的定义、其与其他机器学习方法的关系&#xff0c;以及深度学习在近年来取得的成…

【HD-RK3576-PI】VNC 远程桌面连接

在当今数字化时代&#xff0c;高效便捷的操作方式是技术爱好者与专业人士的共同追求。对于使用 HD-RK3576-PI微型单板计算机的用户而言&#xff0c;当面临没有显示屏的场景时&#xff0c;如何实现远程操作桌面系统呢&#xff1f;别担心&#xff0c;VNC 远程桌面连接将为你解决这…

电梯广告江湖的终局:分众 “吃掉” 新潮,是救赎还是迷途?

文 / 大力财经 作者 / 魏力 导言&#xff1a;商业世界的底层运行法则&#xff0c;从来都是能量流动的自然映射。宇宙第一性原理和运行法则是&#xff0c;能量大的吸引能量小的。电梯里的战争与和平&#xff0c;从对抗到合并&#xff0c;成为中国商业竞争史中关于博弈与进化的…

如何在 CentOS 7 系统上以容器方式部署 GitLab,使用 ZeroNews 通过互联网访问 GitLab 私有仓库,进行代码版本发布与更新

第 1 步&#xff1a; 部署 GitLab 容器​ 在开始部署 GitLab 容器之前&#xff0c;您需要创建本地目录来存储 GitLab 数据、配置和日志&#xff1a; #创建本地目录 mkdir -p /opt/docker/gitlab/data mkdir -p /opt/docker/gitlab/config mkdir -p /opt/docker/gitlab/log#gi…

第1章 对大型语言模型的介绍

人类正处在一个关键转折点。自2012年起&#xff0c;基于深度神经网络的人工智能系统研发进入快速通道&#xff0c;将这一技术推向了新高度&#xff1a;至2019年底&#xff0c;首个能够撰写与人类文章真假难辨的软件系统问世&#xff0c;这个名为GPT-2&#xff08;生成型预训练变…

Quartus II的IP核调用及仿真测试

目录 第一章 什么是IP核&#xff1f;第二章 什么是LPM&#xff1f;第一节 设置LPM_COUNTER模块参数第二节 仿真 第三章 什么是PLL&#xff1f;第一节 设置ALTPLL&#xff08;嵌入式锁相环&#xff09;模块参数第二节 仿真 第四章 什么是RAM&#xff1f;第一节 RAM_1PORT的调用第…

JDK(Java Development Kit)从发布至今所有主要版本 的详细差异、新增特性及关键更新的总结,按时间顺序排列

以下是 JDK&#xff08;Java Development Kit&#xff09;从发布至今所有主要版本 的详细差异、新增特性及关键更新的总结&#xff0c;按时间顺序排列&#xff1a; 1. JDK 1.0 (1996) 发布年份&#xff1a;1996年1月23日关键特性&#xff1a; Java首次正式发布。核心语言特性…

通过websocket给服务端发送订单催单提醒消息

controller层 GetMapping("/reminder/{id}")public Result Remainder(PathVariable("id") Long id){orderService.remainder(id);return Result.success();} 实现类 Overridepublic void remainder(Long id) {Orders ordersDB orderMapper.getById(id);…

c++ 表格控件 UltimateGrid 控件实例

控件区域&#xff1a; 使用效果&#xff1a; 代码如下&#xff1a; void MyUGCtrl::OnSetup() { m_nButtonIndex AddCellType(&m_button); SetNumberCols(6); AppendRow(); CUGCell cell; int rows, cols; int row 0; // 头部 int nHeaderRow -1; …

使用 VcXsrv 在 Windows 10 上运行 Ubuntu 图形界面

VcXsrv 是一款用于 Windows 的开源 X 服务器&#xff0c;它允许在 Windows 系统上显示 Linux 的图形应用程序。当在 Windows 10 上安装并正确配置 VcXsrv 后&#xff0c;通过设置 WSL2 中的DISPLAY环境变量&#xff0c;使其指向运行 VcXsrv 的 Windows 主机的 IP 地址&#xff…

LSTM-SVM长短期记忆神经网络结合支持向量机组合模型多特征分类预测/故障诊断,适合新手小白研究学习(Matlab完整源码和数据)

LSTM-SVM长短期记忆神经网络结合支持向量机组合模型多特征分类预测/故障诊断&#xff0c;适合新手小白研究学习&#xff08;Matlab完整源码和数据&#xff09; 目录 LSTM-SVM长短期记忆神经网络结合支持向量机组合模型多特征分类预测/故障诊断&#xff0c;适合新手小白研究学习…

Autoware源码总结

Autoware源码网站 项目简介 教程 Autoware的整体架构如下图&#xff0c;主要包括传感器sensing、高精地图map data、车辆接口vehicle interface、感知perception&#xff08;动态障碍物检测detection、跟踪tracking、预测prediction&#xff1b;交通信号灯检测detection、分类c…

QT聊天项目DAY01

1.新建初始项目 2.修改UI格式 运行效果 3.创建登录界面 设计登录界面UI 设计布局 调整布局间距 往水平布局中拖入标签和文本输入框 更换控件名称并固定高度 添加窗口部件 往现有的资源文件中导入图片 添加水平布局 4.设置登陆界面为主窗口的核心组件 #pragma once#include &l…

论文精度:基于LVNet的高效混合架构:多帧红外小目标检测新突破

论文地址:https://arxiv.org/pdf/2503.02220 目录 一、论文背景与结构 1.1 研究背景 1.2 论文结构 二、核心创新点解读 2.1 三大创新突破 2.2 创新结构原理 2.2.1 多尺度CNN前端 2.2.2 视频Transformer设计 三、代码复现指南 3.1 环境配置 3.2 数据集准备 3.3 训…

ORM查询的补充

一&#xff0c;ORM查询的补充&#xff1a; 1&#xff0c;连接查询&#xff1a; 反向查询: 先介绍一下什么是正向查询&#xff0c;比如我们之前的数据表之间建立的一对多的关系&#xff0c;我们通过文章找到相应的作者是属于正向查询的&#xff08;由多到一&#xff09;&…

蔚来汽车智能座舱接入通义大模型,并使用通义灵码全面提效

为加速AI应用在企业市场落地&#xff0c;4月9日&#xff0c;阿里云在北京召开AI势能大会。阿里云智能集团资深副总裁、公共云事业部总裁刘伟光发表主题演讲&#xff0c;大模型的社会价值正在企业市场释放&#xff0c;阿里云将坚定投入&#xff0c;打造全栈领先的技术&#xff0…

VMWare Workstation Pro17.6最新版虚拟机详细安装教程(附安装包教程)

目录 前言 一、VMWare虚拟机下载 二、VMWare虚拟机安装 三、运行虚拟机 前言 VMware 是全球领先的虚拟化技术与云计算解决方案提供商&#xff0c;通过软件模拟计算机硬件环境&#xff0c;允许用户在一台物理设备上运行多个独立的虚拟操作系统或应用。其核心技术可提升硬件…

【数据结构】红黑树超详解 ---一篇通关红黑树原理(含源码解析+动态构建红黑树)

一.什么是红黑树 红黑树是一种自平衡的二叉查找树&#xff0c;是计算机科学中用到的一种数据结构。1972年出现&#xff0c;最初被称为平衡二叉B树。1978年更名为“红黑树”。是一种特殊的二叉查找树&#xff0c;红黑树的每一个节点上都有存储表示节点的颜色。每一个节点可以是…