hujj 发表于 2021-1-12 09:53

【GD32E503评测】 汉字及字符串显示的实验

<p>&nbsp; &nbsp; 在对开发板TFT屏幕显示进行了初步了解之后,这将完成了显示汉字的实验,同时写了一个可以用8*16点阵显示ASCII码和16*16点阵显示汉字的字符串函数,改进了原范例只能显示单个字符的缺陷。下图为显示的效果:</p>

<p></p>

<p>&nbsp;</p>

<p>&nbsp; &nbsp; 显示控制的代码如下图,可以在字符串中任意包含汉字或ASCII字符:</p>

<p></p>

<p>&nbsp;</p>

<p>&nbsp; &nbsp; 汉字字库的结构如下图:</p>

<p></p>

<p>&nbsp; &nbsp; 字符串显示的函数如下:</p>

<pre>
<code class="language-cs">/*!
    \brief      从根据指定位置开始在液晶屏上显示字符串(8*16ASCII和16*16汉字字符集)
    \paramx: the start position of row-coordinate    X坐标
    \paramy: the start position of column-coordinate Y坐标
    \paramtext: the char                           要显示的字符串
    \paramchar_color: the color of char            字符颜色
    \paramc_format: the structure of char format   字体(字库)
                  font: CHAR_FONT_8_16 or CHAR_FONT_16_24
                  direction: CHAR_DIRECTION_HORIZONTAL or CHAR_DIRECTION_VERTICAL
                  char_color: the color of char
                  bk_color: the color of background
    \param none
    \retval   none
*/
void lcd_strue_display(uint16_t x,uint16_t y,uint8_t *str,char_format_struct c_format)
{
    uint8_t i,j,k,temp_char;
        uint16_t X,Y;
        X = x;
        Y = y;
        while(*str){
      if(((uint8_t)(*str)) &lt; 128){   //显示单字节ASCII(8*16)
            if(*str &gt; 31){
                for (i = 0; i &lt; 16; i++) { //显示16行的点阵
                  temp_char = ascii_8x16[((*str - 0x20) * 16) + i];
                  for (j = 0; j &lt; 8; j++) {
                        if (((temp_char &gt;&gt; (7 - j)) &amp; 0x01) == 0x01) {
                            lcd_point_set(X + j, Y + i, c_format.char_color);
                        } else {
                            lcd_point_set(X + j, Y + i, c_format.bk_color);
                        }
                  }
                }
            }
                        str++;       
            X += 8;       
                }
                else{                        //显示双字节汉字(16*16)
                  for(k=0; k&lt;200; k++){      //在汉字字符集中查找小于200次
                          if((GB_16ID == *(str)) &amp;&amp; (GB_16ID == *(str + 1))){
                                  for( i=0; i&lt;16; i++){//显示16行的点阵(左半边)
                        temp_char = GB_16[(k * 32) + i];
                        for (j = 0; j &lt; 8; j++) {
                            if (((temp_char &gt;&gt; (7 - j)) &amp; 0x01) == 0x01) {
                              lcd_point_set(X + j, Y + i, c_format.char_color);
                            } else {
                              lcd_point_set(X + j, Y + i, c_format.bk_color);
                            }
                        }
                                  }
                                  for( i=0; i&lt;16; i++){//显示16行的点阵(右半边)
                        temp_char = GB_16[(k * 32) + i + 16];
                        for (j = 0; j &lt; 8; j++) {
                            if (((temp_char &gt;&gt; (7 - j)) &amp; 0x01) == 0x01) {
                              lcd_point_set(X + j + 8, Y + i, c_format.char_color);
                            } else {
                              lcd_point_set(X + j + 8, Y + i, c_format.bk_color);
                            }
                        }
                                  }
                                }
                        }
                        str += 2;
                        X += 16;
                }
        }
}
</code></pre>

<p>&nbsp;</p>

