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

15 - VDMA之SD卡读BMP图片显示实验

文章目录

  • 1 实验任务
  • 2 系统框图
  • 3 硬件设计
  • 4 软件设计
    • 4.1 工程架构
    • 4.2 工程源码
      • 4.2.1 sd_api.h文件
      • 4.2.2 sd_api.c文件
      • 4.2.3 main.c文件

1 实验任务

本实验任务是PS端从SD卡读取bmp格式图片到DDR3内存中,然后通过PL端的VDMA IP核将bmp图片读出,通过HDMI接口按照1080p@60Hz的时序输出显示。

2 系统框图

参见14.1。

3 硬件设计

注意事项:基于14.1做如下改动

  1. 在PS配置中勾选SD卡即可。

4 软件设计

注意事项:

  1. 在Board Support Package Settings➡Overview中,勾选xilffs选项。

4.1 工程架构

工程架构如下图所示:
在这里插入图片描述

4.2 工程源码

4.2.1 sd_api.h文件

代码如下所示:

/*****************************************************************************/#ifndef SRC_SD_SD_API_H_
#define SRC_SD_SD_API_H_/*****************************************************************************/#include "ff.h"/*****************************************************************************/// BMP文件头结构体
#pragma pack(push, 1)       // 确保结构体按1字节对齐
typedef struct {u16 bfType;             // 文件类型,必须是"BM"u32 bfSize;             // 文件大小u16 bfReserved1;        // 保留,必须为0u16 bfReserved2;        // 保留,必须为0u32 bfOffBits;          // 从文件头到像素数据的偏移
} BMPFileHeader;typedef struct {u32 biSize;             // 信息头大小u32 biWidth;            // 图像宽度(像素)u32 biHeight;           // 图像高度(像素)u16 biPlanes;           // 颜色平面数,必须为1u16 biBitCount;         // 每像素位数u32 biCompression;      // 压缩类型u32 biSizeImage;        // 图像大小(字节)u32 biXPelsPerMeter;    // 水平分辨率(像素/米)u32 biYPelsPerMeter;    // 垂直分辨率(像素/米)u32 biClrUsed;          // 使用的颜色数u32 biClrImportant;     // 重要颜色数
} BMPInfoHeader;
#pragma pack(pop)           // 恢复默认对齐方式/*****************************************************************************/int SdCardInit(FATFS* FatFsInstPtr);
int ReadSdCardBmpToDDR(const char* FileName, u8* DdrAddr);/*****************************************************************************/#endif /* SRC_SD_SD_API_H_ *//*****************************************************************************/

4.2.2 sd_api.c文件

代码如下所示:

/*****************************************************************************/#include "stdio.h"
#include "xstatus.h"
#include "xil_cache.h"
#include "sd_api.h"/*****************************************************************************/// 初始化文件系统
int SdCardInit(FATFS* FatFsInstPtr)
{//FRESULT Status;TCHAR *Path = "0:/";BYTE work[FF_MAX_SS];// 挂载SD卡(到一个具体的文件系统对象上)Status = f_mount(FatFsInstPtr, Path, 1);if (Status != FR_OK) {printf("Error : logical drive needs to be formatted.\n");//格式化SD卡Status = f_mkfs(Path, FM_FAT32, 0, work, sizeof(work));if (Status != FR_OK) {printf("Error : logical drive formatting failed.\n");return XST_FAILURE;}//格式化之后,重新挂载SD卡Status = f_mount(FatFsInstPtr, Path, 1);if (Status != FR_OK) {printf("Error : logical drive mounting failed.\n");return XST_FAILURE;}}//return XST_SUCCESS;
}/*****************************************************************************/int ReadSdCardBmpToDDR(const char* FileName, u8* DdrAddr)
{//FIL FileObj;            // 文件对象FRESULT FatFsRes;       // FatFs返回结果UINT BytesRead;        	// 实际读取的字节数UINT ImageLineSize;// 1. 打开BMP文件FatFsRes = f_open(&FileObj, FileName, FA_READ);if (FatFsRes != FR_OK) {printf("Error : file open failed.\n");return XST_FAILURE;}// 2. 读取BMP文件头BMPFileHeader FileHeader;FatFsRes = f_read(&FileObj, &FileHeader, sizeof(BMPFileHeader), &BytesRead);if (FatFsRes != FR_OK || BytesRead != sizeof(BMPFileHeader)) {printf("Error : bmp file header read failed.\n");f_close(&FileObj);return XST_FAILURE;}// 3. 检查文件类型是否为"BM"if (FileHeader.bfType != 0x4D42) {printf("Error : not a valid bmp file.\n");f_close(&FileObj);return XST_FAILURE;}// 4. 读取BMP信息头BMPInfoHeader InfoHeader;FatFsRes = f_read(&FileObj, &InfoHeader, sizeof(BMPInfoHeader), &BytesRead);if (FatFsRes != FR_OK || BytesRead != sizeof(BMPInfoHeader)) {printf("Error : bmp info header read failed.\n");f_close(&FileObj);return XST_FAILURE;}printf("BMP Image Info :\n");printf("\t\tImage Width\t\t= %lu pixels\n", InfoHeader.biWidth);printf("\t\tImage Height\t\t= %lu pixels\n", InfoHeader.biHeight);printf("\t\tImage BitDepth\t= %hu bits\n", InfoHeader.biBitCount);printf("\t\tImage Size\t\t= %lu bytes\n", InfoHeader.biSizeImage);// 5. 定位到像素数据开始位置FatFsRes = f_lseek(&FileObj, FileHeader.bfOffBits);if (FatFsRes != FR_OK) {printf("Error : seeking to pixel data failed.\n");f_close(&FileObj);return XST_FAILURE;}// 6. 读取像素数据到DDRImageLineSize = InfoHeader.biWidth * InfoHeader.biBitCount / 8;for (int i = InfoHeader.biHeight - 1; i >= 0; i--) {//FatFsRes = f_read(&FileObj, DdrAddr + i * ImageLineSize, ImageLineSize, &BytesRead);if (FatFsRes != FR_OK || BytesRead != ImageLineSize) {printf("Error : pixel data read failed.\n");f_close(&FileObj);return XST_FAILURE;}}// 7.刷新DCacheXil_DCacheFlushRange((INTPTR)DdrAddr, InfoHeader.biSizeImage);// 8. 关闭文件f_close(&FileObj);//return XST_SUCCESS;
}/*****************************************************************************/

4.2.3 main.c文件

代码如下所示:

/********************************************************************/#include "vdma/vdma_api.h"
#include "sd/sd_api.h"#include "xparameters.h"
#include "stdio.h"
#include "sleep.h"/********************************************************************/#define VDMA_DEVICE_ID		XPAR_AXIVDMA_0_DEVICE_ID
#define MEMORY_BASEADDR		XPAR_PS7_DDR_0_S_AXI_BASEADDR#define IMAGE_WIDTH			1920
#define IMAGE_HEIGHT		1080/********************************************************************//********************************************************************/XAxiVdma VdmaInst;
FATFS FatFsInst;int FrameBufferAddr = (MEMORY_BASEADDR + 0x02000000);char* FileName = "TestBmp_1920x1080.bmp";
/********************************************************************/int main()
{//int Status;u8* VdmaBufferAddr = (u8*)FrameBufferAddr;// SD卡初始化Status = SdCardInit(&FatFsInst);if (Status == XST_FAILURE) {printf("Error : SD card initialization failed.\n");}else {printf("SD card initialization succeeded.\n");}// 从SD卡中读取BMP图片写入DDR中Status = ReadSdCardBmpToDDR(FileName, VdmaBufferAddr);if (Status == XST_FAILURE) {printf("Error : SD card read failed.\n");}else {printf("SD card read succeeded.\n");}// 启动VDMA读操作Status = run_vdma_frame_buffer(&VdmaInst, VDMA_DEVICE_ID, IMAGE_WIDTH, IMAGE_HEIGHT, FrameBufferAddr, 0, 0, ONLY_READ);if (Status == XST_FAILURE) {printf("Error : run vdma frame buffer failed.\n");}else {printf("Run vdma frame buffer succeeded.\n");}//while (1) {//sleep(10);printf("Stop vdma channel.\n");XAxiVdma_DmaStop(&VdmaInst, XAXIVDMA_READ);//sleep(5);printf("Start vdma channel.\n");XAxiVdma_DmaStart(&VdmaInst, XAXIVDMA_READ);}//return XST_SUCCESS;
}/*****************************************************************************/
http://www.xdnf.cn/news/855.html

相关文章:

  • Unity中的数字孪生项目:两种输入方式对观察物体的实现
  • Linux系统安全及应用
  • android studio sdk unavailable和Android 安装时报错:SDK emulator directory is missing
  • Office文件内容提取 | 获取Word文件内容 |Javascript提取PDF文字内容 |PPT文档文字内容提取
  • 边缘计算场景下的GPU虚拟化实践(基于vGPU的QoS保障与算力隔离方案)
  • ‌信号调制与解调技术基础解析
  • Docker 集成KingBase
  • 瑞吉外卖-分页功能开发中的两个问题
  • 【分布式理论17】分布式调度3:分布式架构-从中央式调度到共享状态调度
  • 8.1 线性变换的思想
  • 基于遗传算法的智能组卷系统设计与实现(springboot+ssm+React+mysql)含万字详细文档
  • Elasticsearch中的_source字段讲解
  • hadoop与spark的区别和联系
  • 大模型面经 | 春招、秋招算法面试常考八股文附答案(三)
  • 主流大模型(如OpenAI、阿里云通义千问、Anthropic、Hugging Face等)调用不同API的参数说明及对比总结
  • 53、Spring Boot 详细讲义(十)(Spring Boot 高级主题)
  • Python自动化selenium-一直卡着不打开浏览器怎么办?
  • 2025.4.21总结
  • 【架构】-- StarRocks 和 Doris 介绍与选型建议
  • [密码学实战]密评考试训练系统v1.0程序及密评参考题库(获取路径在文末)
  • 8086微机原理与接口技术复习(1)存储器(2)接口
  • 爬虫学习——LinkEXtractor提取链接与Exporter导出数据
  • 强化学习笔记(三)——表格型方法(蒙特卡洛、时序差分)
  • P3959 [NOIP 2017 提高组] 宝藏
  • 图形编辑器基于Paper.js教程27:对图像描摹的功能实现,以及参数调整
  • 一款支持多线程的批量任务均衡器
  • Craft 是什么:腾讯 Cloud Studio 中的 CodeBuddy 提供了 Craft 功能
  • 阻塞队列-ArrayBlockingQueue
  • 【Linux专栏】zip 多个文件不带路径
  • 入选AAAI 2025,浙江大学提出多对一回归模型M2OST,利用数字病理图像精准预测基因表达