当前位置: 首页 > article >正文

【【VDMA彩条显示实验之四 含C语言代码】】

VDMA彩条显示实验之四 含C语言代码

VTC 手册简介

所有的视频都需要有时序 有时序的地方就需要有 时序控制器
VTC的 主要作用是 产生 视频时序

相对于上一节 在这里 我们会理解的更多
在这里插入图片描述

观察 这个 HB 信号 其实这个和上一节的图片差不多
在 行同步信号 前面就是前沿 在 行同步信号的后侧 就是 后沿

在这里插入图片描述

VTC 还可以最多支持 16 个 帧同步信号

在这里插入图片描述

我们来配置 VTC
首先观察我们需要配置的 各项参数 设置
在这里插入图片描述

这是 LCD 时序参数
我们需要做的是将 这个参数 与 VTC的 配置 关联起来

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

下面我们来配置 帧时序

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

最终设计的block design

在这里插入图片描述

我们观察一下 像素时钟接到了 哪几个端口上
在这里插入图片描述

我们会发现 由 PLL 锁相环产生 的 像素时钟 连接到 了 VTC 模块 Video out的 一个 clk 还有 连接到了 lcd_clk 上
其他上用的大多是 100M的时钟
int run_triple_frame_buffer(XAxiVdma* InstancePtr , int DeviceId , int hsize, int vsize, int buf_base_addr, int number_frame_count, int enable_frm_cnt_intr)
第一个参数是 XAxiVdma* InstancePtr ----> VDMA 数据结构的 句柄
第二个参数是 int DeviceId -------> VDMA 器件 的 ID
第三个参数是 int hsize --------> 一帧水平方向上的大小
第四个参数是 int vsize ----------> 竖直方向上的大小
第五个参数是 int buf_base_addr ----------> VDMA 起始帧缓存的地址
第六个参数 是 int number_frame_count ----------> 指定了经过多少帧之后 会迎来中断
第七个参数是 int enable_frm_cnt_intr --------> 告诉我们是否需要使能帧计数器这样的 一个中断
因为在本次实验中 我们并不是很需要中断 所以最后两个参数可以不用去考虑

下面展示整个C语言代码

#include "stdio.h"
#include"xparameters.h"
#include "xaxivdma.h"
#include "vdma_api.h"
#define VDMA_ID            XPAR_AXIVDMA_0_DEVICE_ID
#define DDR_BASE_ADDR      XPAR_PS7_DDR_0_S_AXI_BASEADDR  // DDR存储空间 的起始地址
//这个是 DDR的基地址 我们是需要写一个彩条图案 但是 彩条图案总不能从基地址
//开始,因为我们程序 也是 从基地址 开始运行的 。 如果彩条图案是从基地址开始
//运行的话 ,就会给我们程序带来冲突  所以我们要重新定义一个帧缓存的地址
// 把宏定义的形式 改写成 变量的形式 这样在 后续可以更方便使用
int frame_buffer_addr  = (DDR_BASE_ADDR + 0x1000000)  ;// VDMA 帧缓存的地址
#define WIDTH   800  // 图像的宽度
#define HEIGHT  480  // 图像的高度
int main()
{
int i , j ;
u8* vdma_buffer_addr ;
vdma_buffer_addr = (u8*) frame_buffer_addr ;


XAxiVdma vdma_inst;


// 配置并启动 VDMA

run_triple_frame_buffer(
&vdma_inst,        // vdma驱动实例
VDMA_ID,           // VDMA 的 ID信息
WIDTH,             //  图像的水平尺寸  宽度
HEIGHT,            //  图像的高度
frame_buffer_addr,   //  VDMA 究竟从DMA的哪个地址开始读取图像// VDMA 帧缓存的起始地址
0,
0);
//  往 VDMA 的帧缓存里面 写入 图案
for(j=0;j<HEIGHT ; j++){
for(i=0 ; i<WIDTH ; i++)
{
// 因为我们用的是 RGB 888 相当于 占据了 3个字节
// 我们使用的是 u8* 类型的 所以就如同下面写的那样 三个才表示一个数据
//
(vdma_buffer_addr + jWIDTH3 + i3+0 ) = 0xff ; //往像素的红色通道写入FF
(vdma_buffer_addr + jWIDTH3 + i3+1 ) = 0x00 ; //往像素的绿色通道写入00
(vdma_buffer_addr + jWIDTH3 + i3+2 ) = 0x00 ; //往像素的蓝色通道写入00
}
}
return 0  ;
}

