一、整体思路

最近在搞LCD显示汉字、特殊图形的问题。以前玩1602的时候自己做过字模,就是通过1602自带的用户DIY的一个存储点阵区CGROM,把做好的字模转化成点阵的数据存储在CGROM中,最后把汉字显示在1602上面。但是当时是用51做的,而且字模地址是固定存储在1602中的,我们不用去管。在stm32+TFTLCD显示汉字这个实验上面,我的思路还是这个样子,就是做好字模,然后根据地址找到对应汉字的点阵数据。那么问题来了,在1602中每个字模都有自己的显示编码,那么在stm32中,汉字有自己的显示编码吗?

二、数组和字符串的关系

在说汉字的显示编码之前,我想先讲一下数组和字符串的关系。字符串我们可以把它当成一种特殊的数组,编译器识别到字符串时,会自动把它的地址分配到stm32的Flash里面,这就意味着字符串本身就是一个常量。字符串的定义是用双引号括起来的一段字符数据,这段数据最后会自动加上一个空字符为结尾(‘\0’)。我们这里直接上程序:

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "string.h"char arrBuf_1[3] = {'f','a','t'};
char arrBuf_2[4] = {'f','a','t','\0'};
char strBuf_1[]  = "fat";int main(void)
{ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2delay_init(168);  //初始化延时函数uart_init(115200);//初始化串口波特率为115200if(!strcmp(arrBuf_1,strBuf_1)){printf("arrBuf_1 与 strBuf_1 相等\r\n");}else if(!strcmp(arrBuf_2,strBuf_1)){printf("arrBuf_2 与 strBuf_1 相等\r\n");}else{printf("数组与字符串均不相等\r\n");}printf("arrBuf_1的地址为:0x%x\r\n",arrBuf_1);printf("arrBuf_2的地址为:0x%x\r\n",arrBuf_2);printf("strBuf_1的地址为:0x%x\r\n",strBuf_1);printf("arrBuf_1中'f'字符常量的地址为:0x%x\r\n",*arrBuf_1);printf("arrBuf_2中'f'字符常量的地址为:0x%x\r\n",*arrBuf_2);printf("strBuf_1中'f'字符常量的地址为:0x%x\r\n",*strBuf_1);while(1);return 0;
}


一个数组的数组名,就是指向该数组第一位成员的地址的指针,所以我们打印数组名,就是打印该数组第一个成员的地址,解除该指针则打印的是该地址里保存的值,对应程序而言就是’f’的ASCII码值,以16进制形式体现。

通过简单的比较我们可以看到,字符串就是把每个字符转化成单引号字符常量,存储在对应的数组成员中,且最后一位自动加入’\0’空字符表示结尾。上面三个数组的地址是不同的,但是每个数组中存储的单引号字符常量的值却是相同的,这就说明单引号字符常量在keil编译器下,被自动识别为对应的ASCII码值。ASCII码值我们大可以理解为每个字符的显示编码。

三、GBK码

keil这个编译器会自动把有ASCII码值的字符常量识别为对应的ASCII码值,没有对应ASCII码值的常量比如汉字日语等,我们也有一套特殊的编码来表示,这个编码就是GBK码。

GBK码有16位,两个字节组成。

高字节的范围为:0x81~0xFE,每一位都称为一个区,总共有126个区。
低字节的范围为:0x40~0x7E , 0x80~0xFE,低字节总共由两部分构成,每一位都称为一个段,总共有190个段。

GBK码有126个区,190个段,每一个区的每一个段都可以表示一个汉字,那么GBK码总共可以表示126 * 190 = 23940 个汉字。足以满足我们大多数场景下的使用。在keil环境下,编译器自动的将汉字识别为对应的GBK码。