<p>&nbsp; &nbsp; 在这个函数中暂时还没有考虑改变字体方向的问题,稍后准备增加这项功能,以便与范例代码衔接。</p>

<p>&nbsp;</p>

w494143467 发表于 2021-1-12 22:19

<p>不错不错!有木有字体点阵的设置方式,行扫描列扫描啥的,可以贴出图片来。</p>

hujj 发表于 2021-1-13 09:34

w494143467 发表于 2021-1-12 22:19
不错不错!有木有字体点阵的设置方式,行扫描列扫描啥的,可以贴出图片来。

<p>第二幅图片就是:横向取模左高位,数据排列从上到下从左到右。</p>

w494143467 发表于 2021-1-13 13:28

hujj 发表于 2021-1-13 09:34
第二幅图片就是:横向取模左高位,数据排列从上到下从左到右。

<p>好嘞,到时候我试一下,这样就不用各种试方向了。</p>

hujj 发表于 2021-1-13 14:33

<p>&nbsp; &nbsp; 经过测试,字符串的水平方向显示也成功了,下面是显示的效果:</p>

<p>&nbsp;</p>

<p>&nbsp; &nbsp; 显示的代码如下:</p>

<p></p>

<p>&nbsp;</p>

<p>&nbsp; &nbsp; 显示的函数代码:</p>

<pre>
<code class="language-cs">/*!
    \brief      从根据指定位置开始在液晶屏上显示字符串(8*16ASCII和16*16汉字字符集)
    \paramx: the start position of row-coordinate    X坐标
    \paramy: the start position of column-coordinate Y坐标
    \paramtext: the char                           要显示的字符串
    \paramchar_color: the color of char            字符颜色
    \paramc_format: the structure of char format   字体(字库)
                  font: CHAR_FONT_8_16 or CHAR_FONT_16_24
                  direction: CHAR_DIRECTION_HORIZONTAL or CHAR_DIRECTION_VERTICAL
                  char_color: the color of char
                  bk_color: the color of background
    \param none
    \retval   none
*/
void lcd_strue_display(uint16_t x,uint16_t y,uint8_t *str,char_format_struct c_format)
{
    uint8_t i,j,k,temp_char;
        uint16_t X,Y;
        X = x;
        Y = y;
        while(*str){
      if(((uint8_t)(*str)) &lt; 128){   //显示单字节ASCII(8*16)
            if(*str &gt; 31){
                                if(CHAR_DIRECTION_HORIZONTAL == c_format.direction){//水平显示
                  for (i = 0; i &lt; 16; i++) { //显示16行的点阵
                        temp_char = ascii_8x16[((*str - 0x20) * 16) + i];
                        for (j = 0; j &lt; 8; j++) {
                            if (((temp_char &gt;&gt; (7 - j)) &amp; 0x01) == 0x01) {
                              lcd_point_set(X - i, Y + j, c_format.char_color);
                            } else {
                              lcd_point_set(X - i, Y + j, c_format.bk_color);
                            }
                        }
                  }
                                        Y += 8;
                          }else{
                                  for (i = 0; i &lt; 16; i++) { //显示16行的点阵
                        temp_char = ascii_8x16[((*str - 0x20) * 16) + i];
                        for (j = 0; j &lt; 8; j++) {
                            if (((temp_char &gt;&gt; (7 - j)) &amp; 0x01) == 0x01)
                              lcd_point_set(X + j, Y + i, c_format.char_color);
                            else
                              lcd_point_set(X + j, Y + i, c_format.bk_color);
                        }
                  }
                                  X += 8;
                                }

            }
                        str++;
                }
                else{                        //显示双字节汉字(16*16)
                  for(k=0; k&lt;200; k++){      //在汉字字符集中查找小于200次
                          if((GB_16ID == *(str)) &amp;&amp; (GB_16ID == *(str + 1))){
                                        if(CHAR_DIRECTION_HORIZONTAL == c_format.direction){//水平显示
                                for( i=0; i&lt;16; i++){//显示16行的点阵(左半边)
                            temp_char = GB_16[(k * 32) + i];
                            for (j = 0; j &lt; 8; j++) {
                              if (((temp_char &gt;&gt; (7 - j)) &amp; 0x01) == 0x01)
                                    lcd_point_set(X - i, Y + j, c_format.char_color);
                              else
                                    lcd_point_set(X - i, Y + j, c_format.bk_color);
                            }
                        }
                                    for( i=0; i&lt;16; i++){//显示16行的点阵(右半边)
                            temp_char = GB_16[(k * 32) + i + 16];
                            for (j = 0; j &lt; 8; j++) {
                              if (((temp_char &gt;&gt; (7 - j)) &amp; 0x01) == 0x01)
                                    lcd_point_set(X - i, Y + j + 8, c_format.char_color);
                              else
                                    lcd_point_set(X - i, Y + j + 8, c_format.bk_color);
                            }
                        }
                                                Y += 16;
                                  } else {
                                for( i=0; i&lt;16; i++){//显示16行的点阵(左半边)
                            temp_char = GB_16[(k * 32) + i];
                            for (j = 0; j &lt; 8; j++) {
                              if (((temp_char &gt;&gt; (7 - j)) &amp; 0x01) == 0x01)
                                    lcd_point_set(X + j, Y + i, c_format.char_color);
                              else
                                    lcd_point_set(X + j, Y + i, c_format.bk_color);
                            }
                        }
                                    for( i=0; i&lt;16; i++){//显示16行的点阵(右半边)
                            temp_char = GB_16[(k * 32) + i + 16];
                            for (j = 0; j &lt; 8; j++) {
                              if (((temp_char &gt;&gt; (7 - j)) &amp; 0x01) == 0x01)
                                    lcd_point_set(X + j + 8, Y + i, c_format.char_color);
                              else
                                    lcd_point_set(X + j + 8, Y + i, c_format.bk_color);
                            }
                        }
                                                X += 16;
                                        }
                                }
                        }
                        str += 2;
                }
        }
}