我们在上电之后发现现象不对 开始修改
一个是红色和蓝色 的不对 还有一个是 只显示了一部分的颜色

为什么会没写好呢 是因为 我们 PS端的DDR控制器 会缓存一部分数据
我们需要把缓存的数据强行冲出来
void Xil_DCacheFlush(void); 添加 函数
下面是修改之后的代码

#include "stdio.h"
#include"xparameters.h"
#include "xaxivdma.h"
#include "vdma_api.h"
#include "xil_cache.h"
#define VDMA_ID            XPAR_AXIVDMA_0_DEVICE_ID
#define DDR_BASE_ADDR      XPAR_PS7_DDR_0_S_AXI_BASEADDR  // DDR存储空间 的起始地址
//这个是 DDR的基地址 我们是需要写一个彩条图案 但是 彩条图案总不能从基地址
//开始,因为我们程序 也是 从基地址 开始运行的 。 如果彩条图案是从基地址开始
//运行的话 ,就会给我们程序带来冲突  所以我们要重新定义一个帧缓存的地址
// 把宏定义的形式 改写成 变量的形式 这样在 后续可以更方便使用
int frame_buffer_addr  = (DDR_BASE_ADDR + 0x1000000)  ;// VDMA 帧缓存的地址
#define WIDTH   800  // 图像的宽度
#define HEIGHT  480  // 图像的高度
int main()
{
int i , j ;
u8* vdma_buffer_addr ;
vdma_buffer_addr = (u8*) frame_buffer_addr ;


XAxiVdma vdma_inst;


// 配置并启动 VDMA

run_triple_frame_buffer(
&vdma_inst,        // vdma驱动实例
VDMA_ID,           // VDMA 的 ID信息
WIDTH,             //  图像的水平尺寸  宽度
HEIGHT,            //  图像的高度
frame_buffer_addr,   //  VDMA 究竟从DMA的哪个地址开始读取图像// VDMA 帧缓存的起始地址
0,
0);
//  往 VDMA 的帧缓存里面 写入 图案
for(j=0;j<HEIGHT ; j++){
for(i=0 ; i<WIDTH ; i++)
{
// 因为我们用的是 RGB 888 相当于 占据了 3个字节
// 我们使用的是 u8* 类型的 所以就如同下面写的那样 三个才表示一个数据
//
(vdma_buffer_addr + jWIDTH3 + i3+0 ) = 0x00 ; //往像素的蓝色通道写入FF
(vdma_buffer_addr + jWIDTH3 + i3+1 ) = 0x00 ; //往像素的绿色通道写入00
(vdma_buffer_addr + jWIDTH3 + i3+2 ) = 0xff ; //往像素的红色通道写入00
}
}
//将cache缓存的数据冲出来
Xil_DCacheFlush();
return 0  ;
}

纯色模块显示完毕 下面展示彩条代码的书写

