精华内容
下载资源
问答
  • STM32 汉字字库

    热门讨论 2012-05-19 10:28:59
    用于STM32液晶程序开发,解决开发中遇到的需要汉字问题,省去自己设计汉字字库的麻烦
  • STM32汉字字库更新实验 基于神舟3号开发板
  • 各种汉字数字英文字库,16x16,24x24,32x32,40x40,48x48,ASC12,ASC16,ASC24,ASC48 字库STM32字库芯片W25QXX的读写。Windows下生成的16x16,32字节每字: HZK16S 宋体 HZK16F 仿宋 HZK16H 黑体 HZK16K 楷体 HZK16Y ...
  • Keil MDK 4.0或以上版本,stm32 zet6烧写汉字字库到NOR Flash中
  • 在原子的基础上,改写原子代码,加上了汉字字库更新,可以直接使用。
  • STM32 汉字库+ascii字库 存放到 flash中

    千次阅读 2019-02-25 09:47:05
    #ifndef __FONTUPD_H__ #define __FONTUPD_H__ #include "sys.h"   ... //字库存在标志,0XAA,字库正常;其他,字库不存在 u32 ugbkaddr; //unigbk的地址 u32 ugbksize; //unigb...

    #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<FONTSECSIZE;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<ASCII_FONT_SECSIZE;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汉字取模显示

    2017-07-29 20:20:35
    stm32TFT屏幕汉字取模的方法显示汉字字符。简单实用。(非字库显示方法)
  • STM32+TFT彩屏实现汉字字库显示

    万次阅读 2015-08-25 00:16:49
    ...STM32+TFT彩屏实现汉字字库显示 作者: wbsouth 上传时间为: 2014-08-23 12:24 AM  3265    1    3 Cortex-M3 • stm32开发

    http://jingyan.eeboard.com/article/70998


    STM32+TFT彩屏实现汉字字库显示

    作者: wbsouth
    上传时间为: 2014-08-23 12:24 AM
     3265
     
     1
     
     3
    • stm32开发板

    TFT彩屏是大家经常用到的一个显示模块,用来显示字符图片等一些信息,作为产品的一个重要部分,实现人机交互。其中汉字显示是非常必要的,显示字符只需 要采用对应的取模软件,把字符的点阵数据放在程序中即可。当我们要显示少量且固定的汉字时也可以采用这种方法,但是,需要大量且随机的汉字时,靠取模就不 能完成了,需要汉字字库来实现。 这个实验使用的汉字大小是16*16,字库是放在SD卡根目录下sys文件夹中的。下面简单的解释一下实现过程。 先来一张图片看看实验效果。

    本实验中,涉及到SD卡的使用,文件系统的移植,LCD屏的使用等。这里主要说明的是LCD的汉字显示,首先是对SD卡的初始化,以及LCD的初始化。然后下面开始汉字以及一些字符的显示,字符的显示还是采用的字符点阵的方式。

    QQ截图20140624173814.png

    首先是判断的显示位置,是否超过屏的显示范围,如果超过则是实现换行功能。然后下面是判断显示内容的ASCII知道下一个要显示的是字符还是汉字,如果 ASCII大于0x80,则是汉字,小于0x80则是字符。因为字符是16*8,所以每显示一个字符横坐标+8,如果是汉字(16*16),横坐标 是+16。如果你要使用其它大小的字体显示,请修改相应的数据。QQ截图20140624174313.png

    在主要讲解汉字显示,字符显示和汉字一样的道理。显示汉字里面,首先开辟一个缓冲区,用来存储点阵数据,然后获取点阵数据,下面是通过获取的点阵数据来进 行打点显示。注意我们是16*16的字体,所以每行16个点,一共16行。这里简单说一下打点,主要是采用设置一块16*16显示区域,然后逐一把每个点 的数据送给LCD即可,注意要设置号彩屏内部的地址自增方向。否则容易出现错位等现象。注意最后要把显示区域设置成全屏显示。QQ截图20140624180111.png

    怎么在字库中找到对应的汉字点阵信息,这里的文件系统已经移植好了,打开字库文件。注意的是,每个汉字都有一个内码,占两个字节,通过汉字内码的高低字 节,通过公式32*((High8bit-0xa0-1)*94+(Low8bit-0xa0-1))来找到该汉字在字库中的偏移位置,然后读取32个字 节,也就是该汉字的点阵数据。字体是16*16=256。256/8=32字节。最后关闭文件就可以了。QQ截图20140624180840.png

    在整个实验中,要注意字体大小的设置,以及LCD设置的地址自增方向,否则容易出现错位现象。


    展开全文
  • STM32F103 读取字库显示汉字C程序,程序包含编译全部内容,可直接使用
  • STM32自带GB2312字库显示汉字

    万次阅读 多人点赞 2019-03-05 16:19:42
      本文介绍如何把字库文件写入单片机的flash中,然后无需再提取字模,即可实现单片机显示中文字符的功能。 下载字库到单片机flash中的指定位置   在上一篇博客中,最后留了一个想法,让单片机自带字库。现在就来...

      本文介绍如何把字库文件写入单片机的flash中,然后无需再提取字模,即可实现单片机显示中文字符的功能。

    下载字库到单片机flash中的指定位置

      在上一篇博客中,最后留了一个想法,让单片机自带字库。现在就来实现这个想法。
    我把用到的编译过的字符放在这里
      我们借助J-Flash软件把bin文件放在单片机flash中的指定位置。
      首先要新建工程,然后根据自己的板子选择型号
    在这里插入图片描述
    在这里插入图片描述
      然后打开数据文件,找到刚刚下载的bin文件
    在这里插入图片描述
    在这里插入图片描述
      根据自己单片机的flash大小输入地址,注意这个地址要与代码中的“基地址”一致
    在这里插入图片描述
      设置好以后按下快捷键F7
    在这里插入图片描述在这里插入图片描述
      成功烧录以后,代码不可以在使用此区域。——一般情况下,你的工程代码也不会大到可以覆盖这个区域。

    编写字库显示函数

      函数编写过程就不讲述了,原理都在代码里。有需要的可以自行研究。有一些没有提到的函数,可以参考上一篇博客。
      这是显示字符串的函数

    /**
      * @brief 输出12*12的汉字或6*12的字符,函数可以自动识别是中文字符还是ASCII
      * @param 第一个字符的坐标,汉字颜色,背景颜色,需要显示的字符串。背景颜色为0表示不画背景
      * @Note  汉字字模来自于字库,字库是编译好的bin文件,在_DEF_FONT_CH字库的基地址中
      * @retval None
      */
    void LCD_DrawFont_GBK12(u16 x, u16 y, u16 fc, u16 bc, char *pStr)
    {
    	unsigned char xNow,temp_width;
    	const u8 *FontModel;
    	char ch[2];
    	xNow = x;
    	while(*pStr)
    	{
    		ch[0] = *pStr;
    		pStr++;
    		ch[1] = *pStr;
    		if(ch[0] == 10)
    		{
    			x = xNow;
    			y += 12;
    		}
    		else if(ch[0] < 128)
    		{
    			temp_width = Get_Model(ch,&FontModel);
    			if(x < 128)
    				DrawFontModel(x,y,temp_width,FontModel,fc,bc);
    			x += temp_width;//下一个字符的横坐标
    		}
    		else if((ch[0] > 160) && (ch[1] > 160))	//中文
    		{
    			ch[1] = *pStr;
    			temp_width = Get_Model(ch,&FontModel);
    			if(x < 128)
    				DrawFontModel(x,y,temp_width,FontModel,fc,bc);
    				x += temp_width;//下一个字符的横坐标
    				pStr++;
    		}
    	}
    }
    
    

      这个函数用于显示单个字符

    /**
      * @brief 根据传入的参数显示一个字符,可以自动识别是中文还是英文
      * @param 第一个字符的坐标,字符的宽度(中文12英文6),颜色,背景颜色,需要显示的字符串。背景颜色为0表示不画背景
      * @Note  汉字字模来自于字库,字库是编译好的bin文件,在_DEF_FONT_CH字库的基地址中
      *         返回值并不是字库的地址,字库地址是通过指针传递的,也就是说,参数FontModel本身也是返回值
      * @retval None
      */
    static void DrawFontModel(u8 xNow,u8 yNow,u8 width,const u8 *FontModel,u16 fc, u16 bc )
    {
    	u8 bit = 0;
    	u8 m = 0xff;
    	if(FontModel)//字母为空处理
    		m = *FontModel;
    	for (u8 y = yNow; y < yNow + 12; y++)//竖着显示,先判断y坐标。
    	{
    		for(u8 x = xNow; x < xNow + width; x++)//再判断横坐标
    		{
    			if(x < 128)
    			{
    				if((m&0x01) == 0x01)
    				{
    					LCD_DrawPoint(x,y,fc);
    				}
    				else
    				{
    					if ((bc!=0)&&(fc!=bc)) LCD_DrawPoint(x,y,bc);
    				}
    			}
    			bit++;
    			m >>= 1;//字符循环右移
    			if(bit == 8)//一个字节显示完毕,则显示下一个字节
    			{
    				bit = 0;
    				if(FontModel)//空字模处理
    				{
    					FontModel ++;
              m = *FontModel;
    				}
    				else
    				{
    					m = 0xff;
    				}
    			}
    		}
    		
    	}
    }
    

      这是根据字符的标号,从flash中找到对应字符数组的 函数

    /**
      * @brief 获取字模数组的 地址
      * @param 第一个字符的坐标,字符的宽度(中文12英文6),颜色,背景颜色,需要显示的字符串。背景颜色为0表示不画背景
      * @Note  汉字字模来自于字库,字库是编译好的bin文件,在_DEF_FONT_CH字库的基地址中
      * @retval 字模的宽度
      */
    static char Get_Model(const char *ch,const u8 **FontModel)
    {
    	if((ch[0] > 0xA0) && (ch[1] > 0xA0))//中文
    	{
    		*FontModel = _DEF_FONT_CH + 18 * ((ch[0] - 161) * 94 + ch[1] - 161);//获取此字模的地址
    		return 12;
    	}
    	
    	if(*ch >= 0x20)//英文
    	{
    		*FontModel = _DEF_FONT_EN + 9 * (ch[0] - 0x20);
    		return 6;
    	}
    	*FontModel = _DEF_FONT_EN;//无法匹配,显示空白
    		return 0;
    }
    
    

      GB2312的字符计算是怎么算的?GB2312的编号可以帮助我们找到字符,简单来说,就是GB2312规定对收录的每个字符采用两个字节表示,第一个字节为“高字节”,对应94个区;第二个字节为“低字节”,对应94个位。所以它的区位码范围是:0101-9494。区号和位号分别加上0xA0就是GB2312编码。例如最后一个码位是9494,区号和位号分别转换成十六进制是5E5E,0x5E+0xA0=0xFE,所以该码位的GB2312编码是FEFE。
      这也就是为什么我们的代码中要乘以94了。
      关于GB2312的详细资料可以参考这篇博客
      在主函数中我调用了显示函数:

    	ST7735S_CPT144_Initial();
    	LCD_BG_Color(GREEN);
    
    	LCD_DrawFont_GBK12(0,0,BLACK,GREEN,"来自geekYatao的博客");
    	LCD_DrawFont_GBK12(0,12,BLACK,GREEN,"ABCabc123,.?《》");
    	LCD_DrawFont_GBK12(0,24,BLACK,GREEN,"犇鱻羴显示不出来");
    

      另外我还定义了汉字字符的基地址,与英文字符的数组

    extern const u8 _FontLibEn612[];
    #define _DEF_FONT_CH     (const u8*)(0x080DC000)  //字库的基地址
    #define _DEF_FONT_EN            _FontLibEn612
    
    extern const u8 _FontLibEn612[] = { 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,	// 0x20  
                            0x0,0x40,0x10,0x4,0x41,0x10,0x0,0x1,0x0,	// 0x21 !
                            0x0,0xA5,0x28,0x0,0x0,0x0,0x0,0x0,0x0,	// 0x22 "
                            0x0,0x40,0x51,0x3F,0xA5,0xFC,0x8A,0x2,0x0,	// 0x23 #
                            0x0,0xE1,0x55,0x85,0xC1,0x50,0xD5,0x43,0x0,	// 0x24 $
                            0x0,0x20,0x55,0x8D,0x42,0xB1,0xAA,0x4,0x0,	// 0x25 %
                            0x0,0x40,0x28,0x8A,0x57,0x55,0x89,0xD,0x0,	// 0x26 &
                            0x80,0x20,0x4,0x0,0x0,0x0,0x0,0x0,0x0,	// 0x27 '
                            0x0,0x8,0x21,0x8,0x82,0x20,0x8,0x4,0x2,	// 0x28 (
                            0x80,0x40,0x20,0x8,0x82,0x20,0x8,0x21,0x0,	// 0x29 )
                            0x0,0x0,0x10,0x95,0xE3,0x54,0x4,0x0,0x0,	// 0x2A *
                            0x0,0x40,0x10,0xC4,0x47,0x10,0x4,0x0,0x0,	// 0x2B +
                            0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x20,0x4,	// 0x2C ,
                            0x0,0x0,0x0,0xC0,0x7,0x0,0x0,0x0,0x0,	// 0x2D -
                            0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x0,	// 0x2E .
                            0x0,0x84,0x20,0x8,0x41,0x8,0x82,0x10,0x0,	// 0x2F /
                            0x0,0xE0,0x44,0x51,0x14,0x45,0x91,0x3,0x0,	// 0x30 0
                            0x0,0x40,0x18,0x4,0x41,0x10,0x84,0x3,0x0,	// 0x31 1
                            0x0,0xE0,0x44,0x11,0x42,0x8,0xC1,0x7,0x0,	// 0x32 2
                            0x0,0xE0,0x44,0x10,0x3,0x41,0x91,0x3,0x0,	// 0x33 3
                            0x0,0x80,0x30,0x8A,0x92,0x78,0x8,0x6,0x0,	// 0x34 4
                            0x0,0xF0,0x5,0xC1,0x3,0x41,0x91,0x3,0x0,	// 0x35 5
                            0x0,0xE0,0x24,0xC1,0x13,0x45,0x91,0x3,0x0,	// 0x36 6
                            0x0,0xF0,0x25,0x8,0x41,0x10,0x4,0x1,0x0,	// 0x37 7
                            0x0,0xE0,0x44,0x91,0x13,0x45,0x91,0x3,0x0,	// 0x38 8
                            0x0,0xE0,0x44,0x51,0xE4,0x41,0x92,0x3,0x0,	// 0x39 9
                            0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x1,0x0,	// 0x3A :
                            0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x41,0x0,	// 0x3B ;
                            0x0,0x8,0x21,0x84,0x40,0x20,0x10,0x8,0x0,	// 0x3C <
                            0x0,0x0,0x0,0x1F,0x0,0x7C,0x0,0x0,0x0,	// 0x3D =
                            0x80,0x40,0x20,0x10,0x8,0x21,0x84,0x0,0x0,	// 0x3E >
                            0x0,0xE0,0x44,0x11,0x42,0x10,0x0,0x1,0x0,	// 0x3F ?
                            0x0,0xE0,0x44,0x59,0x55,0x75,0x81,0x7,0x0,	// 0x40 @
                            0x0,0x40,0x10,0x8C,0xA2,0x78,0xD2,0xC,0x0,	// 0x41 A
                            0x0,0xF0,0x48,0x92,0x23,0x49,0xD2,0x3,0x0,	// 0x42 B
                            0x0,0xE0,0x45,0x41,0x10,0x4,0x91,0x3,0x0,	// 0x43 C
                            0x0,0xF0,0x48,0x92,0x24,0x49,0xD2,0x3,0x0,	// 0x44 D
                            0x0,0xF0,0x49,0x8A,0xA3,0x8,0xD2,0x7,0x0,	// 0x45 E
                            0x0,0xF0,0x49,0x8A,0xA3,0x8,0xC2,0x1,0x0,	// 0x46 F
                            0x0,0xC0,0x49,0x41,0x90,0x47,0x12,0x3,0x0,	// 0x47 G
                            0x0,0x30,0x4B,0x92,0x27,0x49,0xD2,0xC,0x0,	// 0x48 H
                            0x0,0xF0,0x11,0x4,0x41,0x10,0xC4,0x7,0x0,	// 0x49 I
                            0x0,0xE0,0x23,0x8,0x82,0x20,0x48,0x72,0x0,	// 0x4A J
                            0x0,0x70,0x4B,0x8A,0xA1,0x28,0xD2,0xD,0x0,	// 0x4B K
                            0x0,0x70,0x8,0x82,0x20,0x8,0xE2,0xF,0x0,	// 0x4C L
                            0x0,0xB0,0x6D,0xDB,0x56,0x55,0x55,0x5,0x0,	// 0x4D M
                            0x0,0xB0,0x4B,0x96,0xA5,0x69,0xD2,0x5,0x0,	// 0x4E N
                            0x0,0xE0,0x44,0x51,0x14,0x45,0x91,0x3,0x0,	// 0x4F O
                            0x0,0xF0,0x48,0x92,0x23,0x8,0xC2,0x1,0x0,	// 0x50 P
                            0x0,0xE0,0x44,0x51,0x14,0x5D,0x99,0x83,0x1,	// 0x51 Q
                            0x0,0xF0,0x48,0x92,0xA3,0x48,0xD2,0xD,0x0,	// 0x52 R
                            0x0,0xE0,0x45,0x81,0x81,0x40,0xD1,0x3,0x0,	// 0x53 S
                            0x0,0xF0,0x55,0x4,0x41,0x10,0x84,0x3,0x0,	// 0x54 T
                            0x0,0x30,0x4B,0x92,0x24,0x49,0x12,0x3,0x0,	// 0x55 U
                            0x0,0x30,0x4B,0x92,0xA2,0x30,0x4,0x1,0x0,	// 0x56 V
                            0x0,0x50,0x55,0x95,0xA3,0x28,0x8A,0x2,0x0,	// 0x57 W
                            0x0,0xB0,0x29,0xA,0x41,0x28,0xCA,0x6,0x0,	// 0x58 X
                            0x0,0xB0,0x29,0xA,0x41,0x10,0x84,0x3,0x0,	// 0x59 Y
                            0x0,0xF0,0x25,0x8,0x41,0x8,0xD2,0x7,0x0,	// 0x5A Z
                            0x0,0x47,0x10,0x4,0x41,0x10,0x4,0xC1,0x1,	// 0x5B [
                            0x80,0x20,0x8,0x4,0x81,0x20,0x8,0x4,0x0,	// 0x5C '\'
                            0x80,0x83,0x20,0x8,0x82,0x20,0x8,0xE2,0x0,	// 0x5D ]
                            0x0,0xA1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,	// 0x5E ^
                            0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xFC,	// 0x5F _
                            0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,	// 0x60 `
                            0x0,0x0,0x0,0x0,0x23,0x71,0x12,0xF,0x0,	// 0x61 a
                            0x0,0x30,0x8,0x82,0x23,0x49,0x92,0x3,0x0,	// 0x62 b
                            0x0,0x0,0x0,0x0,0x27,0x9,0x2,0x7,0x0,	// 0x63 c
                            0x0,0x80,0x41,0x10,0x27,0x49,0x12,0xF,0x0,	// 0x64 d
                            0x0,0x0,0x0,0x0,0x23,0x79,0x2,0x7,0x0,	// 0x65 e
                            0x0,0x80,0x13,0x84,0x47,0x10,0x84,0x7,0x0,	// 0x66 f
                            0x0,0x0,0x0,0x0,0x2F,0x31,0x82,0x27,0x72,	// 0x67 g
                            0x0,0x30,0x8,0x82,0x23,0x49,0xD2,0xD,0x0,	// 0x68 h
                            0x0,0x40,0x0,0x80,0x41,0x10,0x84,0x3,0x0,	// 0x69 i
                            0x0,0x80,0x0,0x0,0x83,0x20,0x8,0x82,0x1C,	// 0x6A j
                            0x0,0x30,0x8,0x82,0xAE,0x38,0xD2,0xD,0x0,	// 0x6B k
                            0x0,0x70,0x10,0x4,0x41,0x10,0xC4,0x7,0x0,	// 0x6C l
                            0x0,0x0,0x0,0xC0,0x53,0x55,0x55,0x5,0x0,	// 0x6D m
                            0x0,0x0,0x0,0xC0,0x23,0x49,0xD2,0xD,0x0,	// 0x6E n
                            0x0,0x0,0x0,0x0,0x23,0x49,0x12,0x3,0x0,	// 0x6F o
                            0x0,0x0,0x0,0xC0,0x23,0x49,0x92,0x23,0x1C,	// 0x70 p
                            0x0,0x0,0x0,0x0,0x27,0x49,0x12,0x7,0xE1,	// 0x71 q
                            0x0,0x0,0x0,0xC0,0x66,0x8,0xC2,0x1,0x0,	// 0x72 r
                            0x0,0x0,0x0,0x80,0x27,0x30,0x90,0x7,0x0,	// 0x73 s
                            0x0,0x0,0x10,0x84,0x43,0x10,0x4,0x6,0x0,	// 0x74 t
                            0x0,0x0,0x0,0xC0,0x26,0x49,0x12,0xF,0x0,	// 0x75 u
                            0x0,0x0,0x0,0xC0,0x2D,0x29,0xC,0x1,0x0,	// 0x76 v
                            0x0,0x0,0x0,0x40,0x55,0x39,0x8A,0x2,0x0,	// 0x77 w
                            0x0,0x0,0x0,0xC0,0xA6,0x10,0xCA,0x6,0x0,	// 0x78 x
                            0x0,0x0,0x0,0xC0,0x2D,0x29,0xC,0x41,0xC,	// 0x79 y
                            0x0,0x0,0x0,0x80,0x87,0x10,0x84,0x7,0x0,	// 0x7A z
                            0x0,0x86,0x20,0x8,0x81,0x20,0x8,0x82,0x1,	// 0x7B {
                            0x8,0x82,0x20,0x8,0x82,0x20,0x8,0x82,0x20,	// 0x7C |
                            0x80,0x41,0x10,0x4,0x42,0x10,0x4,0x61,0x0,	// 0x7D }
                            0x42,0x89,0x1,0x0,0x0,0x0,0x0,0x0,0x0,	// 0x7E ~
                            0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0	// 0x20  
                            };
    
    

    效果

      GB2312包含的字符也不是特别多,还有一些生僻字,如犇鱻羴,显示不出来,这个乱码为啥还没时间考虑。以后有兴趣了,可以搞个GBK的编码。想显示一些常用中文字符就不用费劲取字模了。
    在这里插入图片描述

    展开全文
  • STM32制作FLASH字库

    2020-08-15 13:42:30
    有两种方式写入字库。一种把FAT系统做到FLASH里,第二种是直接写入FLASH后一段地址空间里。相比之下,我选择后者。为什么呢?FATFS太大了!你要是每次显示几个汉字就去移植,再去编译下载,那可真慢。。所以后者直接...

    自己做了一块板子,FLASH(W25Qxx)都是空的,自己写了段简洁的代码用FAT从SD卡写到FLASH中。
    有两种方式写入字库。一种把FAT系统做到FLASH里,第二种是直接写入FLASH后一段地址空间里。相比之下,我选择后者。为什么呢?FATFS太大了!你要是每次显示几个汉字就去移植,再去编译下载,那可真慢。。所以后者直接移植一个FLASH驱动就可以了。代码不多,用到什么写什么嘛,实现小功能就小代码呗。
    下面贴代码了,大概讲一下

    地址定义

    
    //W25Q128! -> 总空间:16M
    #define	SPI_FONT_START					12			//从12M开始写入,其余是文件系统
    
    
    #define	FONT16x16_SPI_ADDR				(SPI_FONT_START*1024/16 * 4096)	//16x16字库
    #define	FONT16x16_SPI_SIZE				282752							//使用空间Byte
    #define	FONT16x16_SPI_TOTAL_SIZE		(280*1024)						//占用空间
    
    #define	FONT24x24_SPI_ADDR				(FONT16x16_SPI_ADDR+FONT16x16_SPI_TOTAL_SIZE)
    #define	FONT24x24_SPI_SIZE				636192							//使用空间Byte
    #define	FONT24x24_SPI_TOTAL_SIZE		(624*1024)						//占用空间
    
    #define	FONT32x32_SPI_ADDR				(FONT24x24_SPI_ADDR+FONT24x24_SPI_TOTAL_SIZE)
    #define	FONT32x32_SPI_SIZE				1131008 						//使用空间Byte
    #define	FONT32x32_SPI_TOTAL_SIZE		(1108*1024)						//占用空间
    

    特别注意一点,文件空间和占用空间不一样,和Window一样,一个扇区4KB,哪怕超了1bit也要占用一个扇区。
    这里根据自己需要定义要存的位置。但是自己要计算好空间够不够。

    实现代码

    代码由于是我自己写的,所以我从简,我也挺烦一大串复杂冗余的代码。

    u8 exchangeBuf[4096]	__attribute__((at(0XC0000000)));
    
    FRESULT	f_res;
    FIL	fil;
    UINT spi_btr;
    
    //ph: 16x16字库文件路径	绝对路径!
    void Update_SPI_FONT16x16(const TCHAR* ph)
    {
    	u16 NumtoRead = 0;
    	u16 ByteCnt = 0;
    	u16 spi_offset = 0;
    	u16 Data_Reserve = 0;
    	f_res = f_open(&fil,ph,FA_OPEN_EXISTING|FA_READ);
    	NumtoRead = FONT16x16_SPI_TOTAL_SIZE/4096-1;					//完整扇区读写
    	Data_Reserve = FONT16x16_SPI_SIZE -(FONT16x16_SPI_TOTAL_SIZE - 4096);	//剩余扇区读写
    	if(f_res == FR_OK)
    	{
    		printf("\r\n打开文件成功");
    		printf("\r\n开始写入SPI FLASH");
    		while(NumtoRead != 0)
    		{
    			f_res = f_lseek(&fil,4096*spi_offset);
    			f_res = f_read(&fil,exchangeBuf,4096,&spi_btr);
    			if(f_res == FR_OK) 
    			{
    				SPI_FLASH_BufferWrite(exchangeBuf,FONT16x16_SPI_ADDR+4096*spi_offset,4096);
    				ByteCnt+=4;
    				spi_offset++;
    				printf("\r\n已写入 %d 个字节",ByteCnt);
    				
    				if(f_res == FR_OK)
    					NumtoRead--;
    				else
    				{
    					printf("\r\nSD卡文件偏移失败!!");
    					return;
    				}
    			}
    			else
    			{
    				printf("\r\n读取失败退出写入!!");
    				return;
    			}
    		}
    		f_res = f_read(&fil,exchangeBuf,Data_Reserve,&spi_btr);	//剩余数据写入
    		if(f_res == FR_OK)
    		{
    			SPI_FLASH_BufferWrite(exchangeBuf,FONT16x16_SPI_ADDR+4096*spi_offset,Data_Reserve);
    			printf("\r\n已经完成SPI FLASH 16x16的读写!");
    			f_res = f_close(&fil);
    			if(f_res == FR_OK) printf("\r\n"),printf("\r\n成功完成读写过程!");
    		}
    		else
    		{
    			printf("\r\n写入数据不完整!!需要重新写入");
    		}
    	}
    	else
    	{
    		printf("\r\n打开文件失败");
    	}
    }
    

    我从SDRAM开了片4KB空间给缓冲区(因为FLASH一个扇区4KB)
    什么?要SDRAM?
    慢着!别走这是我图快。。不用SDRAM完全可以的。
    你只要从STM32内存里分配256个也可以。只是需要多写几次罢了,记得地址每次要偏移256B!但是有SRAM/SDRAM的朋友就不会觉得那么麻烦了(也就是代码麻烦)。。
    这是16x16的字库,文件比较小。对于24x24、32x32一样的代码,把宏改一下。

    字库使用

    对于没接触过字库文件的的确很懵,我也是总觉得那玩意前面有个文件头、信息头啥的,还要加偏移。。但是字库这玩意的确没有,按GBK编码寻址就行了,这里大概说一下,毕竟不是主题

    u32 Get_GBK_OffSet_Addr(const u16 Hz)
    {
    	u8 CodeH = 0,CodeL=0;
    	u32 Addr;
    	CodeH = (u8)(Hz >> 8);
    	CodeL = (u8)(Hz & 0x00FF);
    	Addr = (((CodeH - 0xA0 - 1)*94) + (CodeL-0xA0 - 1)) * (Font_Size * Font_Size / 8);
    	return Addr;
    }
    

    这是按GB2312的编码来的,0XA0就是ASCII最后一个码,其他算法没去具体了解。按这个计算公式
    你要调用?

    Get_GBK_OffSet_Addr('汉');
    

    得到偏移地址代入SPIFLASH字库基地址就可以显示了

    本人学习笔记,热爱分享
    <完>

    展开全文
  • 使有STM32F103和OLED 1.3inch I2C接口,驱动高通GT32L24M0140字库显示16*16和24*24点库汉字,内附高通字库FLASH镜象,学习使用可直接写入W25Q64,商业应用请选用高通产芯片,否则后果自负。
  • 第53章 STM32H7的LTDC应用之汉字小字库和全字库制作 本章教程为大家讲解汉字小字库和全字库的制作方式,实际项目中用到的地方比较多。 53.1 初学者重要提示 53.2 使用MakeDot小软件生成C文件格式小字库方法 53.3...
  • 第43章 STM32F429的LTDC应用之汉字小字库和全字库制作 本章教程为大家讲解汉字小字库和全字库的制作方式,实际项目中用到的地方比较多。 目录 第43章 STM32F429的LTDC应用之汉字小字库和全字库制作 43.1 初学者...
  • 1,调用这个函数 void Show_Chinese(u8 x,u16 y,u8 *font) //在x,y地址显示16*16点阵汉字 { u8 temp,t,t1,c=1; u16 y0=y; if(c==1) { for(t=0;t<32;t++) { temp=*font++; for(t1=0;...
  • STM32F103 TFT彩屏显示汉字字符(取摸 无字库)C程序,程序包含编译后全部内容,可直接使用
  • 沈阳理工大学课程设计报告 摘 要 随着社会经济的迅速发展...STM32 的LCD 显示可以更好 的满足各种需求也更便于操作和实现汉字显示系统主要由 STM32 芯片作为 LCD 彩色 显示屏的主要核心控制器并且通过字库制作软件制
  • 沈阳理工大学课程设计报告 摘 要 随着社会经济的迅速发展...STM32 的 LCD 显示可以更 好的满足各种需求也更便于操作和实现汉字显示系统主要由 STM32 芯片作为 LCD 彩色显示屏的主要核心控制器并且通过字库制作软件制
  • stm32+lcd显示汉字之DIY图形及导入字库

    千次阅读 多人点赞 2020-02-25 23:42:22
    上一篇博客,给大家介绍了在LCD上显示汉字/特殊图形需要知道对应的显示编码(GBK码/ASCII码),显示编码对应着每个图形的点阵集(数组),我们可以通过这个点阵集,将自己DIY的图形显示在LCD上面。现在先说一下怎么...
  • 自己画的STM32板子上设计了一个w25xx的外部储存器,在某宝上买了一个3.2寸的屏,我用外部储存器当字库,可惜么有烧录工具,也没TF卡,于是各种上网,各种CSDN,搞出来这么一个串口发送GB2312字库文件到w25xx FLASH中...
  • STM32LCD显示汉字

    2021-05-15 14:59:01
    STM32LCD显示汉字 不能字符串显示,毕竟不是存了字库,只能显示单个汉字,这种需要我们自己去取模,然后存放到数组,基于正点原子的例程改的,要注意的是一个汉字在数组中全部数据是全存在一起的,如下,size=24,一...
  • STM32F103 TFT彩屏显示汉字字符(取摸 无字库)C程序,程序包含编译后全部内容,可直接使用
  • stm32【GT30L32S4W字库芯片】

    千次阅读 多人点赞 2020-04-20 03:05:47
    测试平台:STM32F103RFT6 库版本:官方标准库3.5.0版本 字库芯片:GT30L32S4W 字库标准:GB2312国标汉字,ASCII字符 点阵排列方式:字节横置横排 字库套数:4套(12x12,16x16,24x24,32x32点阵) 驱动方式:SPI 在...

空空如也

空空如也

1 2 3 4 5 ... 7
收藏数 130
精华内容 52
关键字:

stm32汉字字库