首页 > 其他分享 >STM32自带GB2312字库显示汉字

STM32自带GB2312字库显示汉字

时间:2023-01-11 12:35:27浏览次数:46  
标签:0x8 0x20 0x0 GB2312 0x10 STM32 0x41 字库 0x4


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

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

  在​​上一篇博客​​中,最后留了一个想法,让单片机自带字库。现在就来实现这个想法。

我把用到的编译过的字符放在​​这里​​   我们借助J-Flash软件把bin文件放在单片机flash中的指定位置。

  首先要新建工程,然后根据自己的板子选择型号

STM32自带GB2312字库显示汉字_中文


STM32自带GB2312字库显示汉字_STM32_02


  然后打开数据文件,找到刚刚下载的bin文件

STM32自带GB2312字库显示汉字_字库_03


STM32自带GB2312字库显示汉字_字库_04


  根据自己单片机的flash大小输入地址,注意这个地址要与代码中的“基地址”一致

STM32自带GB2312字库显示汉字_中文_05


  设置好以后按下快捷键F7

STM32自带GB2312字库显示汉字_中文_06

STM32自带GB2312字库显示汉字_字库_07


  成功烧录以后,代码不可以在使用此区域。——一般情况下,你的工程代码也不会大到可以覆盖这个区域。

编写字库显示函数

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

/**
* @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自带GB2312字库显示汉字_单片机_08


标签:0x8,0x20,0x0,GB2312,0x10,STM32,0x41,字库,0x4
From: https://blog.51cto.com/u_12001544/6002122

相关文章

  • STM32HAL库定时器中断关闭的方法
    本文可以用于解决这个问题:定时器中断上电后莫名其妙开启,或者首先触发一次。STM32HAL库在定时器初始化并开启以后,也是会默认开启中断。如不需要默认就开启中断可以用一下代......
  • HAL库教程2:使用STM32CubeMX新建一个工程
    安装STM32CubeMX  安装STM32CubeMX之前,电脑中要有java运行时环境(JRE),否则会报错:  双击JavaSetup8u201.exe即可安装JRE。在安装过程中,需要在线下载一些资源,所以应当保持......
  • HAL库教程1:STM32Cube的介绍
      使用STM32HAL库已经有了一段时间,觉得相比于标准库,好用了不少。加上STM32CubeMX图形化配置工具的加持,个人认为可以极大提升开发效率。其实关于HAL库的教程已经很多了,关于......
  • HAL库教程7:STM32的时钟系统
      STM32的时钟系统比较复杂,不像51单片机,可能只有一个时钟。原因:1、外设多,不同的外设有不同的时钟要求;2、功耗原因,速度越快,功耗越大,抗电磁干扰能力越弱。此处以STM32F405......
  • 进阶阶段——STM32学习笔记(一)
    进阶阶段——STM32学习笔记(1)前言由于套件放在学校,待等假期结束后才能做实验0STM32简介注意:STM32的标准工作电压为3.3V,若用5V供电,需要用(电平转换电路)稳压芯片降压至3.3......
  • STM32 - 中断
    1.中断定义(Event)中断(Interrupt):指当出现需要时,CPU暂时暂停当前程序的执行,转而执行处理新情况的程序的处理过程。即在程序运行过程中,系统出现了一个必须由CPU立即处理......
  • Basic Concepts of STM32 (1)
           ......
  • STM32 - USART串口通信
    本文以正点原子-探索者开发板-STM32F407ZGT6为硬件平台进行代码讲解1.简介通用同步异步收发器(USART)能够灵活地与外部设备进行全双工数据交换,满足外部设备对工业标......
  • rt-thread 中pwm组件不起作用的问题 stm32L431
    board.h中打开如下定义,并新增要使用的通道#defineBSP_USING_PWM1/*#defineBSP_USING_PWM2*//*#defineBSP_USING_PWM3*/#defineBSP_USING_PWM1_CH1drv_pwm.c中......
  • STM32 - 时钟系统详解
    0.前言0.1什么是时钟时钟是由电路产生的具有周期性的脉冲信号,相当于单片机的心脏,给单片机提桶一个统一的信号要想使用单片机的外设必须开启相应的时钟,0.2时钟对单......