#include "stdio.h"
#include"xparameters.h"
#include "xaxivdma.h"
#include "vdma_api.h"
#include "xil_cache.h"
#define VDMA_ID            XPAR_AXIVDMA_0_DEVICE_ID
#define DDR_BASE_ADDR      XPAR_PS7_DDR_0_S_AXI_BASEADDR  // DDR存储空间 的起始地址
//这个是 DDR的基地址 我们是需要写一个彩条图案 但是 彩条图案总不能从基地址
//开始,因为我们程序 也是 从基地址 开始运行的 。 如果彩条图案是从基地址开始
//运行的话 ,就会给我们程序带来冲突  所以我们要重新定义一个帧缓存的地址
// 把宏定义的形式 改写成 变量的形式 这样在 后续可以更方便使用
int frame_buffer_addr  = (DDR_BASE_ADDR + 0x1000000)  ;// VDMA 帧缓存的地址
#define WIDTH   800  // 图像的宽度
#define HEIGHT  480  // 图像的高度
int main()
{
int i , j ;
u8* vdma_buffer_addr ;
vdma_buffer_addr = (u8*) frame_buffer_addr ;


XAxiVdma vdma_inst;


// 配置并启动 VDMA

run_triple_frame_buffer(
&vdma_inst,        // vdma驱动实例
VDMA_ID,           // VDMA 的 ID信息
WIDTH,             //  图像的水平尺寸  宽度
HEIGHT,            //  图像的高度
frame_buffer_addr,   //  VDMA 究竟从DMA的哪个地址开始读取图像// VDMA 帧缓存的起始地址
0,
0);
//  往 VDMA 的帧缓存里面 写入 图案
for(j=0;j<HEIGHT ; j++){
for(i=0 ; i<WIDTH ; i++)
{
// 因为我们用的是 RGB 888 相当于 占据了 3个字节
// 我们使用的是 u8* 类型的 所以就如同下面写的那样 三个才表示一个数据
//
if(i < WIDTH/3) {
(vdma_buffer_addr + jWIDTH3 + i3+0 ) = 0x00 ; //往像素的蓝色通道写入FF
(vdma_buffer_addr + jWIDTH3 + i3+1 ) = 0x00 ; //往像素的绿色通道写入00
(vdma_buffer_addr + jWIDTH3 + i3+2 ) = 0xff ; //往像素的红色通道写入00
}
else if( i <(2WIDTH)/3   ){(vdma_buffer_addr + jWIDTH3 + i3+0 ) = 0x00 ; //往像素的蓝色通道写入FF(vdma_buffer_addr + jWIDTH3 + i3+1 ) = 0xff ; //往像素的绿色通道写入00(vdma_buffer_addr + jWIDTH3 + i3+2 ) = 0x00 ; //往像素的红色通道写入00}else{(vdma_buffer_addr + jWIDTH3 + i3+0 ) = 0xff ; //往像素的蓝色通道写入FF(vdma_buffer_addr + jWIDTH3 + i3+1 ) = 0x00 ; //往像素的绿色通道写入00(vdma_buffer_addr + jWIDTH3 + i*3+2 ) = 0x00 ; //往像素的红色通道写入00
}
 }

}
//将cache缓存的数据冲出来
Xil_DCacheFlush();
return 0  ;
}

http://www.kler.cn/a/135022.html

相关文章:

  • 如何为电子课程创造创意
  • 去地面算法——depth_clustering算法调试(1)
  • kafka消费数据太慢了,给优化下
  • 使用支付宝沙箱完成商品下单
  • Python标准库模块的使用:math、datetime
  • 【大数据技术基础 | 实验十】Hive实验:部署Hive
  • android studio导入eclipse项目
  • SpringBoot中文乱码问题解决方案
  • Git常用操作-MD
  • 系列十、ReentrantReadWriteLock
  • Ubuntu 安装VMware Tools选项显示灰色,如何安装VMware Tools
  • 红海营销时代,内容占位的出海品牌更有机会营销占位
  • 探讨MySQL存储过程返回记录集
  • JSON 格式的接口测试流程【Eolink Apikit】
  • 推荐一个windows上传linux服务器/linux服务器的docker镜像的工具,摆脱docker cp,以及解决常见问题。
  • C#的WebRequest类
  • selenium
  • 达芬奇DaVinci Resolve Studio 18.6.3 for Mac
  • 三、机器学习基础知识:Python常用机器学习库(图像处理相关库)
  • Qt的委托代理机制
  • gRPC 四模式之 双向流RPC模式
  • 安全加速cdn可以起到什么作用?
  • Docker中的RabbitMQ已经启动运行,但是管理界面打不开
  • 36、Flink 的 Formats 之Parquet 和 Orc Format
  • 【Python百宝箱】图解未来:数据可视化引领智慧决策时代
  • 15.ORACLE11g的归档方式和日志文件的相关操作