当前位置:   article > 正文

ZYNQ系列之-----SD卡中BMP图片读取+ddr读写验证_fpga 通过sd卡向ddr加载数据

fpga 通过sd卡向ddr加载数据

1、前提:

sd卡挂载在ps测,并且使用的ZYNQ系统。和前文是一样的。

ZYNQ系列之-----SD卡读写文件_hhh_fpga的博客-CSDN博客

2、设备与软件


        软件: vivado 2021.2 及其配套的软件。

硬件: ZCU106开发板。

3、PL测SD的设置


4、VITIS软件设置


在“Board Support Package Settings”中设置“xilffs”

 

 这里的"use_lfn"选项要设置为1之后,就可以操作sd卡中的名字比较长的文件。

 5、BMP信息头:

名称

占用空间

起始地址(十进制)

内容

实际数据

bfType

2字节

0

标识,就是“BM”二字

BM

bfSize

4字节

2

整个BMP文件的大小

x

bfReserved1/2

4字节

6

保留字,没用

0

bfOffBits

4字节

10

偏移数,即 位图文件头+位图信息头+调色板 的大小

0x36(54)

biSize

4字节

14

位图信息头的大小,为40

0x28(40)

biWidth

4字节

18

位图的宽度,单位是像素

x

biHeight

4字节

22

位图的高度,单位是像素

x

biPlanes

2字节

24

固定值1

1

biBitCount

2字节

26

每个像素的位数

1-黑白图,4-16色,8-256色,24-真彩色

0x18(24)

biCompression

4字节

30

压缩方式,BI_RGB(0)为不压缩

0

biSizeImage

4字节

34

位图全部像素占用的字节数,BI_RGB时可设为0

x

biXPelsPerMeter

4字节

38

水平分辨率(像素/米)

0

biYPelsPerMeter

4字节

42

垂直分辨率(像素/米)

0

biClrUsed

4字节

46

位图使用的颜色数

如果为0,则颜色数为2的biBitCount次方

0

biClrImportant

4字节

50

重要的颜色数,0代表所有颜色都重要

0

Eg: 1920*1080 24bitbmp图片:解析出来的内容

 6、C代码 BMP的head获取;

打印结果:如上图所示

  1. void report_bmp_head(char *FileName)
  2. {
  3. u32 Status;
  4. u32 header_addr;
  5. u32 header_data;
  6. u32 len = 54;
  7. Status=SD_read(FileName, (u32)BMP_RD_Buf, len,0);
  8. if (Status==XST_FAILURE)
  9. {
  10. return XST_FAILURE;
  11. }
  12. printf("\r\n");
  13. printf("bmp name : %s \r\n",FileName);
  14. header_addr = 0;
  15. printf("bmp bfType = %c%c \r\n",BMP_RD_Buf[header_addr],BMP_RD_Buf[header_addr+1]);
  16. header_addr = header_addr + 2;
  17. printf("bmp bfSize = 0x%x%x%x%x \r\n",BMP_RD_Buf[header_addr+3],BMP_RD_Buf[header_addr+2],BMP_RD_Buf[header_addr+1],BMP_RD_Buf[header_addr]);
  18. header_addr = header_addr + 8;
  19. printf("bmp bfOffBits = 0x%x%x%x%x \r\n",BMP_RD_Buf[header_addr+3],BMP_RD_Buf[header_addr+2],BMP_RD_Buf[header_addr+1],BMP_RD_Buf[header_addr]);
  20. header_addr = header_addr + 4;
  21. header_data = (BMP_RD_Buf[header_addr+3]<<24)|(BMP_RD_Buf[header_addr+2]<<16)|(BMP_RD_Buf[header_addr+1]<<8)|(BMP_RD_Buf[header_addr]);
  22. printf("bmp bitSize = %d \r\n",header_data);
  23. header_addr = header_addr + 4;
  24. header_data = (BMP_RD_Buf[header_addr+3]<<24)|(BMP_RD_Buf[header_addr+2]<<16)|(BMP_RD_Buf[header_addr+1]<<8)|(BMP_RD_Buf[header_addr]);
  25. printf("bmp biWidth = %d \r\n",header_data);
  26. header_addr = header_addr + 4;
  27. header_data = (BMP_RD_Buf[header_addr+3]<<24)|(BMP_RD_Buf[header_addr+2]<<16)|(BMP_RD_Buf[header_addr+1]<<8)|(BMP_RD_Buf[header_addr]);
  28. printf("bmp biHeight = %d \r\n",header_data);
  29. header_addr = header_addr + 6;
  30. header_data = (BMP_RD_Buf[header_addr+1]<<8)|(BMP_RD_Buf[header_addr]);
  31. printf("bmp biBitCount = %d \r\n",header_data);
  32. header_addr = header_addr + 2;
  33. printf("bmp biCompression = 0x%x%x%x%x \r\n",BMP_RD_Buf[header_addr+3],BMP_RD_Buf[header_addr+2],BMP_RD_Buf[header_addr+1],BMP_RD_Buf[header_addr]);
  34. header_addr = header_addr + 4;
  35. printf("bmp biSizeImage = 0x%x%x%x%x \r\n",BMP_RD_Buf[header_addr+3],BMP_RD_Buf[header_addr+2],BMP_RD_Buf[header_addr+1],BMP_RD_Buf[header_addr]);
  36. header_addr = header_addr + 4;
  37. header_data = (BMP_RD_Buf[header_addr+3]<<24)|(BMP_RD_Buf[header_addr+2]<<16)|(BMP_RD_Buf[header_addr+1]<<8)|(BMP_RD_Buf[header_addr]);
  38. printf("bmp biXPelsPerMeter = %d \r\n",header_data);
  39. header_addr = header_addr + 4;
  40. header_data = (BMP_RD_Buf[header_addr+3]<<24)|(BMP_RD_Buf[header_addr+2]<<16)|(BMP_RD_Buf[header_addr+1]<<8)|(BMP_RD_Buf[header_addr]);
  41. printf("bmp biYPelsPerMeter = %d \r\n",header_data);
  42. }

