切换到宽版
  • 28180阅读
  • 53回复

[ARM]分享一款GB18030汉字点阵库 [复制链接]

上一主题 下一主题
离线2545889167
 

发帖
13268
M币
20754
专家
302
粉丝
4860
只看楼主 倒序阅读 我要置顶 楼主  发表于: 2017-06-11
感谢坛友 @shi988  
在前两天的撸一堆板子上面,发现一款汉字字库芯片
高通gotop的gt32l24m01

一看手册发现这玩意儿支持的字库相当多
汉字支持12*12 16*16 241*24三种大小的GB18030标准的27484个汉字和1038个汉字标点字符
然后呢一大堆各种大小样式的ascii字符
再仔细一读手册发现这玩意儿操作指令居然和25系列的flash一模一样
直接上编程器,发现是个4MB的,直接就给他整片拷贝下来了。
其中0-0x7ffff为空白区域512KB,用户可以自行使用。
那么就是说后面3.5MB的内容就是字库内容了
支持的字库列表和地址


手册上面的样张 一部分截图



拷贝下来的bin有4MB。找个一元pos机上的刚好大小4m的flash烧录进去
烧录器用的:手把手教你用一元pos机打造高速25系列flash烧录器(路由党福利)|http://bbs.mydigit.cn/read.php?tid=1717176


stm32上面找个现成的汉字显示程序,简单一改就可以用了
效果如下:


字符地址计算程序(部分)
  1. //code 字符指针开始
  2. //从字库中查找出字模
  3. //code 字符串的开始地址,GBK码
  4. //mat  数据存放地址 (size/8+((size%8)?1:0))*(size) bytes大小    
  5. //size:字体大小
  6. void Get_HzMat(unsigned char *code,unsigned char *mat,u8 size)
  7. {            
  8.     unsigned char c1,c2,c3,c4;//汉字内码
  9.     unsigned char i;                      
  10.     unsigned long foffset;
  11.     unsigned long h=0;
  12.     u8 csize=(size/8+((size%8)?1:0))*(size);//得到字体一个字符对应点阵集所占的字节数    
  13.     c1=*code;
  14.     c2=*(++code);
  15.     c3=*(++code);
  16.     c4=*(++code);
  17.     if(c2==0x7f)
  18.     {              
  19.         for(i=0;i<csize;i++)*mat++=0x00;//填充满格
  20.         return; //结束访问
  21.     }
  22.     if(size==12)
  23.     {    
  24.             if(c1 >= 0xA1 && c1 <= 0xa9 && c2 >= 0xa1) //Section 1
  25.                 h = (c1 - 0xA1) * 94 + (c2 - 0xA1);
  26.             else if(c1 >= 0xa8 && c1 <= 0xa9 && c2 < 0xa1) //Section 5
  27.             {
  28.                 if(c2 > 0x7f)
  29.                     c2--;
  30.                 h = (c1 - 0xa8) * 96 + (c2 - 0x40) + 846;
  31.             }
  32.             if(c1 >= 0xb0 && c1 <= 0xf7 && c2 >= 0xa1) //Section 2
  33.                 h = (c1 - 0xB0) * 94 + (c2 - 0xA1) + 1038;
  34.             else if(c1 < 0xa1 && c1 >= 0x81 && c2 >= 0x40 ) //Section 3
  35.             {
  36.                 if(c2 > 0x7f)
  37.                     c2--;
  38.                     h=(c1-0x81)*190 + (c2-0x40) + 1038 +6768;
  39.             }
  40.             else if(c1>=0xaa && c2<0xa1) //Section 4
  41.             {
  42.             if(c2>0x7f)
  43.             c2--;
  44.             h=(c1-0xaa)*96 + (c2-0x40) + 1038 +12848;
  45.             }
  46.             foffset=h*24;
  47.             SPI_Flash_Read(mat,foffset+0x093D0E,24);
  48.     }
  49.     
  50.     else    if(size==16)
  51.     {    
  52.                 if(c1 <= 0xA1 && c1 >= 0xA0 && c2 >= 0xa1) //Section 1 标点
  53.                     h = (c1 - 0xA1) * 94 + (c2 - 0xA1);
  54.                 else if(c1 >= 0xa8 && c1 <= 0xa9 && c2 < 0xa1) //Section 5
  55.                 {
  56.                     if(c2 > 0x7f)
  57.                         c2--;
  58.                     h = (c1 - 0xa8) * 96 + (c2 - 0x40) + 846;
  59.                 }
  60.                 if(c1 >= 0xb0 && c1 <= 0xf7 && c2 >= 0xa1) //Section 2
  61.                     h = (c1 - 0xB0) * 94 + (c2 - 0xA1) + 1038;
  62.                 else if(c1 < 0xa1 && c1 >= 0x81 && c2 >= 0x40 ) //Section 3
  63.                 {
  64.                     if(c2 > 0x7f)
  65.                         c2--;
  66.                     h = (c1 - 0x81) * 190 + (c2 - 0x40) + 1038 + 6768;
  67.                 }
  68.                 else if(c1 >= 0xaa && c2 < 0xa1) //Section 4
  69.                 {
  70.                     if(c2 > 0x7f)
  71.                         c2--;
  72.                     h = (c1 - 0xaa) * 96 + (c2 - 0x40) + 1038 + 12848;
  73.                 }
  74.                 else if(c1 == 0x81 && c2 >= 0x39) //四字节区 1
  75.                 {
  76.                     h = 1038 + 21008 + (c3 - 0xEE) * 10 + c4 - 0x39;
  77.                 }
  78.                 else if(c1 == 0x82) //四字节区 2
  79.                 {
  80.                     h = 1038 + 21008 + 161 + (c2 - 0x30) * 1260 + (c3 - 0x81) * 10 + c4 - 0x30;
  81.                 }
  82.             foffset=h*32;
  83.             SPI_Flash_Read(mat,foffset+0x114FDE,32);
  84.     }
  85.     if(size==24)
  86.     {    
  87.                 if(c1 >= 0xA1 && c1 <= 0xAB && c2 >= 0xa1) //Section 1
  88.                     h = (c1 - 0xA1) * 94 + (c2 - 0xA1);
  89.                 else if(c1 >= 0xa8 && c1 <= 0xa9 && c2 < 0xa1) //Section 5
  90.                 {
  91.                     if(c2 > 0x7f)
  92.                         c2--;
  93.                     h = (c1 - 0xa8) * 96 + (c2 - 0x40) + 846;
  94.                 }
  95.                 if(c1 >= 0xb0 && c1 <= 0xf7 && c2 >= 0xa1) //Section 2
  96.                     h = (c1 - 0xB0) * 94 + (c2 - 0xA1) + 1038;
  97.                 else if(c1 < 0xa1 && c1 >= 0x81 && c2 >= 0x40) //Section 3
  98.                 {
  99.                     if(c2 > 0x7f)
  100.                         c2--;
  101.                     h = (c1 - 0x81) * 190 + (c2 - 0x40) + 1038 + 6768;
  102.                 }
  103.                 else if(c1 >= 0xaa && c2 < 0xa1) //Section 4
  104.                 {
  105.                     if(c2 > 0x7f)
  106.                         c2--;
  107.                     h = (c1 - 0xaa) * 96 + (c2 - 0x40) + 1038 + 12848;
  108.                 }
  109.                 else if(c1 == 0x81 && c2 >= 0x39) //四字节区  1
  110.                 {
  111.                     h = 1038 + 21008 + (c3 - 0xEE) * 10 + c4 - 0x39;
  112.                 }
  113.                 else if(c1 == 0x82) //四字节区  2
  114.                 {
  115.                     h = 1038 + 21008 + 161 + (c2 - 0x30) * 1260 + (c3 - 0x81) * 10 + c4 - 0x30;
  116.                 }
  117.                 foffset=h*72;
  118.                 SPI_Flash_Read(mat,foffset+0x1F43DE,72);
  119.     }                                                                  
  120. }  
  121. //显示一个指定大小的汉字
  122. //x,y :汉字的坐标
  123. //font:汉字GBK码
  124. //size:字体大小
  125. //mode:0,正常显示,1,叠加显示      
  126. void Show_Font(u16 x,u16 y,u8 *font,u8 size,u8 mode)
  127. {
  128.     u8 temp,t,t1;
  129.     u16 x0=x;
  130.     u8 dzk[72];  
  131.     u8 csize=(size/8+((size%8)?1:0))*(size);//得到字体一个字符对应点阵集所占的字节数    
  132.     if(size!=12&&size!=16&&size!=24)return;    //不支持的size
  133.     Get_HzMat(font,dzk,size);    //得到相应大小的点阵数据
  134.     for(t=0;t<csize;t++)
  135.     {                                                      
  136.         temp=dzk[t];            //得到点阵数据                          
  137.         for(t1=0;t1<8;t1++)
  138.         {
  139.             if(temp&0x80)LCD_Fast_DrawPoint(x,y,POINT_COLOR);
  140.             else if(mode==0)LCD_Fast_DrawPoint(x,y,BACK_COLOR);
  141.             temp<<=1;
  142.             x++;
  143.             if((x-x0)==size)
  144.             {
  145.                 x=x0;
  146.                 y++;
  147.                 break;
  148.             }
  149.         }      
  150.     }  
  151. }
  152. //在指定位置显示一个字符 从字库中取
  153. //x,y:起始坐标
  154. //num:要显示的字符:" "--->"~"
  155. //size:字体大小 12/16/24
  156. //mode:叠加方式(1)还是非叠加方式(0)
  157. void LCD_ShowChar_ZK(u16 x,u16 y,u8 num,u8 size,u8 mode)
  158. {                                
  159.     u8 temp,t1,t;
  160.     u16 x0=x;
  161.     u8 cache[48];
  162.     u8 csize=(size/8+((size%8)?1:0))*(size/2);        //得到字体一个字符对应点阵集所占的字节数    24号字最大用48
  163.      num=num-0x20;//得到偏移后的值(ASCII字库是从空格开始取模,所以-' '就是对应字符的字库)
  164.     
  165.         if(size==12)SPI_Flash_Read(cache,num*12+0x080900,12);         //调用1206字体
  166.         else if(size==16)SPI_Flash_Read(cache,num*16+0x080D80,16);    //调用1608字体
  167.         else if(size==24){SPI_Flash_Read(cache,num*48+0x081B80,48);csize=48;}    //调用2412字体
  168.         else return;                                //没有的字库    
  169.     
  170.     for(t=0;t<csize;t++)
  171.     {  
  172.         temp=cache[t];
  173.         for(t1=0;t1<8;t1++)
  174.         {                
  175.             if(temp&0x80)LCD_Fast_DrawPoint(x,y,POINT_COLOR);
  176.             else if(mode==0)LCD_Fast_DrawPoint(x,y,BACK_COLOR);
  177.             temp<<=1;
  178.             x++;
  179.             //if(x>=lcddev.width)return;    //超区域了            
  180.             if((x-x0)==size/2)
  181.             {
  182.                 x=x0;
  183.                 y++;
  184.                 //if(y>=lcddev.height)return;        //超区域了
  185.                 break;
  186.             }
  187.         }      
  188.     }                            
  189. }  
  190. //在指定位置开始显示一个字符串        
  191. //支持自动换行
  192. //(x,y):起始坐标
  193. //width,height:区域
  194. //str  :字符串
  195. //size :字体大小
  196. //mode:0,非叠加方式;1,叠加方式                      
  197. void Show_Str(u16 x,u16 y,u16 width,u16 height,u8*str,u8 size,u8 mode)
  198. {                    
  199.     u16 x0=x;
  200.     u16 y0=y;                                    
  201.     u8 bHz=0;     //字符或者中文                                                      
  202.     while(*str!=0)//数据未结束
  203.     {
  204.         if(!bHz)
  205.         {
  206.             if(*str>0x80)bHz=1;//中文
  207.             else              //字符
  208.             {      
  209.                 if(x>(x0+width-size/2))//换行
  210.                 {                  
  211.                     y+=size;
  212.                     x=x0;      
  213.                 }                                
  214.                 if(y>(y0+height-size))break;//越界返回      
  215.                 if(*str==13)//换行符号
  216.                 {        
  217.                     y+=size;
  218.                     x=x0;
  219.                     str++;
  220.                 }  
  221.                 else LCD_ShowChar_ZK(x,y,*str,size,mode);//有效部分写入     外部字库
  222.                         // else LCD_ShowChar(x,y,*str,size,mode);//有效部分写入  内部字库
  223.                 str++;
  224.                 x+=size/2; //字符,为全字的一半
  225.             }
  226.         }else//中文
  227.         {    
  228.                     bHz=0;//有汉字库    
  229.                     if(x>(x0+width-size))//换行
  230.                     {        
  231.                         y+=size;
  232.                         x=x0;          
  233.                     }
  234.             if(y>(y0+height-size))break;//越界返回                              
  235.             Show_Font(x,y,str,size,mode); //显示这个汉字,空心显示
  236.             str+=2;
  237.             x+=size;//下一个汉字偏移        
  238.         }                        
  239.     }  
  240. }