但是GBK码只是一个显示编码,每个显示编码对应的字模还是要由我们来做,做好以后我们把存储汉字字符的字模(点阵)的数组称为GBK库(这个有很多软件可以帮我们生成)。但是要从这个库里找到对应的汉字,就需要知道每个汉字在这个库里的偏移量,通过每个汉字的GBK码,我们可以算出来对应的偏移量:
当GBKL < 0x7F时,HP = ((GBKH - 0x81)*190+GBKL-0x40) * (size * 2)
当GBKL > 0x7F时,HP = ((GBKH - 0x81)*190+GBKL-0x41) * (size * 2)
GBKH 为高字节,GBKL 为低字节,低字节的两部分中间有个断层0x7F,所以要分情况判断其偏移。HP即为求出的汉字显示编码在GBK库中的偏移量,size为显示汉字的大小。

我们这里举个例子,以字符串“你好啊”为例,分析每个汉字的GBK码:

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "string.h"char arrBuf_1[3] = {'f','a','t'};
char arrBuf_2[4] = {'f','a','t','\0'};
char strBuf_1[]  = "fat";
const char* strBuf_2 = "你好啊";int main(void)
{ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2delay_init(168);  //初始化延时函数uart_init(115200);//初始化串口波特率为115200if(!strcmp(arrBuf_1,strBuf_1)){printf("arrBuf_1 与 strBuf_1 相等\r\n");}else if(!strcmp(arrBuf_2,strBuf_1)){printf("arrBuf_2 与 strBuf_1 相等\r\n");}else{printf("数组与字符串均不相等\r\n");}printf("arrBuf_1的地址为:0x%x\r\n",arrBuf_1);printf("arrBuf_2的地址为:0x%x\r\n",arrBuf_2);printf("strBuf_1的地址为:0x%x\r\n",strBuf_1);printf("arrBuf_1中'f'字符常量的地址为:0x%x\r\n",*arrBuf_1);printf("arrBuf_2中'f'字符常量的地址为:0x%x\r\n",*arrBuf_2);printf("strBuf_1中'f'字符常量的地址为:0x%x\r\n",*strBuf_1);printf("strBuf_2汉字常量‘你’的GBK码高位码为:0x%x\r\n",*strBuf_2);printf("strBuf_2汉字常量‘你’的GBK码低位码为:0x%x\r\n",*(strBuf_2+1));printf("strBuf_2汉字常量‘好’的GBK码高位码为:0x%x\r\n",*(strBuf_2+2));printf("strBuf_2汉字常量‘好’的GBK码低位码为:0x%x\r\n",*(strBuf_2+3));printf("strBuf_2汉字常量‘啊’的GBK码高位码为:0x%x\r\n",*(strBuf_2+4));printf("strBuf_2汉字常量‘啊’的GBK码低位码为:0x%x\r\n",*(strBuf_2+5));while(1);return 0;
}


strBuf_2为指针名(数组名),指向第一个成员的地址,解除运算以后就是第一个成员的值,对应汉字即为GBK码,因为GBK码为16位,所以我们连续打印6个字节的数据,每两个组合即为对应汉字的GBK码值。然后我们根据得到的GBK码值,带入上面的公式,算出来每个汉字在GBK库里的偏移量,根据每个汉字在GBK库中的偏移量,我们就可以定位到具体的汉字。

以上就是汉字显示的基本原理了,下一篇文章给大家介绍一下显示汉字的步骤,在EEPROM上建立自己的字库,以及如何在LCD上显示特殊图形(自己DIY)。

