硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1894|回复: 1
收起左侧

修正V7,V6裸机LCD工程显示24点阵和32点阵汉字和ASCII乱码问题

[复制链接]

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106738
QQ
发表于 2019-8-30 17:00:45 | 显示全部楼层 |阅读模式
修改如下两个函数即可,在文件bsp_tft_lcd.C文件:
  1. /*
  2. *********************************************************************************************************
  3. *        函 数 名: LCD_DispStrEx
  4. *        功能说明: 在LCD指定坐标(左上角)显示一个字符串。 增强型函数。支持左\中\右对齐,支持定长清屏。
  5. *        形    参:
  6. *                _usX : X坐标
  7. *                _usY : Y坐标
  8. *                _ptr  : 字符串指针
  9. *                _tFont : 字体结构体,包含颜色、背景色(支持透明)、字体代码、文字间距等参数。可以指定RA8875字库显示汉字
  10. *                _Width : 字符串显示区域的宽度. 0 表示不处理留白区域,此时_Align无效
  11. *                _Align :字符串在显示区域的对齐方式,
  12. *                                ALIGN_LEFT = 0,
  13. *                                ALIGN_CENTER = 1,
  14. *                                ALIGN_RIGHT = 2
  15. *        返 回 值: 无
  16. *********************************************************************************************************
  17. */
  18. void LCD_DispStrEx(uint16_t _usX, uint16_t _usY, char *_ptr, FONT_T *_tFont, uint16_t _Width,
  19.         uint8_t _Align)
  20. {
  21.         uint32_t i;
  22.         uint8_t code1;
  23.         uint8_t code2;
  24.         uint8_t buf[32 * 32 / 8];        /* 最大支持32点阵汉字 */
  25.         uint8_t width;
  26.         uint16_t m;
  27.         uint8_t font_width = 0;
  28.         uint8_t font_height = 0;
  29.         uint16_t x, y;
  30.         uint16_t offset;
  31.         uint16_t str_width;        /* 字符串实际宽度  */
  32.         
  33.         uint8_t line_bytes;
  34.         uint8_t asc_bytes = 0;
  35.         uint8_t hz_bytes = 0;

  36.         switch (_tFont->FontCode)
  37.         {
  38.                 case FC_ST_12:                /* 12点阵 */
  39.                         font_height = 12;
  40.                         font_width = 12;
  41.                         asc_bytes = 1;
  42.                         hz_bytes = 2;
  43.                         break;
  44.                
  45.                 case FC_ST_16:
  46.                         font_height = 16;
  47.                         font_width = 16;
  48.                         asc_bytes = 1;
  49.                         hz_bytes = 2;
  50.                         break;

  51.                 case FC_ST_24:
  52.                         font_height = 24;
  53.                         font_width = 24;
  54.                         asc_bytes = 2;
  55.                         hz_bytes = 3;
  56.                         break;
  57.                                                 
  58.                 case FC_ST_32:        
  59.                         font_height = 32;
  60.                         font_width = 32;
  61.                         asc_bytes = 2;
  62.                         hz_bytes = 4;
  63.                         break;                                       
  64.         }
  65.         
  66.         str_width = LCD_GetStrWidth(_ptr, _tFont);        /* 计算字符串实际宽度(RA8875内部ASCII点阵宽度为变长 */
  67.         offset = 0;
  68.         if (_Width > str_width)
  69.         {
  70.                 if (_Align == ALIGN_RIGHT)        /* 右对齐 */
  71.                 {
  72.                         offset = _Width - str_width;
  73.                 }
  74.                 else if (_Align == ALIGN_CENTER)        /* 左对齐 */
  75.                 {
  76.                         offset = (_Width - str_width) / 2;
  77.                 }
  78.                 else        /* 左对齐 ALIGN_LEFT */
  79.                 {
  80.                         ;
  81.                 }
  82.         }

  83.         /* 左侧填背景色, 中间对齐和右边对齐  */
  84.         if (offset > 0)
  85.         {
  86.                 LCD_Fill_Rect(_usX, _usY, LCD_GetFontHeight(_tFont), offset,  _tFont->BackColor);
  87.                 _usX += offset;
  88.         }
  89.         
  90.         /* 右侧填背景色 */
  91.         if (_Width > str_width)
  92.         {
  93.                 LCD_Fill_Rect(_usX + str_width, _usY, LCD_GetFontHeight(_tFont), _Width - str_width - offset,  _tFont->BackColor);
  94.         }
  95.         
  96.         /* 使用CPU内部字库. 点阵信息由CPU读取 */
  97.         {
  98.                 /* 开始循环处理字符 */
  99.                 while (*_ptr != 0)
  100.                 {
  101.                         code1 = *_ptr;        /* 读取字符串数据, 该数据可能是ascii代码,也可能汉字代码的高字节 */
  102.                         if (code1 < 0x80)
  103.                         {
  104.                                 /* 将ascii字符点阵复制到buf */
  105.                                 _LCD_ReadAsciiDot(code1, _tFont->FontCode, buf);        /* 读取ASCII字符点阵 */
  106.                                 width = font_width / 2;
  107.                                 line_bytes = asc_bytes;
  108.                         }
  109.                         else
  110.                         {
  111.                                 code2 = *++_ptr;
  112.                                 if (code2 == 0)
  113.                                 {
  114.                                         break;
  115.                                 }
  116.                                 /* 读1个汉字的点阵 */
  117.                                 _LCD_ReadHZDot(code1, code2, _tFont->FontCode, buf);
  118.                                 width = font_width;
  119.                                 line_bytes = hz_bytes;
  120.                         }
  121.         
  122.                         y = _usY;
  123.                         /* 开始刷LCD */
  124.                         for (m = 0; m < font_height; m++)        /* 字符高度 */
  125.                         {
  126.                                 x = _usX;
  127.                                 for (i = 0; i < width; i++)        /* 字符宽度 */
  128.                                 {
  129.                                         if ((buf[m * line_bytes + i / 8] & (0x80 >> (i % 8 ))) != 0x00)
  130.                                         {
  131.                                                 LCD_PutPixel(x, y, _tFont->FrontColor);        /* 设置像素颜色为文字色 */
  132.                                         }
  133.                                         else
  134.                                         {
  135.                                                 if (_tFont->BackColor != CL_MASK)        /* 透明色 */
  136.                                                 {
  137.                                                         LCD_PutPixel(x, y, _tFont->BackColor);        /* 设置像素颜色为文字背景色 */
  138.                                                 }
  139.                                         }
  140.         
  141.                                         x++;
  142.                                 }
  143.                                 y++;
  144.                         }
  145.         
  146.                         if (_tFont->Space > 0)
  147.                         {
  148.                                 /* 如果文字底色按_tFont->usBackColor,并且字间距大于点阵的宽度,那么需要在文字之间填充(暂时未实现) */
  149.                         }
  150.                         _usX += width + _tFont->Space;        /* 列地址递增 */
  151.                         _ptr++;                        /* 指向下一个字符 */
  152.                 }
  153.         }
  154. }
复制代码
  1. /*
  2. *********************************************************************************************************
  3. *        函 数 名: _LCD_ReadAsciiDot
  4. *        功能说明: 读取1个ASCII字符的点阵数据
  5. *        形    参:
  6. *                _code : ASCII字符的编码,1字节。1-128
  7. *                _fontcode :字体代码
  8. *                _pBuf : 存放读出的字符点阵数据
  9. *        返 回 值: 文字宽度
  10. *********************************************************************************************************
  11. */
  12. static void _LCD_ReadAsciiDot(uint8_t _code, uint8_t _fontcode, uint8_t *_pBuf)
  13. {
  14.         const uint8_t *pAscDot;
  15.         uint8_t font_bytes = 0;
  16.         uint16_t m;
  17.         uint16_t address;
  18.         uint8_t fAllHz = 0;        /* 1表示程序中内嵌全部的ASCII字符集 */

  19.         pAscDot = 0;
  20.         switch (_fontcode)
  21.         {
  22.                 case FC_ST_12:                /* 12点阵 */
  23.                         font_bytes = 24 / 2;
  24.                         pAscDot = g_Ascii12;        
  25.                         fAllHz = 1;
  26.                         break;
  27.                
  28.                 case FC_ST_16:
  29.                         /* 缺省是16点阵 */
  30.                         font_bytes = 32 / 2;
  31.                         pAscDot = g_Ascii16;
  32.                         fAllHz = 1;
  33.                         break;
  34.                
  35.                 case FC_ST_24:
  36.                         font_bytes = 48;
  37.                         pAscDot = g_Ascii24;
  38.                         break;
  39.                
  40.                 case FC_ST_32:
  41.                         font_bytes = 64;
  42.                         pAscDot = g_Ascii32;
  43.                         break;
  44.                
  45.                 default:
  46.                         return;
  47.         }        

  48.         if (fAllHz == 1)        /* 内嵌全部ASCII字符点阵 */
  49.         {
  50.                 /* 将CPU内部Flash中的ascii字符点阵复制到buf */
  51.                 memcpy(_pBuf, &pAscDot[_code * (font_bytes)], (font_bytes));               
  52.         }
  53.         else        /* 内嵌部分字符,字模数组首字节是ASCII码 */
  54.         {
  55.                 m = 0;
  56.                 while(1)
  57.                 {
  58.                    address = m * (font_bytes + 1);
  59.                    m++;
  60.                    if (_code == pAscDot[address + 0])
  61.                    {
  62.                           address += 1;
  63.                           memcpy(_pBuf, &pAscDot[address], font_bytes);
  64.                           break;
  65.                    }
  66.                    else if ((pAscDot[address + 0] == 0xFF) && (pAscDot[address + 1] == 0xFF))
  67.                    {
  68.                           /* 字库搜索完毕,未找到,则填充全FF */
  69.                           memset(_pBuf, 0xFF, font_bytes);
  70.                           break;
  71.                    }           
  72.            }
  73.    }
  74. }
复制代码



回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106738
QQ
 楼主| 发表于 2019-8-30 17:02:24 | 显示全部楼层
点阵字体的生成和使用方法看
V7用户手册第53章

http://www.armbbs.cn/forum.php?m ... &extra=page%3D1
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-3 08:59 , Processed in 0.171769 second(s), 34 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表