欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 会展 > 15 - VDMA之SD卡读BMP图片显示实验

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

2025/8/11 12:50:15 来源:https://blog.csdn.net/XDUryan/article/details/147396880  浏览:    关键词: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;
}/*****************************************************************************/

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词