下载要30m
东西丢网盘了
内容包含 字库bin文件 芯片手册和完整的stm32的程序

链接:http://pan.baidu.com/s/1cKVLsM 密码:h1i1
欢迎砸m~
本文内容包含图片或附件,获取更多资讯,请 登录 后查看;或者 注册 成为会员获得更多权限
本帖提到的人: @shi988
本帖最近打赏记录:共1条打赏 ,M币+15
艰苦奋斗 M币 +15 感谢楼主的工作,最近正在学习有关内容,值得借鉴。 2018-05-31
离线2545889167

发帖
13268
M币
20754
专家
302
粉丝
4860
只看该作者 1楼 发表于: 2017-06-11
请登录后查看
本文内容包含图片或附件,获取更多资讯,请 登录 后查看;或者 注册 成为会员获得更多权限
离线shi988

发帖
556
M币
1028
专家
2
粉丝
25
只看该作者 2楼 发表于: 2017-06-11
请登录后查看
本帖最近打赏记录:共1条打赏 ,M币+30
离线terry528746

发帖
1210
M币
4794
专家
1
粉丝
23
只看该作者 3楼 发表于: 2017-06-11
本帖最近打赏记录:共1条打赏 ,M币+8
离线3ax31a

发帖
3550
M币
5531
专家
0
粉丝
18
只看该作者 4楼 发表于: 2017-06-11
请登录后查看
本帖最近打赏记录:共1条打赏 ,M币+8
离线snowman007

发帖
23038
M币
508
专家
38
粉丝
144
只看该作者 5楼 发表于: 2017-06-11
请登录后查看
本帖最近打赏记录:共1条打赏 ,M币+8

发帖
4351
M币
1559
专家
30
粉丝
138
只看该作者 6楼 发表于: 2017-06-11
请登录后查看
本帖最近打赏记录:共1条打赏 ,M币+30
离线dnnliyv

发帖
244
M币
51
专家
0
粉丝
32
只看该作者 7楼 发表于: 2017-06-11
请登录后查看
本帖最近打赏记录:共1条打赏 ,M币+8
离线eros8269

发帖
7132
M币
872
专家
84
粉丝
523
只看该作者 8楼 发表于: 2017-06-11
请登录后查看
本帖最近打赏记录:共1条打赏 ,M币+15
离线杨小伟

发帖
24750
M币
35424
专家
656
粉丝
16155
只看该作者 9楼 发表于: 2017-06-11
请登录后查看
本帖最近打赏记录:共1条打赏 ,M币+8
快速回复
限80 字节
温馨提示:欢迎交流讨论,请勿发布纯表情、纯引用等灌水帖子;以免被删除
 
上一个 下一个