7、读取BMP内容,并存储到ddr中:

这里没有对BMP的顺序进行调换,所以后续还要调换一下的。

这里根据从bmp的头部内容,自动读取每一行的数据,并按顺序存入到ddr的缓存中。

  1. //------ FileName: bmp name ;;; frame: ddr address.
  2. void load_sd_bmp(char *FileName,u32 frame)
  3. {
  4. u32 Status,i,j;
  5. u32 len = 57;
  6. u32 bmp_Width,bmp_Height,bmp_size,bmp_headsize;
  7. u32 bmp_data;
  8. u32 bmp_r,bmp_g,bmp_b;
  9. printf("\r\n");
  10. printf("\r\n");
  11. printf("\r\n");
  12. printf("######### load %s ########## \r\n",FileName);
  13. Status=SD_read(FileName, (u32)BMP_RD_Buf, len+1,0);
  14. if (Status==XST_FAILURE)
  15. {
  16. return XST_FAILURE;
  17. }
  18. bmp_headsize = (BMP_RD_Buf[13]<<24)|(BMP_RD_Buf[12]<<16)|(BMP_RD_Buf[11]<<8)|(BMP_RD_Buf[10]);
  19. bmp_Width = (BMP_RD_Buf[21]<<24)|(BMP_RD_Buf[20]<<16)|(BMP_RD_Buf[19]<<8)|(BMP_RD_Buf[18]);
  20. bmp_Height = (BMP_RD_Buf[25]<<24)|(BMP_RD_Buf[24]<<16)|(BMP_RD_Buf[23]<<8)|(BMP_RD_Buf[22]);
  21. bmp_size = (BMP_RD_Buf[37]<<24)|(BMP_RD_Buf[36]<<16)|(BMP_RD_Buf[35]<<8)|(BMP_RD_Buf[34]);
  22. printf("bmp_Width = %d ,bmp_Height = %d ,bmp_size = %d ,bmp_headsize = %d \r\n",bmp_Width,bmp_Height,bmp_size,bmp_headsize);
  23. // Status=SD_read(FileName, (u32)BMP_RD_Buf, bmp_size+bmp_headsize+1);
  24. for(i=0;i<bmp_Height;i++)
  25. {
  26. Status=SD_read(FileName, (u32)BMP_RD_Buf, bmp_Width*3, i*bmp_Width*3+bmp_headsize);
  27. for(j=0;j<bmp_Width;j++)
  28. {
  29. bmp_r =BMP_RD_Buf[j*3];
  30. bmp_g =BMP_RD_Buf[j*3+1];
  31. bmp_b =BMP_RD_Buf[j*3+2];
  32. bmp_data = (bmp_r<<24)|(bmp_g<<16)|(bmp_b<<8)|0x0;
  33. Xil_Out32(frame+((j+i*bmp_Width)<<2),bmp_data);
  34. }
  35. }
  36. printf("######### BMP write finish ########## \r\n");
  37. }

8、调用,并验证:

使用1920*1080 24bit的bmp进行验证。

这里的frame_buffer_addr地址,不要直接等于XPAR_DDR_MEM_BASEADDR,

如果frame_buffer_addr 直接等于XPAR_DDR_MEM_BASEADDR的话,在往ddr写入大量数据的时候,会卡死,数据量少不会卡死。

  1. //------------------ bmp --------------------------------------
  2. report_bmp_head("blue_test_1920x1080.bmp");
  3. u32 frame_buffer_addr = XPAR_DDR_MEM_BASEADDR+0x01000000 ;
  4. load_sd_bmp("blue_test_1920x1080.bmp", frame_buffer_addr);
  5. //--------- 验证一部分ddr的内容
  6. for(i=0; i<len;i++)
  7. {
  8. Status = Xil_In32( (i<<2) + frame_buffer_addr);
  9. printf("ddr_address:%x data = %x \r\n ",(i<<2) + frame_buffer_addr,Status);
  10. }

bmp文件hex截图:

 串口打印结果:与BMP图片一致。

 

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号