赞
踩
sd卡挂载在ps测,并且使用的ZYNQ系统。和前文是一样的。
ZYNQ系列之-----SD卡读写文件_hhh_fpga的博客-CSDN博客
软件: vivado 2021.2 及其配套的软件。
硬件: ZCU106开发板。
在“Board Support Package Settings”中设置“xilffs”
这里的"use_lfn"选项要设置为1之后,就可以操作sd卡中的名字比较长的文件。
名称 | 占用空间 | 起始地址(十进制) | 内容 | 实际数据 |
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 24bit的bmp图片:解析出来的内容
打印结果:如上图所示
- void report_bmp_head(char *FileName)
- {
- u32 Status;
- u32 header_addr;
- u32 header_data;
-
- u32 len = 54;
-
- Status=SD_read(FileName, (u32)BMP_RD_Buf, len,0);
- if (Status==XST_FAILURE)
- {
-
- return XST_FAILURE;
- }
- printf("\r\n");
- printf("bmp name : %s \r\n",FileName);
- header_addr = 0;
- printf("bmp bfType = %c%c \r\n",BMP_RD_Buf[header_addr],BMP_RD_Buf[header_addr+1]);
- header_addr = header_addr + 2;
- 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]);
- header_addr = header_addr + 8;
- 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]);
- header_addr = header_addr + 4;
- 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]);
- printf("bmp bitSize = %d \r\n",header_data);
- header_addr = header_addr + 4;
- 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]);
- printf("bmp biWidth = %d \r\n",header_data);
- header_addr = header_addr + 4;
- 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]);
- printf("bmp biHeight = %d \r\n",header_data);
- header_addr = header_addr + 6;
- header_data = (BMP_RD_Buf[header_addr+1]<<8)|(BMP_RD_Buf[header_addr]);
- printf("bmp biBitCount = %d \r\n",header_data);
- header_addr = header_addr + 2;
- 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]);
- header_addr = header_addr + 4;
- 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]);
- header_addr = header_addr + 4;
- 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]);
- printf("bmp biXPelsPerMeter = %d \r\n",header_data);
- header_addr = header_addr + 4;
- 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]);
- printf("bmp biYPelsPerMeter = %d \r\n",header_data);
- }
这里没有对BMP的顺序进行调换,所以后续还要调换一下的。
这里根据从bmp的头部内容,自动读取每一行的数据,并按顺序存入到ddr的缓存中。
- //------ FileName: bmp name ;;; frame: ddr address.
- void load_sd_bmp(char *FileName,u32 frame)
- {
- u32 Status,i,j;
- u32 len = 57;
-
- u32 bmp_Width,bmp_Height,bmp_size,bmp_headsize;
- u32 bmp_data;
- u32 bmp_r,bmp_g,bmp_b;
-
- printf("\r\n");
- printf("\r\n");
- printf("\r\n");
- printf("######### load %s ########## \r\n",FileName);
- Status=SD_read(FileName, (u32)BMP_RD_Buf, len+1,0);
- if (Status==XST_FAILURE)
- {
- return XST_FAILURE;
- }
-
- bmp_headsize = (BMP_RD_Buf[13]<<24)|(BMP_RD_Buf[12]<<16)|(BMP_RD_Buf[11]<<8)|(BMP_RD_Buf[10]);
- bmp_Width = (BMP_RD_Buf[21]<<24)|(BMP_RD_Buf[20]<<16)|(BMP_RD_Buf[19]<<8)|(BMP_RD_Buf[18]);
- bmp_Height = (BMP_RD_Buf[25]<<24)|(BMP_RD_Buf[24]<<16)|(BMP_RD_Buf[23]<<8)|(BMP_RD_Buf[22]);
- bmp_size = (BMP_RD_Buf[37]<<24)|(BMP_RD_Buf[36]<<16)|(BMP_RD_Buf[35]<<8)|(BMP_RD_Buf[34]);
- printf("bmp_Width = %d ,bmp_Height = %d ,bmp_size = %d ,bmp_headsize = %d \r\n",bmp_Width,bmp_Height,bmp_size,bmp_headsize);
-
- // Status=SD_read(FileName, (u32)BMP_RD_Buf, bmp_size+bmp_headsize+1);
-
- for(i=0;i<bmp_Height;i++)
- {
- Status=SD_read(FileName, (u32)BMP_RD_Buf, bmp_Width*3, i*bmp_Width*3+bmp_headsize);
- for(j=0;j<bmp_Width;j++)
- {
- bmp_r =BMP_RD_Buf[j*3];
- bmp_g =BMP_RD_Buf[j*3+1];
- bmp_b =BMP_RD_Buf[j*3+2];
- bmp_data = (bmp_r<<24)|(bmp_g<<16)|(bmp_b<<8)|0x0;
- Xil_Out32(frame+((j+i*bmp_Width)<<2),bmp_data);
- }
- }
- printf("######### BMP write finish ########## \r\n");
- }
使用1920*1080 24bit的bmp进行验证。
这里的frame_buffer_addr地址,不要直接等于XPAR_DDR_MEM_BASEADDR,
如果frame_buffer_addr 直接等于XPAR_DDR_MEM_BASEADDR的话,在往ddr写入大量数据的时候,会卡死,数据量少不会卡死。
- //------------------ bmp --------------------------------------
- report_bmp_head("blue_test_1920x1080.bmp");
-
- u32 frame_buffer_addr = XPAR_DDR_MEM_BASEADDR+0x01000000 ;
-
- load_sd_bmp("blue_test_1920x1080.bmp", frame_buffer_addr);
-
- //--------- 验证一部分ddr的内容
- for(i=0; i<len;i++)
- {
- Status = Xil_In32( (i<<2) + frame_buffer_addr);
- printf("ddr_address:%x data = %x \r\n ",(i<<2) + frame_buffer_addr,Status);
- }
bmp文件hex截图:
串口打印结果:与BMP图片一致。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。