stm32+lcd显示汉字之GBK编码相关推荐

  1. 嵌入式汉字显示原理及GBK编码详解

    嵌入式汉字显示原理及GBK编码详解 ~~~~~~~~        关于各个编码的介绍和转换可以看我的另一篇博客:[C语言实现]十六进制面值转字符串.字符面值转十六进制.UNICODE与GBK互转,U ...

  2. 北邮实验:ARM实验板移植Linux操作系统,LCD显示汉字

    ARM实验板移植Linux操作系统,LCD显示汉字 一. 实验目的 1. 熟悉点阵字库的使用2. 熟悉Linux操作系统的使用3. 熟悉ARM嵌入式系统开发的过程 二. 实验内容 1. pc端编写用* ...

  3. zigbee板子:lcd显示汉字

    main函数 #include <ioCC2530.h> #include "LCD.h"void main() {//unsigned char i=0; LCD_I ...

  4. STM32: LCD显示

    一.TFTLCD概述 1.1 TFTLCD TFT-LCD 即薄膜晶体管液晶显示器.其英文全称为:Thin Film Transistor-Liquid Crystal  Display,该模块有如下 ...

  5. ARM实验板移植Linux操作系统,LCD显示汉字(名字)

    一.实验目的 1.熟悉点阵字库的使用 2.熟悉Linux操作系统的使用 3.熟悉ARM嵌入式系统开发的过程 二.实验内容 1.pc端编写用×和空格显示自己名字的c程序 2.安装交叉编译工具,修改程序, ...

  6. java 汉字转为GBK编码,再由GBK编码转为汉字

    public static void encode() {String string = "123abc张三";try {System.out.println("stri ...

  7. LCD / OLED显示汉字,取模软件PCtoLCD2002完美版

    一.LCD显示汉字结果展示: 二.取模软件的使用(PCtoLCD2002完美版) 1. 打开软件,模式为(字符模式) 点击菜单栏[选项],打开字模选项 勾选[阴码点阵].逐列式取模.顺向(高位在前,低 ...

  8. 汉字GBK编码-------也叫区位码------本人备注

    原文地址::http://www.qqxiuzi.cn/zh/hanzi-gbk-bianma.php 相关文章 1.gbk+unicode+汉字编码对照表----https://wenku.baid ...

  9. python用gbk编码自己的名字_基于python的汉字转GBK码

    说明: 今天想用python调用百度框计算的搜过结果,看到了URL里面的汉字用GBK编码,虽然可以直接在URL里面加入中文,之前也做过一个简体字转GBK码的python函数,但还是略嫌麻烦,今天改了一 ...

  10. gbk编码python_基于python的汉字转GBK码

    说明: 今天想用python调用百度框计算的搜过结果,看到了URL里面的汉字用GBK编码,虽然可以直接在URL里面加入中文,之前也做过一个简体字转GBK码的python函数,但还是略嫌麻烦,今天改了一 ...

最新文章

  1. python http接口_python处理http接口请求
  2. 【ACM】DFS 全排列 回溯
  3. 【BZOJ】3053: The Closest M Points(kdtree)
  4. HTTP 协议中的 cookie
  5. echarts仪表盘option_echarts仪表盘完整代码
  6. 数字图像处理之空间域图像增强
  7. mysql5.58_mysql5.58编译安装手记
  8. bochs上网镜像怎么上网_【干货科普】上网慢!经常掉线!怎么办?
  9. 基于应用日志的扫描器检测实践
  10. java 课后习题 冒泡排序的运用
  11. 网络安装centos5.4
  12. 各类型土地利用图例_给排水系统各部件及图纸你还有多少不了解?
  13. python js 性能_Python Json使用,Json库性能测试
  14. keras+yolo实现旗帜识别
  15. Java Mail 相关资料
  16. 12306网站抢票机制攻与防
  17. editplus配置python_Editplus配置Python的开发环境
  18. 修改php fpm监听端口,怎样修正php fpm监听端口_后端开发
  19. 齐桓公称霸天下的用人之道
  20. 酒香不怕巷子深,有心人才找得到的京都茶寮

热门文章

  1. eds能谱图分析实例_SPC控制图公式_均值极差SPC控制图公式应用实例分析
  2. 读《亿级流量网站架构核心技术》
  3. java 极光_极光IM系列之java后台集成
  4. eclipse导入javaWeb项目
  5. 第三次PR培训(添加常用效果和转场)
  6. Hadoop 快速入门
  7. 分布式系统架构网络之IDC机房
  8. 智能优化算法:萤火虫算法-附代码
  9. 计算机丢失gdiplus.dll怎么办,win7系统丢失gdiplus.dll报错的解决办法
  10. 渗透测试工具之——Netsparker概述