STM32自带GB2312字库显示汉字

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

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

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

编写字库显示函数

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

/**
  * @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字库显示汉字_第8张图片

你可能感兴趣的:(电子设计,STM32)