1、在需要程序支持全部中文字库时,CPU内部FLASH往往不够用,这时候需要采用外部存储空间来存放字库数据。可以选用的外部存储空间有 外部FLASH、EEPROM、SD卡等。
2、汉字的编码方式有很多种,常用的为GBK或者GB2312。GB2312支持了全部的简体汉字约6000个,兼容ASCII码、 数学符号、罗马希腊的字母、日文的假名等,全部字体有7000多个,可以满足大部分情况下使用; GBK在GB2312基础上增加了两万多个汉字(包括繁体字、生僻字等),涵盖了所有可能用的汉字。在这里采用的是GB2312编码方式。
3、字库数据通常是以二进制方式放在存储空间里,制作二进制字库的工具可以从网上下载到很多种,这里采用的是 “字模III 增强版 V3.91”,还有个“汉字字模点阵数据批量生成工具 V5.3”。这里我生成的是微软雅黑16号字体,文件名称为“ wryh16号 21x28 GB2312全.bin”,每个字大小为21x28,在UCGUI里字体名称为“ GUI_FontWRYH28”。

4、外部存储采用的是K9F2808U0C,16M*8 bits NAND FLASH。
5、准备工作完成后
    第一步、编一个STM32的小程序,完成的功能是:将串口收到的数据按顺序存放入FLASH中。
    第二步、用串口助手将二进制字库文件通过串口发送给STM32,STM32将字库存入FLASH。这里要知道每个字库数据的起始位置。(另外需要注意:网络上很多串口工具的功能都不太完善,质量参差不齐,有些有缺陷且没有提示,例如常用的一个SSCOM32,这个软件最多只能发送512K大小的二进制文件,在发送的文件超过512K时,512K后边的数据会丢失,并且没有提示;同时,这个工具无法在检验方式下发送数据。这里我用的是SSCOM4.2,可以满足使用要求。) 
    第三步、UCGUI的显示字符函数并不能直接支持外部字库这种形式,需要修改两个文件,增加两个文件。外部字库是通过定义一种新的字体的方式加入到UCGUI中。
    A、修改 GUI.h
    增加一句,声明新增加的字体:

/*extern fonts*/
extern GUI_CONST_STORAGE GUI_FONT GUI_FontWRYH28;

B、修改GUI_UC_EncodeNone.c
    修改的地方比较多,

#include "GUI_Protected.h"
/*********************************************************************
*
*       Static code
*
**********************************************************************
*/
/*********************************************************************
*
*       _GetCharCode
*
* Purpose:
*   Return the UNICODE character code of the current character.
*/
static U16 _GetCharCode(const char GUI_UNI_PTR * s) {
//  return *(const U8 GUI_UNI_PTR *)s;
  if((*s) > 0xa0)
  {
      return *(const U16 GUI_UNI_PTR *)s;
  }else{
      return *(const U8 GUI_UNI_PTR *)s;
  }
}
/*********************************************************************
*
*       _GetCharSize
*
* Purpose:
*   Return the number of bytes of the current character.
*/
static int _GetCharSize(const char GUI_UNI_PTR * s) {
//  GUI_USE_PARA(s);
//  return 1;
  if((*s) > 0xa0)
  {
      return 2;
  }else{
      return 1;
  }
}
/*********************************************************************
*
*       _CalcSizeOfChar
*
* Purpose:
*   Return the number of bytes needed for the given character.
*/
static int _CalcSizeOfChar(U16 Char) {
//  GUI_USE_PARA(Char);
//  return 1;
  if(Char > 0xa0a0)
  {
      return 2;
  }else{
      return 1;
  }
}
/*********************************************************************
*
*       _Encode
*
* Purpose:
*   Encode character into 1/2/3 bytes.
*/
static int _Encode(char *s, U16 Char) {
//  *s = (U8)(Char);
//  return 1;
  if(Char > 0xa0a0)
  {
      *((U16 *)s) = (U16)(Char);
      return 2;
  }else{
      *s = (U8)(Char);
      return 1;
  }
}
/*********************************************************************
*
*       Static data
*
**********************************************************************
*/
/*********************************************************************
*
*       _API_Table
*/
const GUI_UC_ENC_APILIST GUI__API_TableNone = {
  _GetCharCode,     /*  return character code as U16 */
  _GetCharSize,     /*  return size of character: 1 */
  _CalcSizeOfChar,  /*  return size of character: 1 */
  _Encode           /*  Encode character */
};
/*********************************************************************
*
*       Exported code
*
**********************************************************************
*/
/*********************************************************************
*
*       GUI_UC_SetEncodeNone
*/
void GUI_UC_SetEncodeNone(void) {
  GUI_LOCK();
  GUI_Context.pUC_API = &GUI__API_TableNone;
  GUI_UNLOCK();
}
C、增加字体文件:FWRYH21x28.c

#include "GUI.h"
#include "GUIType.h"
#include "fsmc_nand.h"
extern int GUIPROP_X_GetCharDistX(U16P c);
extern void GUIPROP_X_DispChar(U16P c);
extern GUI_CONST_STORAGE GUI_CHARINFO GUI_Font24_ASCII_CharInfo[95];
GUI_CONST_STORAGE GUI_CHARINFO GUI_FontWRYH28_CharInfo[3] =
{
     {21, 21, 3, (void *) Bank_NAND_ADDR }    //GB2312±àÂë×Ö·ûÆðʼλÖã¬0XA0A0
    ,{17, 17, 3, (void *)(Bank_NAND_ADDR)}   //GB2312ÄÚASCIIÂëÆðʼλÖÃ
    ,{21, 21, 3, (void *) Bank_NAND_ADDR }   //GB2312ÄÚASCIIÂëÖ®ºóµÄ×Ö·û
};
GUI_CONST_STORAGE GUI_FONT_PROP GUI_FontWRYH28_Prop3 = {
    0xa4A1,
    0xF7FE,
    &GUI_FontWRYH28_CharInfo[2],
    (void *)0
};
GUI_CONST_STORAGE GUI_FONT_PROP GUI_FontWRYH28_Prop2 = {
    0xa3A1,
    0xA3FE,
    &GUI_FontWRYH28_CharInfo[1],
    (void *)&GUI_FontWRYH28_Prop3
};
GUI_CONST_STORAGE GUI_FONT_PROP GUI_FontWRYH28_Prop1 = {
    0xa1a1,
    0xA2FC,
    &GUI_FontWRYH28_CharInfo[0],
    (void *)&GUI_FontWRYH28_Prop2
};
GUI_CONST_STORAGE GUI_FONT_PROP GUI_FontWRYH28_PropASCII = {
    0x0020                         /* first character */
    ,0x007E                         /* last character  */
    ,&GUI_Font24_ASCII_CharInfo[0]  /* address of first character */
    ,(const GUI_FONT_PROP*)&GUI_FontWRYH28_Prop1        /* pointer to next GUI_FONT_PROP */
};
GUI_CONST_STORAGE GUI_FONT GUI_FontWRYH28 =
{
    GUI_FONTTYPE_PROP_X,
    28, //xsize
    28, //ysize
    1,  //x·½Ïò·Å´ó±¶Êý
    1,  //y·½Ïò·Å´ó±¶Êý
    (void GUI_CONST_STORAGE *)&GUI_FontWRYH28_PropASCII
};


        D、增加字体显示程序文件:GUICharPEx.c

#include <stddef.h>           /* needed for definition of NULL */
#include "GUI_Private.h"
#include "fsmc_nand.h"
#define BYTES_PER_FONT  84
extern GUI_CONST_STORAGE GUI_CHARINFO GUI_Font24_ASCII_CharInfo[95];
static U8 GUI_FontDataBuf[BYTES_PER_FONT];
/* ×Ö¿âÍⲿº¯Êý²¿·Ö */
U8 GUI_X_GetFontData(char* font, U32 oft, U8 *ptr, U8 bytes)
{
    U32 status;
    status = FSMC_NAND_ReadToBuffer(ptr, (U32)font + oft, bytes); 
    if((status & 0x40) != NAND_READY)
    {
        return (1);
    }
    return (0);
}
static void GUI_GetDataFromMemory(const GUI_FONT_PROP GUI_UNI_PTR *pProp, U16P c)
{
    I16 BytesPerFont;
    U32 oft;
    char *font = (char *)pProp->paCharInfo->pData;
    BytesPerFont = GUI_Context.pAFont->YSize * pProp->paCharInfo->BytesPerLine;//ÿ¸ö×ÖÄ£µÄÊý¾Ý×Ö½Ú¸öÊý
    if(BytesPerFont > BYTES_PER_FONT)
    {
        BytesPerFont = BYTES_PER_FONT;
    }
    if(c < 0x80)
    {
//        oft = (c - 0x20) * BytesPerFont;
        if(0x20 == c)
        {
            for(oft = 0; oft < BytesPerFont; oft++)
            {
                GUI_FontDataBuf[oft] = 0;
            }
        }
    }
    else
    {
        oft = (((c>>8) - 0xa1)*94 + ((c&0xff) - 0xA1)) * BytesPerFont;//ÖÐÎÄ×Ö·ûµØÖ·Æ«ÒÆËã·¨
        GUI_X_GetFontData(font, oft, GUI_FontDataBuf, BytesPerFont);
    }
}
void GUIPROP_X_DispChar(U16P c)
{
    int BytesPerLine;
    GUI_DRAWMODE DrawMode = GUI_Context.TextMode;
    const GUI_FONT_PROP GUI_UNI_PTR *pProp = GUI_Context.pAFont->p.pProp;
    if((c < 0x80) && (c > 0x20)) c = (c<<8) + 0x80a3;
    if(0x20 != c) c = (c>>8) + (c<<8);
    //ËÑË÷¶¨Î»×Ö¿âÐÅÏ¢
    for(; pProp; pProp = pProp->pNext)
    {
        if((c >= pProp->First) && (c <= pProp->Last)) break;
    }
    if(pProp)
    {
        GUI_DRAWMODE OldDrawMode;
        const GUI_CHARINFO GUI_UNI_PTR *pCharInfo = pProp->paCharInfo;
        GUI_GetDataFromMemory(pProp, c);
        BytesPerLine = pCharInfo->BytesPerLine;
        OldDrawMode = LCD_SetDrawMode(DrawMode);
        LCD_DrawBitmap(GUI_Context.DispPosX, GUI_Context.DispPosY,
                        pCharInfo->XSize, GUI_Context.pAFont->YSize,
                        GUI_Context.pAFont->XMag, GUI_Context.pAFont->YMag,
                        1,
                        BytesPerLine,
                        &GUI_FontDataBuf[0],
                        &LCD_BKCOLORINDEX
                        );
        /* Fill empty pixel lines*/
        if(GUI_Context.pAFont->YDist > GUI_Context.pAFont->YSize)
        {
            int YMag = GUI_Context.pAFont->YMag;
            int YDist = GUI_Context.pAFont->YDist * YMag;
            int YSize = GUI_Context.pAFont->YSize * YMag;
            if(DrawMode != LCD_DRAWMODE_TRANS)
            {
                LCD_COLOR OldColor = GUI_GetColor();
                GUI_SetColor(GUI_GetBkColor());
                LCD_FillRect(GUI_Context.DispPosX, GUI_Context.DispPosY + YSize,
                                GUI_Context.DispPosX + pCharInfo->XSize,
                                GUI_Context.DispPosY + YDist
                            );
                GUI_SetColor(OldColor);                
            }
        }
        LCD_SetDrawMode(OldDrawMode);
        GUI_Context.DispPosX += pCharInfo->XDist * GUI_Context.pAFont->XMag;
    }
}
int GUIPROP_X_GetCharDistX(U16P c)
{
    const GUI_FONT_PROP GUI_UNI_PTR *pProp = GUI_Context.pAFont->p.pProp;
    if((c < 0x80) && (c > 0x20)) c = (c<<8) + 0x80a3;
    if(0x20 != c) c = (c>>8) + (c<<8);
    for(; pProp; pProp = pProp->pNext)
    {
        if((c >= pProp->First) && (c <= pProp->Last)) break;
    }
    return (pProp)?(pProp->paCharInfo->XSize * GUI_Context.pAFont->XMag) : 0;
}
E、修改GUIType.h
        在此文件里增加:

#define GUI_FONTTYPE_PROP_X  \
    GUIPROP_X_DispChar,\
    GUIPROP_X_GetCharDistX,\
    GUIMONO_GetFontInfo, \
    GUIMONO_IsInFont, \
    (tGUI_ENC_APIList*)0 

按以上修改方式即可以用GUI_DispString("欢迎来到汉字的世界")来显示汉字。可以用同样的方法再增加一种或多种字体。使用中注意几个问题:
1、每种字库数据在存储空间里的起始地址 
2、STM32内存里的数据是 低字节在前,高字节在后,而字库制作工具生成的二进制文件有高字节在前的,也有高字节在前的,程序编写时需要按实际情况修改。

STM32 + UCGUI+外扩NAND FLASH 中文字库支持方法相关推荐

  1. FSMC外设接口来外扩SRAM芯片、flash芯片

    1.STM32学习笔记-FSMC外扩SRAM_行之无边的博客-CSDN博客_stm32外扩sram STM32控制器芯片内部有一定大小的SRAM及FLASH作为内存和程序存储空间,但当程序较大,内存和 ...

  2. linux提高nand速度,linux-2.6.31.1内核支持Nand Flash

    linux-2.6.31.1支持Nand Flash 目的:使NandFlash驱动同时支持64M, 256M或更高容量的NandFlash 将linux内核解压在/opt目录下,修改内核源码文件,添 ...

  3. uboot研读笔记 | 05 - 移植uboot 2012.04到JZ2440(支持Nand Flash读写)

    项目开源地址:https://github.com/Mculover666/uboot-jz2440 0. 教程完整目录 00 - 嵌入式Linux系统中Bootloader的作用和基本运行原理 01 ...

  4. nand flash 个人觉得写得比较好的文章

    [详解]如何编写Linux下Nand Flash驱动 版本:v2.2.1 Crifan Li 摘要 本文先解释了Nand Flash相关的一些名词,再从Flash硬件机制开始,介绍到Nand Flas ...

  5. nand flash 经典 全面 ------如何编写Linux下Nand Flash驱动

    Crifan Li 摘要 本文先解释了Nand Flash相关的一些名词,再从Flash硬件机制开始,介绍到Nand Flash的常见的物理特性,且深入介绍了Nand Flash的一些高级功能,然后开 ...

  6. Nand flash(一)硬件实现机制

    Flash全名叫做Flash Memory,属于非易失性存储设备(Non-volatile Memory Device),与此相对应的是易失性存储设备(Volatile Memory Device). ...

  7. 如何编写linux下nand flash驱动

    http://www.cnblogs.com/sankye/articles/1638852.html 向作者Sankye致敬 [编写驱动之前要了解的知识] 1.       硬件特性: [Flash ...

  8. NAND FLASH

    NAND Flash 以Micron公司的MT29F2G08为例介绍NAND Flash原理和使用. 1. 概述 MT29F2G08使用一个高度复用的8-bit总线(I/O[7:0])来数据传输.地址 ...

  9. NAND Flash【转】

    转自:http://www.cnblogs.com/lifan3a/articles/4958224.html 以Micron公司的MT29F2G08为例介绍NAND Flash原理和使用. 1. 概 ...

最新文章

  1. 让你的名字显示在电脑右下角
  2. 苏宁大数据离线任务开发调度平台实践:任务调度模块架构设计
  3. 最强奥运会(互联网公司版)
  4. Hibernate- 包作用详解
  5. java ajax无权限跳转_如何在ajax权限判断后跳转?
  6. 计算机考在职研究生有必要吗,读在职研究生有必要辞掉工作吗?
  7. 【QR Code Generator】开源免费响应式QRcdr二维码生成网站源码
  8. java sqlserver 二进制_Java将图片资源以二进制的形式保存到Sqlserver数据库中
  9. 计算机帮教助教活动总结,【助教总结】_助教总结范文三篇
  10. matlab consumption,Lesage matlab 空间
  11. 新硬盘显示有储存空间但无法分区_容量更足高速无忧,奥睿科迅龙V500 NVME硬盘体验...
  12. python设置excel的格式_python 操作Excel 设置格式
  13. 深度学习笔记_术语/缩写/基本概念
  14. layui 勾选不联动父项 树形控件,treetable-lay
  15. SDRAM 控制器(六)——仲裁模块
  16. 编程序将“china”译成密码
  17. 关于滚动条内子控件控制问题
  18. Latex同时合并表格的多行多列
  19. [张雨生][张雨生典藏合集22CD][APE/整轨/7.56 GB][旋风/快传]
  20. 云服务器iss列表,【踩坑】发布ASP.NET网站到本地IIS和云服务器

热门文章

  1. php判断是否手机,PHP如何判断是否为手机端
  2. [非卷积5D中文翻译及学习笔记] 神经辐射场 NeRF: Representing Scenes as Neural Radiance Fields for View Synthesis
  3. 计算机学习常用网站总结
  4. 2021年美国大学生数学建模竞赛F题思路分析
  5. 基于php的企业公文流转审批系统-计算机毕业设计
  6. 伊利洛伊大学厄巴纳-香槟分校计算机专业,伊利诺伊大学香槟分校人工智能系排名必须得慎重来看...
  7. centos7 配置ssh
  8. DH2F200N6S-ASEMI快恢复模块200A 600V
  9. 学习编程的第32天-不忘初衷
  10. 基于HMM的文本分词