基于stm32f103zet6的FAT16文件系统学习4

发布者:快乐舞蹈最新更新时间:2017-09-06 来源: eefocus关键字:stm32f103zet6  FAT16文件系统  SD卡 手机看文章 扫描二维码
随时随地手机看文章

本博文所用到的代码: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、那么如何查找点阵的字库呢?先看如下的一段代码,通过代码来分析,总是能够减少我们的理解难度

先看主程序中的代码吧


  1. int main(void)  

  2. {  

  3.     delay_init(72);  

  4.     USART1_Init();  

  5.     SPIx_Init();                //初始化SPI  

  6.     LCD_ILI9325_Init();         //LCD驱动初始化    

  7.     printf("\r\n ("__DATE__ " - " __TIME__ ") \r\n");  

  8.     LCD_ClearScreen(0xa451);  

  9.     Lcd_show_bmp(0,0,"/你you.bmp");  

  10.     LCD_ClearScreen(BLACK);  

  11.     Lcd_show_bin(0,0,"/你you.bin");  

  12.     LCD_ClearScreen(RED);  

  13.     LCD_Str_CH(20,300,"从存储卡读取汉字的实验",0,BLUE);          

  14.     while(1);  

  15. }  



主程序就是几个刷屏函数,然后先说读取字库这个函数吧

4、代码如下


  1. void LCD_Str_CH(u16 x,u16 y,const u8 *str,u16 Color,u16 bkColor)    

  2. {  

  3.      

  4.     while(*str != '\0')  

  5.     {  

  6.             if(x>(240-16))  

  7.             {      

  8.                  /*换行*/  

  9.                 x =0;  

  10.                 y +=16;  

  11.                       

  12.             }  

  13.             if(y >(320-16))  

  14.             {  

  15.                  /*重新归零*/  

  16.                  y =0;  

  17.                  x =0;  

  18.             }  

  19.          LCD_Char_CH(x,y,str,Color,bkColor);        

  20.        str += 2 ;  

  21.        x += 16 ;      

  22.     }  

  23. }  

首先就是简单的格式处理,然后重要的是这个函数     LCD_Char_CH(x,y,str,Color,bkColor);      跟踪进去


  1. void LCD_Char_CH(u16 x,u16 y,const u8 *str,u16 Color,u16 bkColor)  

  2. {  

  3.     u8 i,j;  

  4.     u8 buffer[32];  

  5.     u16 tmp_char=0;  

  6.         GetGBKCode_from_sd(buffer,str);  /* 取字模数据 */  

  7.       

  8.     for (i=0;i<16;i++)  

  9.     {  

  10.         tmp_char=buffer[i*2];  

  11.         tmp_char=(tmp_char<<8);  

  12.         tmp_char|=buffer[2*i+1];  

  13.         for (j=0;j<16;j++)  

  14.         {  

  15.             if ( (tmp_char >> 15-j) & 0x01 == 0x01)  

  16.             {  

  17.                 LCD_DispOnePixel(x+j,y+i,Color);  

  18.             }  

  19.             else  

  20.             {  

  21.                 LCD_DispOnePixel(x+j,y+i,bkColor);  

  22.             }  

  23.         }  

  24.     }  

  25. }  

这些代码大家都能看懂,那么 GetGBKCode_from_sd(buffer,str);  /* 取字模数据 */实现的是什么功能呢?


  1. int GetGBKCode_from_sd(unsigned char* pBuffer,const unsigned char * c)  

  2. {   

  3.     unsigned char High8bit,Low8bit;  

  4.     unsigned int pos;  

  5.     High8bit=*c;     /* 取高8位数据 */  

  6.     Low8bit=*(c+1);  /* 取低8位数据 */  

  7.       

  8.     pos = ((High8bit-0xb0)*94+Low8bit-0xa1)*2*16 ;    

  9. //     pos = ((High8bit-0xa0)*94+Low8bit-0xa0)*2*16 ;     

  10.     f_mount(0, &fs);  

  11.     res = f_open(&fsrc , "0:/汉字.bin", FA_OPEN_EXISTING | FA_READ);  

  12.       

  13.     if ( res == FR_OK )   

  14.     {  

  15.         f_lseek (&fsrc, pos);                                                        //指针偏移  

  16.         res = f_read( &fsrc, pBuffer, 32, &br );         //16*16大小的汉字 其字模 占用16*2个字节  

  17.           

  18.         f_close(&fsrc);  

  19.           

  20.         return 0;    

  21.     }  

  22.       

  23.     else  

  24.         return -1;      

  25. }  


其实,我这里还不是很明白,就是偏移量计算的问题,比较郁闷,但是在网上似乎有没有找到合理的解释,真心的希望有人能够帮助我解决这个问题,这个问题也困扰我好久了,我通过打印信息、单步调试、winhex观察内容都没有找到答案,不知道是不是有个头码还是什么的。这个先搁着吧!


