OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6213|回复: 3

STM32Cube1 SDIO+FATFS 写入TF卡bmp图片问题

[复制链接]

1

主题

4

帖子

0

精华

初级会员

Rank: 2

积分
80
金钱
80
注册时间
2015-11-27
在线时间
8 小时
发表于 2015-12-6 11:05:16 | 显示全部楼层 |阅读模式
5金钱
STM32Cube1 SDIO+FATFS 写入TF卡图片遇到点问题,不知道网站里有没有人遇到过,帮忙看看,谢了。。。
公司要用STM32Cube1+STM32CubeMX搞开发 USB和TF卡相关的 ,用STM32F103ZET6 芯片 ,现在USB还没有搞,最近搞到SDIO操作TF卡部分,测试下往TF卡里写入24位 .bmp 图片(项目中主要是写入400X400X3的.bmp图片),我写入的是纯色的图片测试,STACK HEAD大小如下
Stack_Size EQU 0x00001000
。。。。。。。

Heap_Size EQU 0x00001000

单片机里有个测试数组往TF卡里写入数据,当大小为300字节的时候,写入40x40x3或者 400X400X3的图片没有问题,可以当 数组大小为600或者更大的时候就会出现问题,为600时,图片会出现问题不是纯色的。如下所示,后面一张是没有问题的。



我将图片转换成16进制数据看了下,主要是有问题图片,数据写入错误了,就是错了两个8位
的数据,下图中前面图是正确的数据,后面图是错误的,193行开头应该是FF00的,现在多出了个 0080不知道这是为什么。192行 一共 3072个字节,不知道有什么关系。。。FATFS是 R0.11 的我写入6k的 .txt文件,缓存为1K多,数据没有错误,就是图片数据不对。换个TF卡也是一样 。
另外想问下,16G的卡写入时间比4G的卡多挺多的,4GB的卡比128M的小卡写入时间也多1倍,不知道这是为什么。16G/4G都按键 32K格式化。




最后写入的总数据是一样的,我改过STACK HEAD大一些也一样是在这个地方出现错误,不知道为什么,难道是FATFS的问题吗 ?
写入主要代码如下: [mw_shl_code=c,true]SDIO_TEST_PICTURE_WITH_SIZE 是数组的大小[/mw_shl_code]
[mw_shl_code=c,true]// 给测试图片填充数据 void User_Picture_Process(void) { uint16_t Tempi = 0; static uint16_t Tempj = 0; for (Tempi=0; Tempi<SDIO_TEST_PICTURE_WITH_SIZE; Tempi += 3) { PictureTestBuf[Tempi] = TestColourSet[Tempj][0]; // B PictureTestBuf[Tempi+1] = TestColourSet[Tempj][1]; // G PictureTestBuf[Tempi+2] = TestColourSet[Tempj][2]; // R } ++Tempj; Tempj %= 10; } [/mw_shl_code]
[mw_shl_code=c,true]// TF卡写入图片测试 .bmp格式图片 void Sdio_Store_Picture(uint32_t FileWidth, uint32_t FileHeight) { uint16_t i = 0; uint32_t FileSize = 0; // 数据大小 //uint8_t Temp1[4]={0,0,0,0}; // 填充数组 uint16_t TempTime, TempValue; /* bmp 文件头 54个字节 */ uint8_t Fileheader[54] = { 0x42, 0x4d, // 0X4D42 就是字符“BM” 0, 0, 0, 0, // 位图大小,预留 0, 0, 0, 0, // 必须为0 54, 0, 0, 0, // 从文件头开始到实际的图象数据之间的字节的偏移量,这里为54字节 40, 0, 0, 0, // 一般为40 0, 0, 0, 0, // 图象宽度,像素为单位,预留 0, 0, 0, 0, // 图象高度,像素为单位,预留 1, 0, // 位面数,为1 24, 0, // 比特数/像素 常用24、32,也有1、4、8、16. 24表示一个像素占三个字节 0, 0, 0, 0, // 图像压缩类型 0 表示 BI_RGB 没有压缩 0, 0, 0, 0, // 图象大小 字节为单位,用 BI_RGB 时,可设置为 0 0, 0, 0, 0, // 水平分辨率,不用为 0 0, 0, 0, 0, // 垂直分辨率,不用为 0 0, 0, 0, 0, // BMP图像使用的颜色,0 表示使用全部颜色 0, 0, 0, 0 // 重要的颜色数,0 表示所有颜色都重要 }; /* 宽*高 +补充的字节 + 头部信息 注意乘3,如果输入参数有乘则不有乘3 */ FileSize = FileWidth * FileHeight * 3 + FileHeight*(FileWidth%4) + 54; // FileSize = FileWidth * FileHeight * 4 + 54; /* 文件大小 4个字节 */ Fileheader[2] = (uint8_t)((FileSize >> 0) & 0x000000ff); Fileheader[3] = (uint8_t)((FileSize >> 8) & 0x000000ff); Fileheader[4] = (uint8_t)((FileSize >> 16) & 0x000000ff); Fileheader[5] = (uint8_t)((FileSize >> 24) & 0x000000ff); /* 位图宽 4个字节 */ Fileheader[18] = (uint8_t)((FileWidth >> 0) & 0x000000ff); Fileheader[19] = (uint8_t)((FileWidth >> 8) & 0x000000ff); Fileheader[20] = (uint8_t)((FileWidth >> 16) & 0x000000ff); Fileheader[21] = (uint8_t)((FileWidth >> 24) & 0x000000ff); /* 位图高 4个字节 */ Fileheader[22] = (uint8_t)((FileHeight >> 0) & 0x000000ff); Fileheader[23] = (uint8_t)((FileHeight >> 8) & 0x000000ff); Fileheader[24] = (uint8_t)((FileHeight >> 16) & 0x000000ff); Fileheader[25] = (uint8_t)((FileHeight >> 24) & 0x000000ff); do { // 动态创建文件名 sprintf((char*)FileName,"%s/ST32Pict_%d.bmp", SdioPicturePath, g_NameNum++); //sprintf((char*)PName,"STM32Picture_%d.bmp", NameNum++); //if(g_NameNum>50000) // break; g_Res = f_open(&g_Filnew,(const TCHAR *)FileName, FA_CREATE_NEW | FA_WRITE); }while(g_Res != FR_OK); g_SdioRdWrSize = 0; // 计数前清零 // 写入文件头 User_F_Write(Fileheader, 54); g_SdioRdWrSize += ByWrCount; // 写入数据的总字节数 // 读取数据,继续写入SD卡里面 // 写的整数次 TempTime = (FileSize-54) / SDIO_TEST_PICTURE_WITH_SIZE; // 剩下不够1个缓存大小 TempValue = (FileSize-54) % SDIO_TEST_PICTURE_WITH_SIZE; i = 0; if (0 == FileWidth%4) { while((i < TempTime) && (g_Res==FR_OK)) { ++i; User_F_Write(PictureTestBuf, SDIO_TEST_PICTURE_WITH_SIZE); f_sync(&g_Filnew); g_SdioRdWrSize += ByWrCount; } if (TempValue) // 300或者600的缓存用不到这里 { User_F_Write(PictureTestBuf, TempValue); g_SdioRdWrSize += ByWrCount; } } else { /* 这段代码有错 暂不处理 不是4倍数的宽度.bmp图片 while((i < TempTime) && (g_Res==FR_OK)) { ++i; User_F_Write(PictureTestBuf, SDIO_TEST_PICTURE_WITH_SIZE); g_SdioRdWrSize += ByWrCount; // 宽 不是4的倍数,则补全 User_F_Write(Temp1, FileWidth%4); g_SdioRdWrSize += ByWrCount; } if (TempValue) { User_F_Write(PictureTestBuf, TempValue); g_SdioRdWrSize += ByWrCount; } */ } User_F_Close(); } [/mw_shl_code]

[mw_shl_code=c,true]主程序测试调用方法: for (i=0; i<2; ++i) { User_Picture_Process(); Sdio_Store_Picture(40, 40); }[/mw_shl_code]
SDIO-TX 是用DMA ,RX没有用DMA,尝试搞过都用DMA没有成功,STM32Cube1+STM32CubeMX软件配置只能配置一个方向,因为只有一一个通道,之后双向要自己搞,没有成功,就是DMA等待传输成功一直卡在那里,不知道为什么。。。
不知道论坛有没有人遇到过这问题。。。求帮忙下。。。
附件里是工程代码。





STM32F103ZETx.zip

11.67 MB, 下载次数: 665

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-12-6 22:59:30 | 显示全部楼层
回复

使用道具 举报

1

主题

4

帖子

0

精华

初级会员

Rank: 2

积分
80
金钱
80
注册时间
2015-11-27
在线时间
8 小时
 楼主| 发表于 2015-12-7 16:04:02 | 显示全部楼层
 谢谢原子哥, 问题暂时解决了, 在文件头和数据之前进行数据填充就可以了,我将54后面填充74个0,这样文件头到数据之间有128个字节,24位bmp图片不用调色板,填充0 不影响,但不知道为什么不填充写入的数据就会有2个错误的我也不懂,尝试过以.txt格式写入,写入文件头为54时也出了同样的错误,不知道为什么,填充到256也可以,其他的没有测试,应该也可以吧。

// 文件头写入函数
[mw_shl_code=c,true]void Sdio_Store_Picture_Header(uint32_t FileWidth, uint32_t FileHeight) { uint32_t FileSize = 0; // 数据大小 BmpStr_TypDef BmpPictureHeader; // 文件头 uint16_t i = 0; uint8_t TempBuf[74]; // 填充数组 for (i = 0; i < 74; ++i) { TempBuf = 0; } /* 宽*高 +补充的字节 + 头部信息 注意乘3,如果输入参数有乘则不有乘3 */ FileSize = FileWidth * FileHeight * 3 + FileHeight*(FileWidth%4) + 128; // FileSize = FileWidth * FileHeight * 4 + 54; BmpPictureHeader.FileHeader.bfType = 0x4D42; // BM BmpPictureHeader.FileHeader.bfSize = FileSize; // 文件大小 BmpPictureHeader.FileHeader.bfReserverd1 = 0x0000; // 0 BmpPictureHeader.FileHeader.bfReserverd2 = 0x0000; // 文件大小 BmpPictureHeader.FileHeader.bfbfOffBits = 0x00000080; // 54/128 BmpPictureHeader.InfoHeader.biSize = 0x00000028; // 40 BmpPictureHeader.InfoHeader.biWidth = FileWidth; // 宽 BmpPictureHeader.InfoHeader.biHeight = FileHeight; // 高 BmpPictureHeader.InfoHeader.biPlanes = 0x0001; BmpPictureHeader.InfoHeader.biBitcount = 0x0018; // 24 BmpPictureHeader.InfoHeader.biCompression = 0x00000000; BmpPictureHeader.InfoHeader.biSizeImage = 0x00000000; BmpPictureHeader.InfoHeader.biXPelsPermeter = 0x00000000; BmpPictureHeader.InfoHeader.biYPelsPermeter = 0x00000000; BmpPictureHeader.InfoHeader.biClrUsed = 0x00000000; BmpPictureHeader.InfoHeader.biClrImportant = 0x00000000; do { // 动态创建文件名 //sprintf((char*)FileName,"%s/ST32Pict_%d.bmp", DirectoryName, g_NameNum++); sprintf((char*)FileName,"%s/ST32Pict_%d.bmp", DirectoryName, g_PictureBufTest); // FA_CREATE_NEW 表示文件名存在则创建失败,继续创建下一个文件名 g_Res = f_open(&g_Filnew,(const TCHAR *)FileName, FA_CREATE_NEW | FA_WRITE); }while(g_Res != FR_OK); User_F_Write((uint8_t *)&BmpPictureHeader, 54); User_F_Write(TempBuf, 74); User_F_Close(); g_SdioRdWrSize += ByWrCount; // 写入数据的总字节数 }[/mw_shl_code]

回复

使用道具 举报

260

主题

810

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1898
金钱
1898
注册时间
2012-10-28
在线时间
357 小时
发表于 2016-3-15 16:53:51 | 显示全部楼层
hxhaawt 发表于 2015-12-7 16:04
&nbsp;谢谢原子哥, 问题暂时解决了, 在文件头和数据之前进行数据填充就可以了,我将54后面填充74个0,这 ...

*.bmp 图片是有一定的数据格式的,你找一下 .bmp 24bit的数据格式看看估计就会明白了哟
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-7-13 03:29

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表