基于stm32f103zet6的FAT16文件系统学习4(管理SD卡,读取图片,字库)
来源:互联网 发布:宜家值得买 知乎 编辑:程序博客网 时间:2024/06/05 03:01
本博文所用到的代码:http://download.csdn.net/detail/king_bingge/5739167
好几天没有写博客了,这几天都在忙挑战杯的事情,由于某些不和谐因素,昨天才开始准备今天的挑战杯答辩,虽然不知道结果是怎样的,但是个人感觉创新点还是有的,就是主评委老师拽着我们这个消费对象来说事,过去了就不再想了,也不知道能不能进入省赛,但是学习还是要继续的,今天总结的这个实验是实现从SD卡里面读bmp图片,bin图片,同时在将我制作的字库存放在SD卡中,从里面读取所需要的汉字,虽然之前早就实现了bmp图片读取和字库的读取,但是一直困扰我的就是bin格式的图片读取,今天下午花了些时间终于弄出来的,刷图是比bmp块了,但是没快多少,也就快五分之一的样子!!不过也算是知道了怎么读取bin文件的内容吧,还是有收获的。
好的,实验开始..
预备知识就是知道我们的汉字显示原理,区位码的关系,还有bmp图片的显示原理。这部分知识我也看了几个小时,现在把一些需要注意的地方总结一下
一、关于汉字GBK码显示
1、汉字在各种文件里面的存储不是以点阵数据的形式存储的(否则那占用的空间就太大了),而是以内码的形式存储的,就是GB2312/GBK/BIG5等这几种的一种,每个汉字对应着一个内码,在知道了内码之后再去字库里面查找这个汉字的点阵数据,然后在液晶上显示出来。这个过程我们是看不到,但是计算机是要去执行的。
2、stm32显示汉字流程:汉字内码(GBK/GB2312) ---->查找点阵库 -----> 解析 ------- >显示
那么关于汉字内码的知识,我想这不应该是我们讨论的内容,网上一大把,我推荐一个介绍比较易懂的博文,是转载的,大家可以参考这看一看
http://blog.csdn.net/king_bingge/article/details/8780202
3、那么如何查找点阵的字库呢?先看如下的一段代码,通过代码来分析,总是能够减少我们的理解难度
先看主程序中的代码吧
int main(void){delay_init(72);USART1_Init();SPIx_Init(); //初始化SPILCD_ILI9325_Init();//LCD驱动初始化printf("\r\n ("__DATE__ " - " __TIME__ ") \r\n");LCD_ClearScreen(0xa451);Lcd_show_bmp(0,0,"/你you.bmp");LCD_ClearScreen(BLACK);Lcd_show_bin(0,0,"/你you.bin");LCD_ClearScreen(RED);LCD_Str_CH(20,300,"从存储卡读取汉字的实验",0,BLUE);while(1);}
主程序就是几个刷屏函数,然后先说读取字库这个函数吧
4、代码如下
void LCD_Str_CH(u16 x,u16 y,const u8 *str,u16 Color,u16 bkColor) { while(*str != '\0') {if(x>(240-16)){ /*换行*/x =0;y +=16;}if(y >(320-16)){ /*重新归零*/ y =0; x =0;} LCD_Char_CH(x,y,str,Color,bkColor); str += 2 ; x += 16 ; }}首先就是简单的格式处理,然后重要的是这个函数 LCD_Char_CH(x,y,str,Color,bkColor); 跟踪进去
void LCD_Char_CH(u16 x,u16 y,const u8 *str,u16 Color,u16 bkColor){ u8 i,j; u8 buffer[32]; u16 tmp_char=0;GetGBKCode_from_sd(buffer,str); /* 取字模数据 */ for (i=0;i<16;i++) { tmp_char=buffer[i*2]; tmp_char=(tmp_char<<8); tmp_char|=buffer[2*i+1]; for (j=0;j<16;j++) { if ( (tmp_char >> 15-j) & 0x01 == 0x01) { LCD_DispOnePixel(x+j,y+i,Color); } else { LCD_DispOnePixel(x+j,y+i,bkColor); } } }}这些代码大家都能看懂,那么 GetGBKCode_from_sd(buffer,str); /* 取字模数据 */实现的是什么功能呢?
int GetGBKCode_from_sd(unsigned char* pBuffer,const unsigned char * c){ unsigned char High8bit,Low8bit; unsigned int pos; High8bit=*c; /* 取高8位数据 */ Low8bit=*(c+1); /* 取低8位数据 */ pos = ((High8bit-0xb0)*94+Low8bit-0xa1)*2*16 ;// pos = ((High8bit-0xa0)*94+Low8bit-0xa0)*2*16 ; f_mount(0, &fs); res = f_open(&fsrc , "0:/汉字.bin", FA_OPEN_EXISTING | FA_READ); if ( res == FR_OK ) { f_lseek (&fsrc, pos); //指针偏移 res = f_read( &fsrc, pBuffer, 32, &br ); //16*16大小的汉字 其字模 占用16*2个字节 f_close(&fsrc); return 0; } else return -1; }
其实,我这里还不是很明白,就是偏移量计算的问题,比较郁闷,但是在网上似乎有没有找到合理的解释,真心的希望有人能够帮助我解决这个问题,这个问题也困扰我好久了,我通过打印信息、单步调试、winhex观察内容都没有找到答案,不知道是不是有个头码还是什么的。这个先搁着吧!
这就是利用文件系统打开了SD卡上面存放的字库,文件系统的那部分知识之前已经总结过了,重点就是注意这个定位函数吧,这个函数我喜欢,嘿嘿!
这个函数的作用很简单,就是将我们在字库中的点阵信息提取存到pBuffer中,注意咯一个汉字俩字节的。回到之前的那个函数就是将点阵信息打印出来了。
二、接下来就是显示bmp图片了
bmp图片比较特殊的是有一个54字节的头信息,在这个头信息里面我们能提取到很多信息的。当然你也可以直接读取54字节之后的信息,照样能正常显示的。还有一点要注意的就是,bmp显示的格式呀!!!!他有一个镜像的,也就是说当我们按顺序读取文件中的内容的时候,在TFT上面显示的是一个镜像的图像,但是还是蛮不错的啦!所以需要正常显示的话,那么就得按你的需要修改了!
看一段代码:
for(i=y;i<height+1; i++) { f_read(&bmpfsrc,pColorData,720,&read_num); for(j=x;j<width;j++) //一行有效信息 { k = j*3;//一行中第K个像素的起点(地址) red = pColorData[k+2]; green = pColorData[k+1]; blue = pColorData[k];if(mode==1) LCD_DispOnePixel(i,j,RGB24TORGB16(red,green,blue));//写入LCD-GRAM显示出来else LCD_DispOnePixel(j,i,RGB24TORGB16(red,green,blue));//写入LCD-GRAM显示出来 } }
因为这个位图是24位的,那么就需要转换字节了,也就是说对于我们的屏是240*320的来说,这里的240就是有720转换来的,连续的三个字节转化为16bit类型的颜色数据,也就是这个宏
#define RGB24TORGB16(R,G,B) ((unsigned short int)((((R)>>3)<<11) | (((G)>>2)<<5)| ((B)>>3)))
24转16位,简单来说就是把低位的舍弃掉了。
这样就没有问题了,bmp格式的文件就到这里了,至于bmp位图更为详细的解释可以参考这个文库,个人觉得分析的比较详细哦!
http://wenku.baidu.com/view/95fd4484b9d528ea81c779b3.html
三、接下来就是自己写的一个读bin文件格式的图片,代码有待优化,代码肯定要进行优化的
先看代码,这是我读取了相应的文件之后的代码!!
for(j=0;j<300;j++) //300表示一幅图片含有300x512字节的信息 {tmp_pdata = NULL;f_lseek (&bmpfsrc,(512*j));f_read(&bmpfsrc,pdata,512,&read_num);tmp_pdata = pdata;for(k=0;k<512;k++)printf("%x ",pdata[k]);//打印MBR扇区数据 for(i=0;i<256;i++) //然后写到液晶屏,可以显示256个像素,每个像素16位即2个字节{ data = LD_WORD(tmp_pdata);LCD_DispOnePixel(x1,y1,data); tmp_pdata = tmp_pdata + 2;x1++;if(x1==240) //检测是否写到屏的边缘 240x320{y1++;x1=0;if(y1==320)y1=0;} } }
这个和bmp文件的格式区别就是,这个bin文件,我用的是16位的,所以只需要把相应的高8位和低8位合并起来,编程一个WORD类型的颜色数据,那么实现这个转换的宏是什么呢?如下,借用了FAT文件系统里面的一个宏,还不错哟!
#define LD_WORD(ptr)(WORD)(((WORD)*((BYTE*)(ptr)+1)<<8)|(WORD)*(BYTE*)(ptr))
接下来就准备着手使用FSMC+DMA来驱动TFT试一试,我这个模块不支持SD模式,这是最蛋疼的,先这样用着吧!记得:运行的时候记得将打印信息注释掉,否则,那真是龟速!!!!
- 基于stm32f103zet6的FAT16文件系统学习4(管理SD卡,读取图片,字库)
- 基于stm32f103zet6的FAT16文件系统学习0(读SD卡扇区)
- 基于stm32f103zet6的FAT16文件系统学习1(初识FAT16)
- 基于stm32f103zet6的FAT16文件系统学习2(初步移植ff9a)
- 基于stm32f103zet6的FAT16文件系统学习3(初步分析ff9a)
- SD卡FAT16文件系统的学习笔记
- SD卡FAT16文件系统的学习笔记
- 基于stm32f103zet6的内存管理的学习
- SD+FAT16文件系统学习笔记1
- 基于ATmega32的SD卡上FAT32文件系统数据读取
- FAT16文件系统在SD卡上实现(一) 读写SD卡
- 基于stm32f103zet6的串口学习
- 基于stm32f103zet6的DMA学习
- 基于stm32f103zet6的RTC学习
- 基于stm32f103zet6的DS1302学习
- 基于stm32f103zet6的IIC学习
- 基于stm32f103zet6的看门狗学习
- 基于FAT16文件系统的嵌入式温度记录器
- 【程序23】打印菱形
- HDU 1728
- 两个向量点积的几何意义
- ROW_NUMBER() OVER函数的基本用法
- Ubuntu下安装Qt4和PyQt4
- 基于stm32f103zet6的FAT16文件系统学习4(管理SD卡,读取图片,字库)
- 浙江大华2011.10.10校园招聘会笔试题
- android下SQLite学习笔记
- 冒泡排序、插入排序、选择排序--C语言实现
- Bash游戏 V3
- 数据结构复习笔记(一)
- hdu 1548 最短路
- 个性化设置 MySQL prompt 提示符
- A* (路径搜索)算法导引