这就是利用文件系统打开了SD卡上面存放的字库,文件系统的那部分知识之前已经总结过了,重点就是注意这个定位函数吧,这个函数我喜欢,嘿嘿!

这个函数的作用很简单,就是将我们在字库中的点阵信息提取存到pBuffer中,注意咯一个汉字俩字节的。回到之前的那个函数就是将点阵信息打印出来了。

二、接下来就是显示bmp图片了

bmp图片比较特殊的是有一个54字节的头信息,在这个头信息里面我们能提取到很多信息的。当然你也可以直接读取54字节之后的信息,照样能正常显示的。还有一点要注意的就是,bmp显示的格式呀!!!!他有一个镜像的,也就是说当我们按顺序读取文件中的内容的时候,在TFT上面显示的是一个镜像的图像,但是还是蛮不错的啦!所以需要正常显示的话,那么就得按你的需要修改了!

看一段代码:


  1. for(i=y;i

  2.         {                 

  3.         f_read(&bmpfsrc,pColorData,720,&read_num);    

  4.                     

  5.             for(j=x;j

  6.             {  

  7.                 k = j*3;                                                                                //一行中第K个像素的起点(地址)  

  8.                 red = pColorData[k+2];  

  9.                 green = pColorData[k+1];  

  10.                 blue =  pColorData[k];  

  11.                 if(mode==1)  

  12.                 LCD_DispOnePixel(i,j,RGB24TORGB16(red,green,blue));                 //写入LCD-GRAM    显示出来  

  13.                 else    LCD_DispOnePixel(j,i,RGB24TORGB16(red,green,blue));     //写入LCD-GRAM    显示出来  

  14.             }              

  15.         }  



因为这个位图是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文件格式的图片,代码有待优化,代码肯定要进行优化的

先看代码,这是我读取了相应的文件之后的代码!!


  1. for(j=0;j<300;j++)               //300表示一幅图片含有300x512字节的信息  

  2.   {  

  3.     tmp_pdata = NULL;  

  4.     f_lseek (&bmpfsrc,(512*j));  

  5.     f_read(&bmpfsrc,pdata,512,&read_num);     

  6.     tmp_pdata = pdata;  

  7.     for(k=0;k<512;k++)  

  8.         printf("%x ",pdata[k]);//打印MBR扇区数据           

  9.     for(i=0;i<256;i++)             //然后写到液晶屏,可以显示256个像素,每个像素16位即2个字节  

  10.     {    

  11.         data = LD_WORD(tmp_pdata);                            

  12.         LCD_DispOnePixel(x1,y1,data);   

  13.         tmp_pdata = tmp_pdata + 2;    

  14.         x1++;  

  15.         if(x1==240)            //检测是否写到屏的边缘 240x320  

  16.         {  

  17.             y1++;  

  18.             x1=0;  

  19.             if(y1==320)  

  20.                 y1=0;  

  21.         }  

  22.     }  

  23.   }   


这个和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文件系统  SD卡 引用地址:基于stm32f103zet6的FAT16文件系统学习4

上一篇:基于stm32f103zet6之DS18B20的学习
下一篇:基于stm32f103zet6的FAT16文件系统学习3(初步分析ff9a)

推荐阅读最新更新时间:2024-03-16 15:36

STM32 USB SD卡读卡器和NAND FLASH模拟U盘
本次工程是要同时实现SD卡读卡器和NAND Flash模拟U盘的功能。结合之前的两个工程,稍稍修改下就可以了。 既然要实现两个盘,当然在usb_prop.c中的Max_Lun变量赋值为1,在USB_User组中同时添加fsmc_nand.c和sdio_sdcard.c这两个文件,在外设库中挺尸添加stm32f10x_sdio.c和stm32f10x_fsmc.c两个文件。 添加完之后,可能会有些许的错误,解决完后,我们就要修改下mass_mal.c文件了,这个文件本次要同时实现SD卡和NAND Flash的相关驱动代码的挂接,代码如下: uint32_t Mass_Memory_Size ; uint32_t Mass_B
[单片机]
支持S3C6410处理器SD卡启动模式的U-Boot-2011.06移植修改方案
通用Bootloader(Universal Bootloader,U-Boot)是系统上电后执行的第一段代码,其作用主要包括初始化硬件环境以及加载执行操作系统内核。在进行系统安装时,U-Boot通常需要使用专用工具烧写到FLASH中,内核及文件系统则通过U-Boot命令进行烧写,该过程操作繁琐,并且容易出错,不适宜系统的大量安装。 S3C6410是三星公司生产的一款基于ARM11架构的通用嵌入式处理器,其启动方式除了传统的Flash启动模式外,还支持从SD 卡中启动系统。本文基于S3C6410处理器,分析了从SD卡启动系统的原理,并对U-Boot源码进行修改以支持该启动方式,在此基础上进一步扩展了U-Boot的功能,使其支持
[单片机]
支持S3C6410处理器<font color='red'>SD卡</font>启动模式的U-Boot-2011.06移植修改方案
BootLoader启动引导方式分析(sd卡引导)
引言   BootLoader通常称为“系统的引导加载程序”,是系统加电或复位后执行的第一段程序代码 。这段程序的主要任务是,实现硬件设备初 始化并建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核或用户应用程序准备好正确的环境。通 常,BootLoader包含两种不同的加载和启动引导方式,即启动加载方式和下载方式。   ① 启动加载(boot loading)方式。这种引导方式也称为“自主(autonomous)引导方式”,也即BootLoader从目标机的某个固态存储设备上将操作系统 加载到RAM中并引导运行,整个过程并没有用户的介入。这种引导方式是BootLoader的正常工作模式下普
[单片机]
BootLoader启动引导方式分析(<font color='red'>sd卡</font>引导)
SD卡读CID寄存器
/** * @brief Card Identification Data: CID Register */ typedef struct { uint8 ManufacturerID; // 生产标识ID uint16 OEM_AppliID; // OEM/应用 ID uint32 ProdName1; // 产品名称1 uint8 ProdName2; // 产品名称2 uint8 ProdRev; // 产品版本 uint32 ProdSN; // 产品序号 uint8 Reserved1; // 保留 uint16 Manufa
[单片机]
SD卡中逻辑分析仪的应用
  1.引言   SD卡以大容量,低功耗,小巧轻便,热插拔,价格便宜等特点,在如今的移动存储中占有重要的地位。   今天我们就以广州致远电子出品的 逻辑分析仪 系列产品LAB7504为例,介绍其在SD卡设计中的应用。   2.SD卡简介   SD卡共支持三种传输模式:SPI模式(独立序列输入和序列输出),1位SD模式(独立指令和数据通道,独有的传输格式),4位SD模式(支持四位宽的并行传输)。表1介绍了数据率与模式的关系。      SD模式的总线拓扑结构为:   一个主机(如微控制器)、多个从机(卡)和同步的星形拓扑结构。   所有卡共用时钟CLK、电源和地信号。而命令线(CMD)和数据线(DAT0~DA
[测试测量]
<font color='red'>SD卡</font>中逻辑分析仪的应用
为STM32移植FATFS,读取SD卡上FAT12/16/32文件系统
给stm32移植fatfs文件系统,今天终于取得阶段性胜利。只需要提供这样几个函数即可 DSTATUS disk_initialize (BYTE); DSTATUS disk_status (BYTE); DRESULT disk_read (BYTE, BYTE*, DWORD, BYTE); DRESULT disk_write (BYTE, const BYTE*, DWORD, BYTE); // 如果实现只读的文件系统就不需要了。 DRESULT disk_ioctl (BYTE, BYTE, void*); 移植成功后,可以用如下方式读取SD卡了,实在太方便了,和PC机上编程差不了多少。 unsigned in
[单片机]
STM32F103ZET6 — RTC
简介 RTC 是Real Time Clock 的简称,意为实时时钟。即,提供类似于 PC 上的时间记录信息的功能。既然是实时时钟,则至少应该有秒、分、时等信息。也可以直观的把他理解成为一个计数器,一直累加。但又不同于 CPU 上电后的那些计数器,对于 RTC ,需要支持的是掉电后的继续计数(存在备用电源)。所谓掉电,是指电源Vpp断开的情况下,为了RTC外设掉电可以继续运行,必须给STM32芯片通过VBAT引脚街上锂电池.当主电源VDD有效时,由VDD给RTC外设供电.当VDD掉电后,由VBAT给RTC外设供电.无论由什么电源供电,RTC中的数据始终都保存在属于RTC的备份域中,如果主电源和VBA都掉电,那么备份域中保存的所有
[单片机]
STM32F103ZET6 — SPI
简介 SPI,是英语Serial Peripheral interface的缩写,顾名思义就是串行外围设备接口。是Motorola首先在其MC68HCXX系列处理器上定义的。SPI接口主要应用在 EEPROM,FLASH,实时时钟,AD转换器,还有数字信号处理器和数字信号解码器之间。SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便,正是出于这种简单易用的特性,现在越来越多的芯片集成了这种通信协议。 SPI 具有信号线少,协议简单,数据率高等优点。数据传送速率达几MB/s Pin 脚介绍 标准的 SPI 使用 4 Pin 进行数据传送: (1
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved