STM32 汉字库+ascii字库 存放到 flash中

#ifndef __FONTUPD_H__

#define __FONTUPD_H__

#include "sys.h"

 

//字库信息结构体定义33字节

__packed typedef struct

{

u8 fontok; //字库存在标志,0XAA,字库正常;其他,字库不存在

u32 ugbkaddr; //unigbk的地址

u32 ugbksize; //unigbk的大小

u32 f12addr; //gbk12地址

u32 gbk12size; //gbk12的大小

u32 f16addr; //gbk16地址

u32 gbk16size; //gbk16的大小

u32 f24addr; //gbk24地址

u32 gkb24size; //gbk24的大小

}_font_info;

extern _font_info ftinfo; //汉字库信息结构体

 

//字库信息结构体定义 25字节

//第1个字节用于标记字库是否存在.后续分别保存起始地址和文件大小

__packed typedef struct

{

u8 fontflag; //字库存在标志,0XAA,字库正常;其他,字库不存在

u32 asc1206_addr; //asc1206的地址

u32 asc1206_size; //asc1206的大小

u32 asc1608_addr; //asc1608地址

u32 asc1608_size; //asc1608的大小

u32 asc2412_addr; //asc2412地址

u32 asc2412_size; //asc2412的大小

} _ascii_font;

extern _ascii_font ascii_font; //ascii字库信息结构体

 

 

u8 updata_HZ_fontx(u8 *fxpath,u8 fx); //更新指定字库

u8 update_HZ_font(u8* src); //更新全部字库

u8 HZ_font_init(void); //初始化字库

 

u8 updata_ascii_fontx(u8 *fxpath,u8 fx); //更新指定字库

u8 update_ascii_font(u8* src); //更新全部字库

u8 ascii_font_init(void); //初始化字库

 

u8 font_init(void);

void updateHZfont(void);

void updateasciifont(void);

#endif

 

 

 

#include "fontupd.h"

#include "malloc.h"

#include "ff.h"

#include "w25qxx.h"

#include "string.h"

#include "delay.h"

#include "usart.h"

 

 

/* ascii字库在flash中的地址及大小(字节)

fontflagaddr=15831040 ascii_font_size=25

asc1206_addr=15831065 asc1206_size=1140

asc1608_addr=15832205 asc1608_size=1520

asc2412_addr=15833725 asc2412_size=3420

*/

 

//W25Q128FVFIG容量有128Mbit = 16MB

//前面12M被fatfs占用了,从12M地址以后存放字库结构体、UNIGBK.bin、和三个字库

//地址: (1024*12)*1024 字节处,大小约 3.09M,不能动!

//15.10M以后,存放ASCII三个字库

//首地址: 1024*1024*15 + 1024*100 =15831040字节处 字库总大小25+ 6080字节,也不能动 !

//15.20M以后剩余0.8M字节空间,用户可以使用。

 

//汉字库区域占用的总扇区数大小(3个字库+unigbk表+字库信息=3238700字节,3238700/512=791)

//ascii字库区域占用的总扇区数大小 //(字库信息结构体+字库 = 25+ 6080字节,占12个W25QXX扇区)

 

#define ASCII_FONT_SECSIZE 12 //ascii字库占用扇区

#define ASCIIFONTINFOADDR 1024*1024*15 + 1024*100 //ascii字库起始地址

#define FONTSECSIZE 791 //汉字库占用扇区

#define FONTINFOADDR 1024*1024*12 //汉字库起始地址

_font_info ftinfo; //用来保存字库基本信息,地址,大小等

_ascii_font ascii_font; //用来保存字库基本信息,地址,大小等

 

//汉字库存放在磁盘中的路径

u8*const GBK24_PATH="/SYSTEM/FONT/GBK24.FON"; //GBK24的存放位置

u8*const GBK16_PATH="/SYSTEM/FONT/GBK16.FON"; //GBK16的存放位置

u8*const GBK12_PATH="/SYSTEM/FONT/GBK12.FON"; //GBK12的存放位置

u8*const UNIGBK_PATH="/SYSTEM/FONT/UNIGBK.BIN"; //UNIGBK.BIN的存放位置

//ascii字库存放在磁盘中的路径

u8*const ASC1206_PATH="/SYSTEM/FONT/ASC1206.dat"; //asc1206的存放位置

u8*const ASC1608_PATH="/SYSTEM/FONT/ASC1608.dat"; //asc1608的存放位置

u8*const ASC2412_PATH="/SYSTEM/FONT/ASC2412.dat"; //asc2412的存放位置

 

 

 

//更新某一个

//fxpath:路径

//fx:更新的内容 0,ungbk;1,gbk12;2,gbk16;3,gbk24;

//返回值:0,成功;其他,失败.

u8 updata_HZ_fontx(u8 *fxpath,u8 fx)

{

u32 flashaddr=0;

FIL * fftemp;

u8 *tempbuf;

u8 res;

u16 bread;

u32 offx=0;

u8 rval=0;

fftemp=(FIL*)mymalloc(SRAMIN,sizeof(FIL)); //分配内存

if(fftemp==NULL)rval=1;

tempbuf=mymalloc(SRAMIN,4096); //分配4096个字节空间

if(tempbuf==NULL)rval=1;

res=f_open(fftemp,(const TCHAR*)fxpath,FA_READ);

if(res)rval=2;//打开文件失败

if(rval==0)

{

switch(fx)

{

case 0:

ftinfo.ugbkaddr=FONTINFOADDR+sizeof(ftinfo); //信息头之后,紧跟UNIGBK转换码表

ftinfo.ugbksize=fftemp->fsize; //UNIGBK大小

flashaddr=ftinfo.ugbkaddr;

break;

case 1:

ftinfo.f12addr=ftinfo.ugbkaddr+ftinfo.ugbksize; //UNIGBK之后,紧跟GBK12字库

ftinfo.gbk12size=fftemp->fsize; //GBK12字库大小

flashaddr=ftinfo.f12addr; //GBK12的起始地址

break;

case 2:

ftinfo.f16addr=ftinfo.f12addr+ftinfo.gbk12size; //GBK12之后,紧跟GBK16字库

ftinfo.gbk16size=fftemp->fsize; //GBK16字库大小

flashaddr=ftinfo.f16addr; //GBK16的起始地址

break;

case 3:

ftinfo.f24addr=ftinfo.f16addr+ftinfo.gbk16size; //GBK16之后,紧跟GBK24字库

ftinfo.gkb24size=fftemp->fsize; //GBK24字库大小

flashaddr=ftinfo.f24addr; //GBK24的起始地址

break;

}

while(res==FR_OK)//死循环执行

{

res=f_read(fftemp,tempbuf,4096,(UINT *)&bread); //读取数据

if(res!=FR_OK)break; //执行错误

W25QXX_Write(tempbuf,offx+flashaddr,4096); //从0开始写入4096个数据

offx+=bread;

if(bread!=4096)break; //读完了.

}

f_close(fftemp);

}

myfree(SRAMIN,fftemp); //释放内存

myfree(SRAMIN,tempbuf); //释放内存

return res;

}

 

//更新字体文件,UNIGBK,GBK12,GBK16,GBK24一起更新

//src:字库来源磁盘."0:",SD卡;"1:",FLASH盘,"2:",U盘.

//提示信息字体大小

//返回值:0,更新成功;

// 其他,错误代码.

u8 update_HZ_font(u8* src)

