汉字自定义点阵语句
在一些特殊情况下,比如少量使用一些生僻字显示姓名,这样如果使用全部GBK汉字库会占用大量的flash内存,况且还有少量生僻字连GBK也不包含;为此我们设置了由串口传入汉字点阵字符串,然后通过语句写入flash字库的方案。
语句介绍详见:fontdot
在使用fontdot语句之前,我们需要了解以下概念:
一、flash是按4K的数据块进行擦除的
需要更改数据库,必然要对存储数据库的flash进行写入操作,而写入则必须先擦除(所谓擦除是指将存储器由0擦除成1,这个擦除是按4K字节的一个数据块整体操作的);而存储器由1写成0则可以按字节进行操作;
因此,在写入第一个汉字点阵时,必须要擦除存储器,而写入第二个汉字在同一存储区时,则不能擦除存储器;
二、需要根据汉字点阵确定4K存储边界
首先,需要了解各点阵汉字的大小以及在汉字库中的位置计算规则:
- 各点阵汉字存储大小
点阵大小 | 存储大小(字节) | 4K存储字数 |
---|---|---|
16 | 32 | 128 |
24 | 72 | 56.89 |
32 | 128 | 32 |
48 | 288 | 14.22 |
64 | 512 | 8 |
- 建议的汉字内码区域
无论是GB2312还是GBK,对于 内码AAA1~AFFE这个区间全部点阵为空,前面已经在这个区域构建图标体系,同样,自定义汉字也可以使用该区域;
具体区域:
区码 | 汉字内码 |
---|---|
AA | AAA1~AAFE |
AB | ABA1~ABFE |
AC | ACA1~ACFE |
AD | ADA1~ADFE |
AE | AEA1~AEFE |
AF | AFA1~AFFE |
- 汉字库实际存储位置计算公式
//GB2312:
addr=((q-161)*94+(w-161))*size;
//GBK:
addr=((q-129)*191+(w-64))*size;
//其中q为汉字的区码,也就是汉字内码高8位
//其中w为汉字的位码,也就是汉字内码低8位
//size为汉字点阵存储大小,详见上表
计算示例:
使用16点阵GBK2312汉字的AA区域,计算数据块:
- 计算AAA1这个汉字的实际存储位置
addr=((0xaa-161)*94+(0xa1-161))*32
=27072
//而27072/4096=6.609
//因此最佳存储位置应该是汉字库的第7个数据块
- 计算第7个数据块对应的汉字内码
//起始地址:7*4096=28672;
//结束地址:28672+4095=32767;
//28672对应的汉字内码:
//设 x=q-161; y=w-161;
//按汉字内码规则要求 x<94; y<94;
x*94+y=896; //28672/32=896
//因此:
x=896/94=9.531914894 取整为9
y=896%94=50
则:q=161+9=170=0xAA;
w=161+50=211=0xD3
//同理:32768对应的汉字为:
32768/32=1024
1024/94=10...(余)84
因此:q=161+10=171=0xAB;
w=161+84=245=0xF5
//因此得出结论:第7个数据块对应汉字为:
AAD3 ~ ABF4
//由于AB跨区,因此实际区域:
AAD3~AAFE ABA1~ABF5
//因此,在写AAD3的时候,需要擦除存储区,而后面的不需要
总结:
GB2312字库各点阵使用AAA1 附近数据块对应汉字内码:
点阵 | 块编号 | 起始地址 | 结束地址 | 内码范围 |
---|---|---|---|---|
16 | 7 | 28672 | 32767 | AAD3~AAFE ABA1~ABF5 |
24 | 15 | 61440 | 65535 | AAA9~AAE1 |
32 | 27 | 110592 | 114687 | AAB3~AAD3 |
48 | 60 | 245760 | 249855 | AAA9~AAB6 |
64 | 106 | 434176 | 438271 | AAA3~AAAB |
汉字点阵算法
汉字点阵,是按行计算的,以上图的32X32点阵汉字为例,一行4个字节,对应点阵关系如下:
1字节[bit7]...[bit0] 2字节[bit7]...[bit0] ......4字节[bit7]...[bit0]
因此,按照上图点阵逐行转换:
第一行和第二行无显示点,都是:
[1]:0x00 0x00 0x00 0x00
[2]:0x00 0x00 0x00 0x00
第三行有两个点:
[3]:0x08 0x00 0x00 0x20
第四行为:
[4]:0x0F 0xFF 0xFF 0xF8
......
因此最后全部点数据为:
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x08,0x00,0x00,0x20,
0x0F,0xFF,0xFF,0xF8,
0x0C,0x00,0x00,0x30,
0x0C,0x00,0x00,0x30,
0x0C,0x00,0x03,0x30,
0x0C,0xFF,0xFF,0xB0,
0x0C,0x01,0x80,0x30,
0x0C,0x01,0x80,0x30,
0x0C,0x01,0x80,0x30,
0x0C,0x01,0x80,0x30,
0x0C,0x01,0x80,0x30,
0x0C,0x01,0x84,0x30,
0x0C,0x7F,0xFE,0x30,
0x0C,0x01,0x80,0x30,
0x0C,0x01,0xA0,0x30,
0x0C,0x01,0x98,0x30,
0x0C,0x01,0x8C,0x30,
0x0C,0x01,0x8E,0x30,
0x0C,0x01,0x84,0x30,
0x0C,0x01,0x84,0x30,
0x0C,0x01,0x83,0x30,
0x0D,0xFF,0xFF,0xB0,
0x0C,0x00,0x00,0x30,
0x0C,0x00,0x00,0x30,
0x0C,0x00,0x00,0x30,
0x0F,0xFF,0xFF,0xF0,
0x0C,0x00,0x00,0x30,
0x0C,0x00,0x00,0x30,
0x08,0x00,0x00,0x00,
0x00,0x00,0x00,0x00