</code></pre>

<p>&nbsp;</p>

freebsder 发表于 2021-1-13 22:56

<p>谢谢分享,期待后续!</p>

caizhiwei 发表于 2021-1-14 08:18

<p>牛!昨天晚上还在研究这个,没搞出来~</p>

hujj 发表于 2021-1-14 09:33

caizhiwei 发表于 2021-1-14 08:18
牛!昨天晚上还在研究这个,没搞出来~

<p>这是参照范例照葫芦画瓢,就是水平(横向)和垂直(竖向)有点懵圈,测试了多次才成功的。</p>

caizhiwei 发表于 2021-1-15 22:04

<p>汉字或者图片取模的软件,能分享一下吗?<img height="48" src="https://bbs.eeworld.com.cn/static/editor/plugins/hkemoji/sticker/facebook/congra.gif" width="48" /></p>

hujj 发表于 2021-1-16 10:12

<p>这个软件也是从网上获得的,我已经用习惯了,感觉很好用,完全可以满足我的需要。顺便感谢一下软件的作者!</p>

<p></p>

csfc 发表于 2024-5-15 13:58

<p>大佬能发个完整的吗,对照着改入GD32F303中,运行报错了,想看看那一块的问题。</p>

hujj 发表于 2024-5-16 11:46

csfc 发表于 2024-5-15 13:58
大佬能发个完整的吗,对照着改入GD32F303中,运行报错了,想看看那一块的问题。

<p>这是当时保存的项目文件,希望能够帮助到您。</p>

<div></div>

csfc 发表于 2024-5-17 11:00

hujj 发表于 2024-5-16 11:46
这是当时保存的项目文件,希望能够帮助到您。

<p>感谢大佬,我看看</p>
页: [1]
查看完整版本: 【GD32E503评测】 汉字及字符串显示的实验