zynq板zedboard+SDK设计(一)读取SD中bmp图片存入DDR

本文详细介绍了如何在Zedboard开发板上使用Vivado2019.1SDK从SD卡读取BMP图像,并将其存储到DDR内存中。文章涵盖了BMP图像的位深概念,文件结构,以及利用FATFS进行文件操作的方法。通过读取文件头和信息头来解析图像尺寸,并将像素数据写入DDR。
摘要由CSDN通过智能技术生成

0.前言

本文讲的是如何读取SD卡中的BMP图像并存入DDR中

使用的开发板是zedboard

vivado使用的是2019.1配套SDK

1.bmp图像

讲程序之前先简单说一下bmp图像

1.1bmp位深

BMP是位图(bitmap),可以分为1、4、8、16、24及32位图像等。

1位深的bmp图只有2^{1}种颜色,就是纯粹的黑白图片。图中1个像素点占1个比特位,即1个字节可以描述8个像素点。

8位深的bmp图有2^{8}种颜色,通常是灰度图,即由不同程度的黑白色构成的图像,也可以是伪彩色图,即由较少色彩构成的图像。该图中1个像素点占1个字节,即1个字节可以描述1个像素点。

24位深的bmp图有2^{24}种颜色,称为真彩色图。24个比特位以8位一组分三个通道,即RGB通道。该图中1个像素点占3个字节,即3个字节可以描述1个像素点。

1.2bmp图像构成

BMP文件由以下四部分组成:

  • 位图文件头:用于描述整个bmp文件的情况,具体包括BMP文件的类型、文件大小和位图起始位置等信息。
  • 位图信息头:含有 BMP 图像的宽、高、压缩方法,以及定义颜色等信息。
  • 颜色表:用于说明位图中的颜色(24位深的bmp图像没有颜色表)。
  • 像素阵列:记录位图的每一个像素点(记录顺序是在扫描行内是从左到右,扫描行之间是从下到上)。

 在属性的详细信息内可以看见图像的宽、高及位深信息

这里用notepad++打开该图

 画红线的部分是文件头,绿色部分是信息头,紫色部分是颜色表,橙色部分一直到最后都是像素矩阵。

其中文件头每一位的具体含义如下表

 其中信息头每一位的具体含义如下表

 举个例子

 图中黑圈内的两个四字节数就是图像的宽和高,因为这里是小端存储的,所以宽和高分别是00000114和00000114,换成10进制就是276,和从图像属性内看到的一致。

2.bd部分

本文设计的SD卡读取及对DDR的写入只需要zynq本身就可以完成,因此BlockDesign中添加一个zynq核并打开SD以及其他基本配置即可。

3.SDK部分

3.1读取SD卡前置设置

 如图所示,读取SD卡前需要先右击bsp文件选择board support package setting,然后勾选xilffs,然后选择下面的xilffs页面,将use_lfn后面的value中的0改为1。xilffs是打开SD卡需要使用的工具,use_lfn是允许读取长整型的文件名

3.2代码

完整代码如下

#include "xparameters.h"
#include "xil_printf.h"
#include "ff.h"
#include "xdevcfg.h"
#include "stdio.h"
#include "xil_io.h"
#include <stdlib.h>
#include <string.h>
#include "xil_types.h"
#include "xil_cache.h"

#define FILE_NAME "cat.bmp"                //定义文件名
static FATFS fatfs;                         //文件系统

unsigned int const DDR_buffer_addr = 0x01000000;//DDR地址

//初始化SD卡
u32 Init()
{
    FRESULT result;
    TCHAR *Path = "0:/";
    result =f_mount(&fatfs,Path, 0);    
        if(result){
               printf("error : f_mount returned error \r\n");

               return XST_FAILURE;
                  }

    return XST_SUCCESS ;
}

//SD卡写函数
u32 Write(char *FileName,u32 src_addr,u32 byte_len,u32 start_addr)
{
    FIL file;       //文件对象
    FRESULT result;
    UINT BytesWr;   //f_write函数返回已写入的字节数

    result = f_open(&file,FileName,FA_CREATE_ALWAYS | FA_WRITE);//打开一个文件,如果不存在,则创建一个文件
    if(result)
    {
        printf("error : f_open returned error \r\n");
        return XST_FAILURE;
    }

    result = f_lseek(&file, start_addr);//移动打开的文件对象的文件读/写指针,相当于将鼠标放在文件的某个开始位置。
    if(result)
    {
        printf("error : f_lseek returned error \r\n");
        return XST_FAILURE;
    }

    result = f_write(&file,(void*) src_addr,byte_len,&BytesWr);//写文件内容
    if(result)
    {
        printf("error : f_write returned error \r\n");
        return XST_FAILURE;
    }

    result = f_close(&file);    //关闭一个文件
    if(result){
        printf("error : f_close returned error \r\n");
        return XST_FAILURE;
    }

    return XST_SUCCESS;
}

//SD卡读函数
u32 Read(char *FileName,u32 DestinationAddress,u32 ByteLength,u32 start_addr)
{
    FIL file;    //文件对象
    FRESULT result;
    UINT BytesRd;    //f_read函数返回已读出的字节数

    result = f_open(&file,FileName,FA_READ);    //打开一个只读的文件
    if(result)
    {
        printf("error : f_open returned error \r\n");
        return XST_FAILURE;
    }

    result = f_lseek(&file,start_addr);    //相当于将鼠标放在文件的某个开始位置。
    if(result)
    {
        printf("error : f_lseek returned error \r\n");
        return XST_FAILURE;
    }

    result = f_read(&file, (void*)DestinationAddress,ByteLength,&BytesRd);//读文件内容
    if(result)
    {
        printf("error : f_read returned error \r\n");
        return XST_FAILURE;
    }

    result = f_close(&file);//关闭一个文件
    if(result)
    {
        printf("error : f_close returned error \r\n");
        return XST_FAILURE;
    }
    return XST_SUCCESS;
}

//main函数
int main()
{
    int Status,i,j,j_1,j_2,k,k_1,line_cnt,line_last,signal_cnt;
    u8 bmp_head[54];
    UINT *bmp_width,*bmp_height,*bmp_size,*offbit;

    Init();

    //读取bmp图像头文件
     Status=Read(FILE_NAME, bmp_head, 54, 0);
     if (Status==XST_FAILURE)
     {
         return XST_FAILURE;
     }
     //读取信息头,并显示图像高、宽、大小以及像素数据开始位等信息
     xil_printf("cat.bmp head: \r");
     for(i=0;i<54;i++)
         xil_printf(" %x",bmp_head[i]);

     bmp_width = (UINT *)(bmp_head + 0x12);
     bmp_height = (UINT *)(bmp_head + 0x16);
     bmp_size = (UINT *)(bmp_head + 0x22);
     offbit = (UINT *)(bmp_head + 0x0A);
     xil_printf("\n width = %d, height = %d, size = %d, offbit = %d bytes \r",
             *bmp_width,*bmp_height,*bmp_size,*offbit);

//每次一行,将图像中除了信息头以及颜料表之外的像素数据存入DDR
     for(i=0;i<=*bmp_height-1;i++){
         Read(FILE_NAME,DDR_buffer_addr+i*(*bmp_width),(*bmp_width),(*offbit)+i*(*bmp_width));
     }

  }

terminal内打印出文件的文件头和信息头数据,和前面的对比没有问题

 debug模式下,可以看见图像的数据被写入了ddr内

 4.结语

本文都是比较基础的应用,如有错误,欢迎指正。

  • 7
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值