{

u8 *pname;

u32 *buf;

u8 res=0;

u16 i,j;

FIL *fftemp;

u8 rval=0;

res=0XFF;

ftinfo.fontok=0XFF;

pname=mymalloc(SRAMIN,100); //申请100字节内存

buf=mymalloc(SRAMIN,4096); //申请4K字节内存

fftemp=(FIL*)mymalloc(SRAMIN,sizeof(FIL)); //分配内存

if(buf==NULL||pname==NULL||fftemp==NULL)

{

myfree(SRAMIN,fftemp);

myfree(SRAMIN,pname);

myfree(SRAMIN,buf);

return 5; //内存申请失败

}

//先查找文件是否正常

strcpy((char*)pname,(char*)src); //copy src内容到pname

strcat((char*)pname,(char*)UNIGBK_PATH); //文件路径放到pname后

res=f_open(fftemp,(const TCHAR*)pname,FA_READ);

if(res)rval|=1<<4;//打开文件失败

strcpy((char*)pname,(char*)src); //copy src内容到pname

strcat((char*)pname,(char*)GBK12_PATH);

res=f_open(fftemp,(const TCHAR*)pname,FA_READ);

if(res)rval|=1<<5;//打开文件失败

strcpy((char*)pname,(char*)src); //copy src内容到pname

strcat((char*)pname,(char*)GBK16_PATH);

res=f_open(fftemp,(const TCHAR*)pname,FA_READ);

if(res)rval|=1<<6;//打开文件失败

strcpy((char*)pname,(char*)src); //copy src内容到pname

strcat((char*)pname,(char*)GBK24_PATH);

res=f_open(fftemp,(const TCHAR*)pname,FA_READ);

if(res)rval|=1<<7;//打开文件失败

myfree(SRAMIN,fftemp);//释放内存

if(rval==0)//字库文件都存在.

{

for(i=0;i

{

W25QXX_Read((u8*)buf,((FONTINFOADDR/4096)+i)*4096,4096);//读出整个扇区的内容

for(j=0;j<1024;j++)//校验数据

{

if(buf[j]!=0XFFFFFFFF)break;//需要擦除

}

if(j!=1024)W25QXX_Erase_Sector((FONTINFOADDR/4096)+i); //需要擦除的扇区

}

myfree(SRAMIN,buf);

printf("began to Update HZ font!\r\n");

strcpy((char*)pname,(char*)src); //copy src内容到pname

strcat((char*)pname,(char*)UNIGBK_PATH); //文件路径放到pname后

res=updata_HZ_fontx(pname,0); //更新UNIGBK.BIN

if(res){myfree(SRAMIN,pname);return 1;}

printf("UNIGBK.BIN Update Success!\r\n");

strcpy((char*)pname,(char*)src); //copy src内容到pname

strcat((char*)pname,(char*)GBK12_PATH);

res=updata_HZ_fontx(pname,1); //更新GBK12.FON

if(res){myfree(SRAMIN,pname);return 2;}

printf("GBK12.FON Update Success!\r\n");

strcpy((char*)pname,(char*)src); //copy src内容到pname

strcat((char*)pname,(char*)GBK16_PATH);

res=updata_HZ_fontx(pname,2); //更新GBK16.FON

if(res){myfree(SRAMIN,pname);return 3;}

printf("GBK16.FON Update Success!\r\n");

strcpy((char*)pname,(char*)src); //copy src内容到pname

strcat((char*)pname,(char*)GBK24_PATH);

res=updata_HZ_fontx(pname,3); //更新GBK24.FON

if(res){myfree(SRAMIN,pname);return 4;}

printf("GBK24.FON Update Success!\r\n");

//全部更新好了

ftinfo.fontok=0XAA;

W25QXX_Write((u8*)&ftinfo,FONTINFOADDR,sizeof(ftinfo)); //保存字库信息

}

else

printf("HZ file error!\r\n");

myfree(SRAMIN,pname);//释放内存

myfree(SRAMIN,buf);

return rval;//无错误.

}

//初始化字体

//返回值:0,字库完好.

//其他,字库丢失

u8 HZ_font_init(void)

{

u8 t=0;

W25QXX_Init();

while(t<10)//连续读取10次,都是错误,说明确实是有问题,得更新字库了

{

t++;

W25QXX_Read((u8*)&ftinfo,FONTINFOADDR,sizeof(ftinfo));//读出ftinfo结构体数据

if(ftinfo.fontok==0XAA)break;

delay_ms(20);

}

if(ftinfo.fontok!=0XAA)return 1;

return 0;

}

 

 

 

 

//更新某一个

//fxpath:路径

//fx:要更新的内容 0asc1206;1,asc1608;2,asc2412;

//返回值:0,成功;其他,失败.

u8 updata_ascii_fontx(u8 *fxpath,u8 fx)

{

u32 flashaddr=0;

FIL * fftemp;

u8 *tempbuf;

u8 res;

u16 bread;

u32 offx=0;

u8 rval=0;

fftemp=(FIL*)mymalloc(SRAMIN,sizeof(FIL)); //分配内存

if(fftemp==NULL)rval=1;

tempbuf=mymalloc(SRAMIN,4096);//分配4096个字节空间

if(tempbuf==NULL)rval=1;

res=f_open(fftemp,(const TCHAR*)fxpath,FA_READ); //打开文件

if(res)rval=2;//打开文件失败

if(rval==0)

{

switch(fx)

{

case 0:

ascii_font.asc1206_addr=ASCIIFONTINFOADDR+sizeof(ascii_font);//信息头之后,紧跟asc1206字库 15831040+25

ascii_font.asc1206_size=fftemp->fsize; //asc1206字库大小(文件大小)

flashaddr=ascii_font.asc1206_addr; //asc1206字库的起始地址

break;

case 1:

ascii_font.asc1608_addr=ascii_font.asc1206_addr+ascii_font.asc1206_size; //asc1206之后,紧跟asc1608字库

ascii_font.asc1608_size=fftemp->fsize; //asc1608字库大小(文件大小)

flashaddr=ascii_font.asc1608_addr; //asc1608字库的起始地址

break;

case 2:

ascii_font.asc2412_addr=ascii_font.asc1608_addr+ascii_font.asc1608_size; //asc1608之后,紧跟asc2412字库

ascii_font.asc2412_size=fftemp->fsize; //asc2412字库大小(文件大小)

flashaddr=ascii_font.asc2412_addr; //asc2412的起始地址

break;

}

 

res=f_read(fftemp,tempbuf,4096,(UINT *)&bread); //读取4096个数据

if(res!=FR_OK)//执行错误

{

myfree(SRAMIN,fftemp); //释放内存

myfree(SRAMIN,tempbuf);//释放内存

f_close(fftemp);

return 1;

}

W25QXX_Write(tempbuf,flashaddr,bread);//从0开始写入bread个数据

f_close(fftemp);

}

else

printf("ascii file error!\r\n");

myfree(SRAMIN,fftemp); //释放内存

myfree(SRAMIN,tempbuf);//释放内存

return res;

}

 

//更新字体文件,asc1206 asc1608 asc2412一起更新

//src:字库来源磁盘."0:",SD卡;"1:",FLASH盘,"2:",U盘.

//提示信息字体大小

//返回值:0,更新成功;

//其他,错误代码.

u8 update_ascii_font(u8* src)

{

u8 *pname;

u32 *buf;

u8 res=0;

u16 i,j;

FIL *fftemp;

u8 rval=0;

res=0XFF;

ascii_font.fontflag=0XFF; //先将字库标记为未更新

pname=mymalloc(SRAMIN,100); //申请100字节内存

buf=mymalloc(SRAMIN,4096); //申请4K字节内存

fftemp=(FIL*)mymalloc(SRAMIN,sizeof(FIL)); //分配内存

if(buf==NULL||pname==NULL||fftemp==NULL)

{

myfree(SRAMIN,fftemp);

myfree(SRAMIN,pname);

myfree(SRAMIN,buf);

return 5; //内存申请失败

}

//先查找文件是否正常

strcpy((char*)pname,(char*)src); //copy src内容到pname

strcat((char*)pname,(char*)ASC1206_PATH); //文件路径添加到pname结尾处

res=f_open(fftemp,(const TCHAR*)pname,FA_READ);

if(res)rval|=1<<4;//打开文件失败

strcpy((char*)pname,(char*)src); //copy src内容到pname

strcat((char*)pname,(char*)ASC1608_PATH);

res=f_open(fftemp,(const TCHAR*)pname,FA_READ);

if(res)rval|=1<<5;//打开文件失败

strcpy((char*)pname,(char*)src); //copy src内容到pname

strcat((char*)pname,(char*)ASC2412_PATH);

res=f_open(fftemp,(const TCHAR*)pname,FA_READ);

if(res)rval|=1<<6;//打开文件失败

myfree(SRAMIN,fftemp);//释放内存

if(rval==0)//字库文件都存在,更新字库

{

//先擦除扇区,提高后面的写入速度

for(i=0;i

{

W25QXX_Read((u8*)buf,((ASCIIFONTINFOADDR/4096)+i)*4096,4096);//读出整个扇区的内容

for(j=0;j<1024;j++)//校验数据

{

if(buf[j]!=0XFFFFFFFF)break;//需要擦除

}

if(j!=1024)W25QXX_Erase_Sector((ASCIIFONTINFOADDR/4096)+i); //需要擦除的扇区

}

myfree(SRAMIN,buf);

printf("began to Update ascii font!\r\n");

//开始更新ascii字库

strcpy((char*)pname,(char*)src);//copy src内容到pname

strcat((char*)pname,(char*)ASC1206_PATH); //ASC1206路径接到pname后

res=updata_ascii_fontx(pname,0); //更新ASC1206

if(res){myfree(SRAMIN,pname);return 1;}

printf("1206 Update Success!\r\n");

 

strcpy((char*)pname,(char*)src); //copy src内容到pname

strcat((char*)pname,(char*)ASC1608_PATH);

res=updata_ascii_fontx(pname,1); //更新ASC1608

if(res){myfree(SRAMIN,pname);return 2;}

printf("1608 Update Success!\r\n");

strcpy((char*)pname,(char*)src); //copy src内容到pname

strcat((char*)pname,(char*)ASC2412_PATH);

res=updata_ascii_fontx(pname,2); //更新ASC2412

if(res){myfree(SRAMIN,pname);return 3;}

printf("2412 Update Success!\r\n");

//全部更新好了

ascii_font.fontflag=0XAA; //标记字库存在

W25QXX_Write((u8*)&ascii_font,ASCIIFONTINFOADDR,sizeof(ascii_font)); //保存字库信息

}

myfree(SRAMIN,pname);//释放内存

myfree(SRAMIN,buf);

return rval;//无错误.

}

 

 

//初始化ascii字库

//返回值:0,字库完好.

// 其他,字库丢失

u8 ascii_font_init(void)

{

u8 t=0;

W25QXX_Init();

while(t<10)//连续读取10次,都是错误,说明确实是有问题,得更新字库了

{

t++;

W25QXX_Read((u8*)&ascii_font,ASCIIFONTINFOADDR,sizeof(ascii_font));//读出ftinfo结构体数据

if(ascii_font.fontflag==0XAA)break;

delay_ms(20);

}

if(ascii_font.fontflag!=0XAA)return 1;

return 0;

}

 

 

//字库初始化

u8 font_init(void)

{

u8 res=0;

if(ascii_font_init())

res|=1<<0;

if(ascii_font_init())

res|=1<<1;

return res;

}

 

//更新汉字库

void updateHZfont(void)

{

u8 key;

printf("ASCII Font Updating...\r\n");

while(ascii_font_init()) //检查ascii字库

{

key=update_ascii_font("0:");//更新ascii库

if(key)//更新失败

{

printf("ASCII Font Update Failed!\r\n");

delay_ms(1500);

}

}

printf("ASCII Font Update Success!\r\n");

}

//更新ascii字库

void updateasciifont(void)

{

u8 key;

printf("HZ Font Updating\r\n");

while(font_init()) //检查汉字库

{

key=update_HZ_font("0:");//更新汉字库

if(key)//更新失败

{

printf("HZ Font Update Failed!\r\n");

delay_ms(1500);

}

}

printf("HZ Font Update Success!\r\n");

}

 

 

 

 

 

//////////////////////////////////////////////////////////////////////////////////////////////

/*

int main(void)

{

u8 key,t,res;

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2

delay_init(); //延时函数初始化

uart1_init(115200); //串口初始化为115200

LCD_Init(); //初始化液晶

LED_Init(); //LED初始化

KEY_Init(); //按键初始化

 

mem_init(SRAMIN); //初始化内存池

exfuns_init(); //为fatfs相关变量申请内存

f_mount(fs[0],"0:",1); //挂载SD卡 顺便初始化SD

f_mount(fs[1],"1:",1); //挂载FLASH.顺便初始化flash

LCD_Clear(WHITE); //清屏

POINT_COLOR=RED; //设置字体为红色

res=font_init(); //检查字库,顺便初始化W25Q128

if(res)

{

switch(res)

{

case 0x01:

updateHZfont();

break;

case 0x02:

updateasciifont();

break;

case 0x03:

updateHZfont();

updateasciifont();

break;

}

}

LCD_ShowStr(60,50,200,16,"字库 OK",16,0);

while(1)

{

while(t--)//延时,同时扫描按键

{

delay_ms(1);

key=KEY_Scan(0);

if(key==KEY0_PRES) goto UPD;

if(key==KEY1_PRES) goto UPD2;

}

LED0=!LED0;

}

}

*/

 

 

 

 

 

 

 

/////////////////////////////////////////////////////////////////////////////////////////////////////

创建ascii字库文件

 

 

/*

u8*const asc1206name="0:/ASCII/ASC1206.dat"; //asc1206的生成位置

u8*const asc1608name="0:/ASCII/ASC1608.dat"; //asc1608的生成位置

u8*const asc2412name="0:/ASCII/ASC2412.dat"; //asc2412的生成位置

 

int main(void)

{

FIL* f_rec=0; //文件

DIR recdir; //目录

u8 res;

delay_init(); //延时函数初始化

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

uart1_init(115200); //串口初始化为115200

LED_Init(); //初始化与LED连接的硬件接口

KEY_Init(); //初始化按键

LCD_Init(); //初始化LCD

mem_init(SRAMIN); //初始化内部内存池

exfuns_init(); //为fatfs相关变量申请内存

f_mount(fs[0],"0:",1); //挂载SD卡(diskio.c里指定了SD卷标为0) 初始化SD

f_mount(fs[1],"1:",1); //挂载FLASH(diskio.c里指定了FLASH卷标为1)初始FLASH

POINT_COLOR=RED;

f_rec=(FIL *)mymalloc(SRAMIN,sizeof(FIL)); //开辟FIL字节的内存区域

while(f_opendir(&recdir,"0:/ASCII"))//打开/创建ascii字库文件夹

{

f_mkdir("0:/ASCII");//创建该目录

LED1=!LED1;

delay_ms(1000);

}

 

//创建一个新文件。(如果文件已存在,则创建失败 | 指定写访问对象,可以向文件写入数据

res=f_open(f_rec,(const TCHAR*)asc1206name, FA_CREATE_NEW | FA_WRITE);

f_write(f_rec,asc2_1206,sizeof(asc2_1206),&bw);

f_close(f_rec);//关闭文件

//创建一个新文件。(如果文件已存在,则创建失败 | 指定写访问对象,可以向文件写入数据)

res=f_open(f_rec,(const TCHAR*)asc1608name, FA_CREATE_NEW | FA_WRITE);

f_write(f_rec,asc2_1608,sizeof(asc2_1608),&bw);

f_close(f_rec);//关闭文件

//创建一个新文件。(如果文件已存在,则创建失败 | 指定写访问对象,可以向文件写入数据)

res=f_open(f_rec,(const TCHAR*)asc2412name, FA_CREATE_NEW | FA_WRITE);

f_write(f_rec,asc2_2412,sizeof(asc2_2412),&bw);

f_close(f_rec);//关闭文件

*/

 

你可能感兴趣的:(STM32 汉字库+ascii字库 存放到 flash中)