硬汉嵌入式论坛

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

[有问必答] 请问 ASCII 字符集是如何产生的?

[复制链接]

7

主题

7

回帖

7

积分

新手上路

积分
7
发表于 2014-1-13 13:57:53 | 显示全部楼层 |阅读模式
龙猫版主您好:

在开发板例程中我有看到一个 fonts_ascii16x24.h 档为 16*24 的 ASCII 字符数组 ,
请问这种字符数组是如何产生的?

如果想自己产生 16*16 或更大的 24*24 的 ASCII 字符的话要怎么做呢?

谢谢。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106882
QQ
发表于 2014-1-13 15:33:28 | 显示全部楼层
用的UCDOS的,也可以用这个软件生成
http://www.armbbs.cn/forum.php?mod=viewthread&tid=396
回复

使用道具 举报

0

主题

10

回帖

10

积分

新手上路

积分
10
发表于 2014-2-14 13:37:34 | 显示全部楼层
[s:151]    马上试试看。
南京电子爱好者。
回复

使用道具 举报

1

主题

25

回帖

28

积分

新手上路

积分
28
发表于 2015-2-28 16:13:11 | 显示全部楼层

回 eric2013 的帖子

eric2013:用的UCDOS的,也可以用这个软件生成
http://www.armbbs.cn/forum.php?mod=viewthread&tid=396 (2014-01-13 15:33)
楼主 UCDOS的字体在哪下载?
如果我想做24*24的任意字体的ASCII,怎么做呢?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106882
QQ
发表于 2015-2-28 18:57:32 | 显示全部楼层

Re:回 eric2013 的帖子

lansing1648:

楼主 UCDOS的字体在哪下载?
如果我想做24*24的任意字体的ASCII,怎么做呢?

UCDOS字体在这个帖子里面可以下载:
http://www.armbbs.cn/forum.php?m ... 604&fpage=2

1.png

ACSII字体不用制作,emwin里面自带很很多样式的。
回复

使用道具 举报

1

主题

25

回帖

28

积分

新手上路

积分
28
发表于 2015-3-2 10:17:00 | 显示全部楼层

回 eric2013 的帖子

eric2013:UCDOS字体在这个帖子里面可以下载:
http://www.armbbs.cn/forum.php?m ... 604&fpage=2

....... (2015-02-28 18:57)
楼主:您发的ASC12.ASC16怎么转化16进制的数组?字模3里面智能批量导TXT文件的数据
我想把ASC字库直接放在FLASH里面?

另外emwin里面我没找到相关的字体,请指教。
谢谢了。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106882
QQ
发表于 2015-3-2 18:49:43 | 显示全部楼层

回 lansing1648 的帖子

lansing1648:楼主:您发的ASC12.ASC16怎么转化16进制的数组?字模3里面智能批量导TXT文件的数据
我想把ASC字库直接放在FLASH里面?

另外emwin里面我没找到相关的字体,请指教。
....... (2015-03-02 10:17) 
emwin的看我的这个教程,emwin有专门的字体生成工具,教程里面都有讲:http://www.armbbs.cn/forum.php?mod=viewthread&tid=2932
回复

使用道具 举报

1

主题

25

回帖

28

积分

新手上路

积分
28
发表于 2015-3-2 21:10:13 | 显示全部楼层

回 eric2013 的帖子

eric2013:emwin的看我的这个教程,emwin有专门的字体生成工具,教程里面都有讲:http://www.armbbs.cn/forum.php?mod=viewthread&tid=2932 (2015-03-02 18:49)
没有用到emwin呢,就是普通的ASC显示。
回复

使用道具 举报

0

主题

5

回帖

5

积分

新手上路

积分
5
发表于 2021-6-26 17:20:37 | 显示全部楼层
/* ********************************************************************************************************* * *        模块名称 : TFT液晶显示器驱动模块 *        文件名称 : bsp_tft_lcd.c *        版    本 : V4.2 *        说    明 : 支持3.0, 3.5, 4.3, 5.0, 7.0寸显示模块. *                          3.0寸的支持的LCD内部驱动芯片型号有: SPFD5420A、OTM4001A、R61509V *        修改记录 : *                版本号  日期       作者    说明 *                v1.0    2011-08-21 armfly  ST固件库版本 V3.5.0版本。 *                                        a) 取消访问寄存器的结构体,直接定义 *                V2.0    2011-10-16 armfly  增加R61509V驱动,实现图标显示函数 *                V2.1    2012-07-06 armfly  增加RA8875驱动,支持4.3寸屏 *                V2.2    2012-07-13 armfly  改进LCD_DispStr函数,支持12点阵字符;修改LCD_DrawRect,解决差一个像素问题 *                V2.3    2012-08-08 armfly  将底层芯片寄存器操作相关的函数放到单独的文件,支持RA8875 *           V3.0    2013-05-20 增加图标结构; 修改        LCD_DrawIconActive  修改DispStr函数支持文本透明 *                V3.1    2013-06-12 解决LCD_DispStr()函数BUG,如果内嵌字库中汉字个数多于256,则出现死循环。 *                V3.2    2013-06-28 完善Label控件, 当显示字符串比之前短时,自动清除多余的文字 *                V3.3    2013-06-29 FSMC初始化时,配置时序,写时序和读时序分开设置。 LCD_FSMCConfig 函数。 *                V3.4    2013-07-06 增加显示32位带Alpha图标的函数 LCD_DrawIcon32 *                V3.5    2013-07-24 增加显示32位带Alpha图片的函数 LCD_DrawBmp32 *                V3.6    2013-07-30 修改 DispEdit() 支持12点阵汉字对齐 *                V3.7    2014-09-06 修改 LCD_InitHard() 同时支持 RA8875-SPI接口和8080接口 *                V3.8    2014-09-15 增加若干函数: *                                        (1) LCD_DispStrEx() 可以自动对齐自动填白的显示字符串函数 *                                        (2) LCD_GetStrWidth() 计算字符串的像素宽度 *                V3.9    2014-10-18 *                                        (1) 增加 LCD_ButtonTouchDown() LCD_ButtonTouchRelease 判断触摸坐标并重绘按钮 *                                        (2) 增加3.5寸LCD驱动 *                                        (3) 增加 LCD_SetDirection() 函数,设置显示屏方向(横屏 竖屏动态切换) *                V4.0   2015-04-04  *                                (1) 按钮、编辑框控件增加RA8875字体,内嵌字库和RA8875字库统一编码。字体代码增加  *                                    FC_RA8875_16, FC_RA8875_24,        FC_RA8875_32 *                                (2) FONT_T结构体成员FontCode的类型由 uint16_t 修改为 FONT_CODE_E枚举,便于编译器查错; *                                (3) 修改 LCD_DispStrEx(), 将读点阵的语句独立到函数:_LCD_ReadAsciiDot(), _LCD_ReadHZDot() *                                (4) LCD_DispStr() 函数简化,直接调用 LCD_DispStrEx() 实现。 *                                (5) LCD_DispStrEx() 函数支持 RA8875字体。 *                                (6) LCD_ButtonTouchDown() 增加按键提示音 *                V4.1   2015-04-18  *                                (1) 添加RA885 ASCII字体的宽度表。LCD_DispStrEx() 函数可以支持RA8875 ASCII变长宽度计算。 *                                (2) 添加 LCD_HardReset()函数,支持LCD复位由GPIO控制的产品。STM32-V5 不需要GPIO控制。 *                V4.2   2015-07-23 *                                (1) 添加函数LCD_InitButton() *                                (2) h文件中使能按键提示音 #define BUTTON_BEEP()        BEEP_KeyTone(); * *        Copyright (C), 2015-2016, 安富莱电子 www.armfly.com * ********************************************************************************************************* */  #include "bsp.h" #include "fonts.h"  /* 下面3个变量,主要用于使程序同时支持不同的屏 */ uint16_t g_LcdHeight = 240;                        /* 显示屏分辨率-高度 */ uint16_t g_LcdWidth = 400;                        /* 显示屏分辨率-宽度 */ uint8_t s_ucBright;                                        /* 背光亮度参数 */ uint8_t g_LcdDirection = 0;                                /* 显示方向.0,1,2,3 */  static void LCD_HardReset(void); static void LCD_SetPwmBackLight(uint8_t _bright);  /* ********************************************************************************************************* *        函 数 名: LCD_InitHard *        功能说明: 初始化LCD *        形    参: 无 *        返 回 值: 无 ********************************************************************************************************* */ void LCD_InitHard(void) {         LCD_HardReset();        /* 硬件复位 (STM32-V5, V6 无需),针对其他GPIO控制LCD复位的产品 */          LCDH7_InitHard();                  LCD_SetDirection(0);          LCD_ClrScr(CL_BLACK);        /* 清屏,显示全黑 */          //LCD_SetBackLight(BRIGHT_DEFAULT);         /* 打开背光,设置为缺省亮度 */ }   /* ********************************************************************************************************* *        函 数 名: LCD_SetPwmBackLight *        功能说明: 初始化控制LCD背景光的GPIO,配置为PWM模式。 *                        当关闭背光时,将CPU IO设置为浮动输入模式(推荐设置为推挽输出,并驱动到低电平);将TIM3关闭 省电 *        形    参:  _bright 亮度,0是灭,255是最亮 *        返 回 值: 无 ********************************************************************************************************* */ static void LCD_SetPwmBackLight(uint8_t _bright) {         /* 背光有CPU输出PWM控制,PA0/TIM5_CH1/TIM2_CH1 */         //bsp_SetTIMOutPWM(GPIOA, GPIO_PIN_0, TIM5, 1, 100, (_bright * 10000) /255);         //bsp_SetTIMOutPWM(GPIOA, GPIO_PIN_0, TIM5, 1, 20000, (_bright * 10000) /255);         bsp_SetTIMOutPWM(GPIOA, GPIO_PIN_8, TIM1, 1, 20000, (_bright * 10000) /255); }  /* ********************************************************************************************************* *        函 数 名: LCD_SetBackLight *        功能说明: 初始化控制LCD背景光的GPIO,配置为PWM模式。 *                        当关闭背光时,将CPU IO设置为浮动输入模式(推荐设置为推挽输出,并驱动到低电平);将TIM3关闭 省电 *        形    参: _bright 亮度,0是灭,255是最亮 *        返 回 值: 无 ********************************************************************************************************* */ void LCD_SetBackLight(uint8_t _bright) {         s_ucBright =  _bright;        /* 保存背光值 */          LCD_SetPwmBackLight(s_ucBright); }  /* ********************************************************************************************************* *        函 数 名: LCD_GetBackLight *        功能说明: 获得背光亮度参数 *        形    参: 无 *        返 回 值: 背光亮度参数 ********************************************************************************************************* */ uint8_t LCD_GetBackLight(void) {         return s_ucBright; }  /* ********************************************************************************************************* *        函 数 名: LCD_HardReset *        功能说明: 硬件复位. 针对复位口线由GPIO控制的产品。 *        形    参: 无 *        返 回 值: 无 ********************************************************************************************************* */ void LCD_HardReset(void) { #if 0                 GPIO_InitTypeDef GPIO_InitStructure;          /* 使能 GPIO时钟 */         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);                  /* 配置背光GPIO为推挽输出模式 */         GPIO_InitStructure.GPIO_Pin = GPIO_PIN_1;         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;         GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;         GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;         GPIO_Init(GPIOB, &GPIO_InitStructure);          GPIO_ResetBits(GPIOB, GPIO_PIN_1);         bsp_DelayMS(20);         GPIO_SetBits(GPIOB, GPIO_PIN_1); #endif         }  /* ********************************************************************************************************* *        函 数 名: LCD_GetChipDescribe *        功能说明: 读取LCD驱动芯片的描述符号,用于显示 *        形    参: char *_str : 描述符字符串填入此缓冲区 *        返 回 值: 无 ********************************************************************************************************* */ void LCD_GetChipDescribe(char *_str) {                 LCDH7_GetChipDescribe(_str); }  /* ********************************************************************************************************* *        函 数 名: LCD_GetHeight *        功能说明: 读取LCD分辨率之高度 *        形    参: 无 *        返 回 值: 无 ********************************************************************************************************* */ uint16_t LCD_GetHeight(void) {         return g_LcdHeight; }  /* ********************************************************************************************************* *        函 数 名: LCD_GetWidth *        功能说明: 读取LCD分辨率之宽度 *        形    参: 无 *        返 回 值: 无 ********************************************************************************************************* */ uint16_t LCD_GetWidth(void) {         return g_LcdWidth; }  /* ********************************************************************************************************* *        函 数 名: LCD_DispOn *        功能说明: 打开显示 *        形    参: 无 *        返 回 值: 无 ********************************************************************************************************* */ void LCD_DispOn(void) {         ; }  /* ********************************************************************************************************* *        函 数 名: LCD_DispOff *        功能说明: 关闭显示 *        形    参: 无 *        返 回 值: 无 ********************************************************************************************************* */ void LCD_DispOff(void) {         ; }  /* ********************************************************************************************************* *        函 数 名: LCD_ClrScr *        功能说明: 根据输入的颜色值清屏 *        形    参: _usColor : 背景色 *        返 回 值: 无 ********************************************************************************************************* */ void LCD_ClrScr(uint16_t _usColor) {         LCDH7_ClrScr(_usColor); }  /* ********************************************************************************************************* *        函 数 名: LCD_DispStr *        功能说明: 在LCD指定坐标(左上角)显示一个字符串 *        形    参: *                _usX : X坐标 *                _usY : Y坐标 *                _ptr  : 字符串指针 *                _tFont : 字体结构体,包含颜色、背景色(支持透明)、字体代码、文字间距等参数 *        返 回 值: 无 ********************************************************************************************************* */ void LCD_DispStr(uint16_t _usX, uint16_t _usY, char *_ptr, FONT_T *_tFont) {         LCD_DispStrEx(_usX, _usY, _ptr, _tFont, 0, 0); }  /* ********************************************************************************************************* *        函 数 名: LCD_GetFontWidth *        功能说明: 读取字体的宽度(像素单位) *        形    参: *                _tFont : 字体结构体,包含颜色、背景色(支持透明)、字体代码、文字间距等参数 *        返 回 值: 字体的宽度(像素单位) ********************************************************************************************************* */ uint16_t LCD_GetFontWidth(FONT_T *_tFont) {         uint16_t font_width = 16;          switch (_tFont->FontCode)         {                 case FC_ST_12:                         font_width = 12;                         break;                  case FC_ST_16:                 case FC_RA8875_16:                                                 font_width = 16;                         break;                                          case FC_RA8875_24:                                         case FC_ST_24:                         font_width = 24;                         break;                                          case FC_ST_32:                 case FC_RA8875_32:                                 font_width = 32;                         break;                                  case FC_ST_40:                         font_width = 40;                         break;                          case FC_ST_48:                         font_width = 48;                         break;                          }         return font_width; }  /* ********************************************************************************************************* *        函 数 名: LCD_GetFontHeight *        功能说明: 读取字体的高度(像素单位) *        形    参: *                _tFont : 字体结构体,包含颜色、背景色(支持透明)、字体代码、文字间距等参数 *        返 回 值: 字体的宽度(像素单位) ********************************************************************************************************* */ uint16_t LCD_GetFontHeight(FONT_T *_tFont) {         uint16_t height = 16;          switch (_tFont->FontCode)         {                 case FC_ST_12:                         height = 12;                         break;                  case FC_ST_16:                 case FC_RA8875_16:                                                 height = 16;                         break;                                          case FC_RA8875_24:                                         case FC_ST_24:                         height = 24;                         break;                                          case FC_ST_32:                 case FC_RA8875_32:                                 height = 32;                         break;                 case FC_ST_40:                         height = 40;                         break;                         case FC_ST_48:                         height = 48;                         break;                         }         return height; }  /* ********************************************************************************************************* *        函 数 名: LCD_GetStrWidth *        功能说明: 计算字符串宽度(像素单位) *        形    参: *                _ptr  : 字符串指针 *                _tFont : 字体结构体,包含颜色、背景色(支持透明)、字体代码、文字间距等参数 *        返 回 值: 无 ********************************************************************************************************* */ uint16_t LCD_GetStrWidth(char *_ptr, FONT_T *_tFont) {         char *p = _ptr;         uint16_t width = 0;         uint8_t code1, code2;         uint16_t font_width;          font_width = LCD_GetFontWidth(_tFont);          while (*p != 0)         {                 code1 = *p;        /* 读取字符串数据, 该数据可能是ascii代码,也可能汉字代码的高字节 */                 if (code1 < 0x80)        /* ASCII */                 {                         switch(_tFont->FontCode)                         {                                 case FC_RA8875_16:                                         font_width = g_RA8875_Ascii16_width[code1 - 0x20];                                         break;                                                                  case FC_RA8875_24:                                         font_width = g_RA8875_Ascii24_width[code1 - 0x20];                                         break;                                                                  case FC_RA8875_32:                                         font_width = g_RA8875_Ascii32_width[code1 - 0x20];                                         break;                                                                  case FC_ST_12:                                         font_width = 6;                                         break;                                  case FC_ST_16:                                                         font_width = 8;                                         break;                                                                          case FC_ST_24:                                                                 font_width = 12;                                         break;                                                                          case FC_ST_32:                                         font_width = 16;                                         break;                                                                                                   case FC_ST_40:                                         font_width = 20;                                         break;                                                                  case FC_ST_48:                                         font_width = 24;                                         break;                                                                                                   default:                                         font_width = 8;                                         break;                                                                 }                                          }                 else        /* 汉字 */                 {                         code2 = *++p;                         if (code2 == 0)                         {                                 break;                         }                         font_width = LCD_GetFontWidth(_tFont);                                          }                 width += font_width;                 p++;         }          return width; }  /* ********************************************************************************************************* *        函 数 名: _LCD_ReadAsciiDot *        功能说明: 读取1个ASCII字符的点阵数据 *        形    参: *                _code : ASCII字符的编码,1字节。1-128 *                _fontcode :字体代码 *                _pBuf : 存放读出的字符点阵数据 *        返 回 值: 文字宽度 ********************************************************************************************************* */ static void _LCD_ReadAsciiDot(uint8_t _code, uint8_t _fontcode, uint8_t *_pBuf) {         const uint8_t *pAscDot; //        const uint16_t *pAscDot;         uint8_t font_bytes = 0; //        uint16_t font_bytes = 0;                  uint16_t m;         uint16_t address; //        uint32_t address;         uint8_t fAllHz = 0;        /* 1表示程序中内嵌全部的ASCII字符集 */          pAscDot = 0;         switch (_fontcode)         {                 case FC_ST_12:                /* 12点阵 */                         font_bytes = 24/ 2;                         pAscDot = g_Ascii12;                         fAllHz = 1;                                         break;                  //                case FC_ST_24:                  case FC_ST_16:                         /* 缺省是16点阵 */                         font_bytes = 32/ 2;                         pAscDot = g_Ascii16;                         fAllHz = 1;                                 break;                                  case FC_ST_24: //                        font_bytes = 24*2;                         font_bytes = 24*2;                         pAscDot = g_Ascii24;                         break;                                                          case FC_ST_32:                         /* 缺省是16点阵 */                         font_bytes = 64;                         pAscDot = g_Ascii32;                         break;                                                   case FC_RA8875_16:                 case FC_RA8875_24:                 case FC_RA8875_32:                         return;                                  case FC_ST_40:                         /* 缺省是16点阵 */                         font_bytes = 40*3;//不行16*7.5/40=3                         pAscDot = g_Ascii40;                         fAllHz = 0;                                 break;                                  case FC_ST_48:                         /* 缺省是16点阵 */                         font_bytes = 48*3;//没问题                         pAscDot = g_Ascii48;                         fAllHz = 0;                                         break;                         return;         }          //        /* 将CPU内部Flash中的ascii字符点阵复制到buf */ //        memcpy(_pBuf, &pAscDot[_code * (font_bytes / 2)], (font_bytes / 2));                                  if (fAllHz == 1)        /* 内嵌全部ASCII字符点阵 */         {                 /* 将CPU内部Flash中的ascii字符点阵复制到buf */                 memcpy(_pBuf, &pAscDot[_code * (font_bytes)], (font_bytes));                        }         else        /* 内嵌部分字符,字模数组首字节是ASCII码 */         {                 m = 0;                 while(1)                 {                    address = m * (font_bytes + 1);                    m++;                    if (_code == pAscDot[address + 0])                    {                           address += 1;                           memcpy(_pBuf, &pAscDot[address], font_bytes);                           break;                    }                    else if ((pAscDot[address + 0] == 0xFF) && (pAscDot[address + 1] == 0xFF))                    {                           /* 字库搜索完毕,未找到,则填充全FF */                           memset(_pBuf, 0xFF, font_bytes);                           break;                    }                       }    } }  /* ********************************************************************************************************* *        函 数 名: _LCD_ReadHZDot *        功能说明: 读取1个汉字的点阵数据 *        形    参: *                _code1, _cod2 : 汉字内码. GB2312编码 *                _fontcode :字体代码 *                _pBuf : 存放读出的字符点阵数据 *        返 回 值: 无 ********************************************************************************************************* */ static void _LCD_ReadHZDot(uint8_t _code1, uint8_t _code2,  uint8_t _fontcode, uint8_t *_pBuf) {         #ifdef USE_SMALL_FONT        /* 使用CPU 内部Flash 小字库 */                 uint8_t *pDot; //                uint8_t font_bytes = 0;                 uint16_t font_bytes = 0;                 uint32_t address;                 uint16_t m;                  pDot = 0;        /* 仅仅用于避免告警 */                 switch (_fontcode)                 {                         case FC_ST_12:                /* 12点阵 */                                 font_bytes = 24;                                 pDot = (uint8_t *)g_Hz12;                                         break;                                                  case FC_ST_16:                                 font_bytes = 32;                                 pDot = (uint8_t *)g_Hz16;                                 break;                                  case FC_ST_24:                                 font_bytes = 72;                                 pDot = (uint8_t *)g_Hz24;                                 break;                                                                                  case FC_ST_32:                                         font_bytes = 128;                                 pDot = (uint8_t *)g_Hz32;                                 break;                                                                                                  case FC_ST_40:                                         font_bytes = 200;//25*8=5^2*8                                 pDot = (uint8_t *)g_Hz40;                                 break;                                  case FC_ST_48:                                         font_bytes =288;//36*8=6^2*8 //                                font_bytes =255;//36*8=6^2*8                                 pDot = (uint8_t *)g_Hz48;                                 break;                                                          case FC_RA8875_16:                         case FC_RA8875_24:                         case FC_RA8875_32:                                 return;                 }                          m = 0;                 while(1)                 {                         address = m * (font_bytes + 2);                         m++;                         if ((_code1 == pDot[address + 0]) && (_code2 == pDot[address + 1]))                         {                                 address += 2;                                 memcpy(_pBuf, &pDot[address], font_bytes);                                 break;                         }                         else if ((pDot[address + 0] == 0xFF) && (pDot[address + 1] == 0xFF))                         {                                 /* 字库搜索完毕,未找到,则填充全FF */                                 memset(_pBuf, 0xFF, font_bytes);                                 break;                         }                 }         #else        /* 用全字库 */                 uint8_t *pDot = 0;                 uint8_t font_bytes = 0;                                          switch (_fontcode)                 {                         case FC_ST_12:                /* 12点阵 */                                 font_bytes = 24;                                 pDot = (uint8_t *)HZK12_ADDR;                                         break;                                                  case FC_ST_16:                                 font_bytes = 32;                                 pDot = (uint8_t *)HZK16_ADDR;                                 break;                                  case FC_ST_24:                                 font_bytes = 72;                                 pDot = (uint8_t *)HZK24_ADDR;                                 break;                                                                                  case FC_ST_32:                                         font_bytes = 128;                                 pDot = (uint8_t *)HZK32_ADDR;                                 break;                                                                                                  case FC_RA8875_16:                         case FC_RA8875_24:                         case FC_RA8875_32:                                 return;                 }                                                  /* 此处需要根据字库文件存放位置进行修改 */                 if (_code1 >=0xA1 && _code1 <= 0xA9 && _code2 >=0xA1)                 {                         pDot += ((_code1 - 0xA1) * 94 + (_code2 - 0xA1)) * font_bytes;                 }                 else if (_code1 >=0xB0 && _code1 <= 0xF7 && _code2 >=0xA1)                 {                         pDot += ((_code1 - 0xB0) * 94 + (_code2 - 0xA1) + 846) * font_bytes;                 }                 memcpy(_pBuf, pDot, font_bytes);         #endif }                          /* ********************************************************************************************************* *        函 数 名: LCD_DispStrEx *        功能说明: 在LCD指定坐标(左上角)显示一个字符串。 增强型函数。支持左\中\右对齐,支持定长清屏。 *        形    参: *                _usX : X坐标 *                _usY : Y坐标 *                _ptr  : 字符串指针 *                _tFont : 字体结构体,包含颜色、背景色(支持透明)、字体代码、文字间距等参数。可以指定RA8875字库显示汉字 *                _Width : 字符串显示区域的宽度. 0 表示不处理留白区域,此时_Align无效 *                _Align :字符串在显示区域的对齐方式, *                                ALIGN_LEFT = 0, *                                ALIGN_CENTER = 1, *                                ALIGN_RIGHT = 2 *        返 回 值: 无 ********************************************************************************************************* */ void LCD_DispStrEx(uint16_t _usX, uint16_t _usY, char *_ptr, FONT_T *_tFont, uint16_t _Width,         uint8_t _Align) {         uint32_t i;         uint8_t code1;         uint8_t code2; //        uint8_t buf[64 * 64 / 8];        /* 最大支持24点阵汉字 */         uint8_t buf[64 * 64 / 1]; //        uint8_t buf[48 * 48 / 8];                  uint8_t width;         uint16_t m;         uint8_t font_width = 0;         uint8_t font_height = 0;         uint16_t x, y;         uint16_t offset;         uint16_t str_width;        /* 字符串实际宽度  */          //        uint8_t num_timers=0;//将                   uint8_t line_bytes;         uint8_t asc_bytes = 0;     uint8_t hz_bytes = 0;          switch (_tFont->FontCode)         {                 case FC_ST_12:                /* 12点阵 */                         font_height = 12;                         font_width = 12; //                        num_timers=2;                                          asc_bytes = 1;                         hz_bytes = 2;                         break;                                  case FC_ST_16:                 case FC_RA8875_16:                         font_height = 16;                         font_width = 16; //                        num_timers=2;                                          asc_bytes = 1;                         hz_bytes = 2;                         break;                  case FC_ST_24:                 case FC_RA8875_24:                         font_height = 24;                         font_width = 24; //                        num_timers=3;                                          asc_bytes = 4;                //width = font_width / 2=12;                                                                 //((line_bytes * width) / font_width)=4*12/24=2                         hz_bytes = 3;                         break;                                                                  case FC_ST_32:                         case FC_RA8875_32:                                 font_height = 32;                         font_width = 32; //                        num_timers=4;                                          asc_bytes = 2;                         hz_bytes = 4;                         break;                          case FC_ST_40:                                 font_height = 40;                         font_width = 40; //                        num_timers=5;                          asc_bytes = 6;                                         hz_bytes = 5;                         break;                          case FC_ST_48:                                 font_height = 48;                         font_width = 48; //                        num_timers=6;                         asc_bytes = 6;                         hz_bytes = 6;                         break;                         }                  str_width = LCD_GetStrWidth(_ptr, _tFont);        /* 计算字符串实际宽度(RA8875内部ASCII点阵宽度为变长 */         offset = 0;         if (_Width > str_width)         {                 if (_Align == ALIGN_RIGHT)        /* 右对齐 */                 {                         offset = _Width - str_width;                 }                 else if (_Align == ALIGN_CENTER)        /* 左对齐 */                 {                         offset = (_Width - str_width) / 2;                 }                 else        /* 左对齐 ALIGN_LEFT */                 {                         ;                 }         }          /* 左侧填背景色, 中间对齐和右边对齐  */         if (offset > 0)         {                 LCD_Fill_Rect(_usX, _usY, LCD_GetFontHeight(_tFont), offset,  _tFont->BackColor);                 _usX += offset;         }                  /* 右侧填背景色 */         if (_Width > str_width)         {                 LCD_Fill_Rect(_usX + str_width, _usY, LCD_GetFontHeight(_tFont), _Width - str_width - offset,  _tFont->BackColor);         }                  /* 使用CPU内部字库. 点阵信息由CPU读取 */         {                 /* 开始循环处理字符 */                 while (*_ptr != 0)                 {                         code1 = *_ptr;        /* 读取字符串数据, 该数据可能是ascii代码,也可能汉字代码的高字节 */                         if (code1 < 0x80)                         {                                 /* 将ascii字符点阵复制到buf */                                 //memcpy(buf, &pAscDot[code1 * (font_bytes / 2)], (font_bytes / 2));                                 _LCD_ReadAsciiDot(code1, _tFont->FontCode, buf);        /* 读取ASCII字符点阵 */                                 width = font_width / 2;                                 line_bytes = asc_bytes;                         }                         else                         {                                 code2 = *++_ptr;                                 if (code2 == 0)                                 {                                         break;                                 }                                 /* 读1个汉字的点阵 */                                 _LCD_ReadHZDot(code1, code2, _tFont->FontCode, buf);                                 width = font_width;                                 line_bytes = hz_bytes;                         }                                  y = _usY;                         /* 开始刷LCD */                         for (m = 0; m < font_height; m++)        /* 字符高度 */                         {                                 x = _usX;                                 for (i = 0; i < width; i++)        /* 字符宽度 */                                 { //                                        if ((buf[m * ((num_timers * width) / font_width) + i / 8] & (0x80 >> (i % 8 ))) != 0x00) //                                        if ((buf[m * ((2 * width) / font_width) + i / 8] & (0x80 >> (i % 8 ))) != 0x00)                                          //                                         if ((buf[m * line_bytes + i / 8] & (0x80 >> (i % 8 ))) != 0x00)                                         if ((buf[m * ((line_bytes * width) / font_width) + i / 8] & (0x80 >> (i % 8 ))) != 0x00)                                         {                                                 LCD_PutPixel(x, y, _tFont->FrontColor);        /* 设置像素颜色为文字色 */                                         }                                         else                                         {                                                 if (_tFont->BackColor != CL_MASK)        /* 透明色 */                                                 {                                                         LCD_PutPixel(x, y, _tFont->BackColor);        /* 设置像素颜色为文字背景色 */                                                 }                                         }                                                  x++;                                 }                                 y++;                         }                                  if (_tFont->Space > 0)                         {                                 /* 如果文字底色按_tFont->usBackColor,并且字间距大于点阵的宽度,那么需要在文字之间填充(暂时未实现) */                         }                         _usX += width + _tFont->Space;        /* 列地址递增 */                         _ptr++;                        /* 指向下一个字符 */                 }         } }  /* ********************************************************************************************************* *        函 数 名: LCD_PutPixel *        功能说明: 画1个像素 *        形    参: *                        _usX,_usY : 像素坐标 *                        _usColor  : 像素颜色 *        返 回 值: 无 ********************************************************************************************************* */ void LCD_PutPixel(uint16_t _usX, uint16_t _usY, uint16_t _usColor) {         LCDH7_PutPixel(_usX, _usY, _usColor); }  /* ********************************************************************************************************* *        函 数 名: LCD_GetPixel *        功能说明: 读取1个像素 *        形    参: *                        _usX,_usY : 像素坐标 *                        _usColor  : 像素颜色 *        返 回 值: RGB颜色值 ********************************************************************************************************* */ uint16_t LCD_GetPixel(uint16_t _usX, uint16_t _usY) {         uint16_t usRGB;          usRGB = LCDH7_GetPixel(_usX, _usY);         return usRGB; }  /* ********************************************************************************************************* *        函 数 名: LCD_DrawLine *        功能说明: 采用 Bresenham 算法,在2点间画一条直线。 *        形    参: *                        _usX1, _usY1 : 起始点坐标 *                        _usX2, _usY2 : 终止点Y坐标 *                        _usColor     : 颜色 *        返 回 值: 无 ********************************************************************************************************* */ void LCD_DrawLine(uint16_t _usX1 , uint16_t _usY1 , uint16_t _usX2 , uint16_t _usY2 , uint16_t _usColor) {         LCDH7_DrawLine(_usX1 , _usY1 , _usX2, _usY2 , _usColor); }  /* ********************************************************************************************************* *        函 数 名: LCD_DrawPoints *        功能说明: 采用 Bresenham 算法,绘制一组点,并将这些点连接起来。可用于波形显示。 *        形    参: *                        x, y     : 坐标数组 *                        _usColor : 颜色 *        返 回 值: 无 ********************************************************************************************************* */ void LCD_DrawPoints(uint16_t *x, uint16_t *y, uint16_t _usSize, uint16_t _usColor) {         uint16_t i;          for (i = 0 ; i < _usSize - 1; i++)         {                 LCD_DrawLine(x, y, x[i + 1], y[i + 1], _usColor);         } }  /* ********************************************************************************************************* *        函 数 名: LCD_DrawRect *        功能说明: 绘制水平放置的矩形。 *        形    参: *                        _usX,_usY: 矩形左上角的坐标 *                        _usHeight : 矩形的高度 *                        _usWidth  : 矩形的宽度 *        返 回 值: 无 ********************************************************************************************************* */ void LCD_DrawRect(uint16_t _usX, uint16_t _usY, uint16_t _usHeight, uint16_t _usWidth, uint16_t _usColor) {         LCDH7_DrawRect(_usX, _usY, _usHeight, _usWidth, _usColor); }  /* ********************************************************************************************************* *        函 数 名: LCD_Fill_Rect *        功能说明: 用一个颜色值填充一个矩形。【emWin 中有同名函数 LCD_FillRect,因此加了下划线区分】 *        形    参: *                        _usX,_usY: 矩形左上角的坐标 *                        _usHeight : 矩形的高度 *                        _usWidth  : 矩形的宽度 *        返 回 值: 无 ********************************************************************************************************* */ void LCD_Fill_Rect(uint16_t _usX, uint16_t _usY, uint16_t _usHeight, uint16_t _usWidth, uint16_t _usColor) {         LCDH7_FillRect(_usX, _usY, _usHeight, _usWidth, _usColor); }  /* ********************************************************************************************************* *        函 数 名: LCD_DrawCircle *        功能说明: 绘制一个圆,笔宽为1个像素 *        形    参: *                        _usX,_usY  : 圆心的坐标 *                        _usRadius  : 圆的半径 *        返 回 值: 无 ********************************************************************************************************* */ void LCD_DrawCircle(uint16_t _usX, uint16_t _usY, uint16_t _usRadius, uint16_t _usColor) {         LCDH7_DrawCircle(_usX, _usY, _usRadius, _usColor); }  /* ********************************************************************************************************* *        函 数 名: LCD_DrawBMP *        功能说明: 在LCD上显示一个BMP位图,位图点阵扫描次序: 从左到右,从上到下 *        形    参: *                        _usX, _usY : 图片的坐标 *                        _usHeight  : 图片高度 *                        _usWidth   : 图片宽度 *                        _ptr       : 图片点阵指针 *        返 回 值: 无 ********************************************************************************************************* */ void LCD_DrawBMP(uint16_t _usX, uint16_t _usY, uint16_t _usHeight, uint16_t _usWidth, uint16_t *_ptr) {         LCDH7_DrawBMP(_usX, _usY, _usHeight, _usWidth, _ptr); }  /* ********************************************************************************************************* *        函 数 名: LCD_DrawWin *        功能说明: 在LCD上绘制一个窗口 *        形    参: 结构体指针 *        返 回 值: 无 ********************************************************************************************************* */ void LCD_DrawWin(WIN_T *_pWin) {         uint16_t TitleHegiht;          TitleHegiht = 20;          /* 绘制窗口外框 */         LCD_DrawRect(_pWin->Left, _pWin->Top, _pWin->Height, _pWin->Width, WIN_BORDER_COLOR);         LCD_DrawRect(_pWin->Left + 1, _pWin->Top + 1, _pWin->Height - 2, _pWin->Width - 2, WIN_BORDER_COLOR);          /* 窗口标题栏 */         LCD_Fill_Rect(_pWin->Left + 2, _pWin->Top + 2, TitleHegiht, _pWin->Width - 4, WIN_TITLE_COLOR);          /* 窗体填充 */         LCD_Fill_Rect(_pWin->Left + 2, _pWin->Top + TitleHegiht + 2, _pWin->Height - 4 - TitleHegiht,                 _pWin->Width - 4, WIN_BODY_COLOR);          LCD_DispStr(_pWin->Left + 3, _pWin->Top + 2, _pWin->pCaption, _pWin->Font); }   /* ********************************************************************************************************* *        函 数 名: LCD_DrawIcon *        功能说明: 在LCD上绘制一个图标,四角自动切为弧脚 *        形    参: _pIcon : 图标结构 *                          _tFont : 字体属性 *                          _ucFocusMode : 焦点模式。0 表示正常图标  1表示选中的图标 *        返 回 值: 无 ********************************************************************************************************* */ void LCD_DrawIcon(const ICON_T *_tIcon, FONT_T *_tFont, uint8_t _ucFocusMode) {         const uint16_t *p;         uint16_t usNewRGB;         uint16_t x, y;                /* 用于记录窗口内的相对坐标 */          p = _tIcon->pBmp;         for (y = 0; y < _tIcon->Height; y++)         {                 for (x = 0; x < _tIcon->Width; x++)                 {                         usNewRGB = *p++;        /* 读取图标的颜色值后指针加1 */                         /* 将图标的4个直角切割为弧角,弧角外是背景图标 */                         if ((y == 0 && (x < 6 || x > _tIcon->Width - 7)) ||                                 (y == 1 && (x < 4 || x > _tIcon->Width - 5)) ||                                 (y == 2 && (x < 3 || x > _tIcon->Width - 4)) ||                                 (y == 3 && (x < 2 || x > _tIcon->Width - 3)) ||                                 (y == 4 && (x < 1 || x > _tIcon->Width - 2)) ||                                 (y == 5 && (x < 1 || x > _tIcon->Width - 2))        ||                                  (y == _tIcon->Height - 1 && (x < 6 || x > _tIcon->Width - 7)) ||                                 (y == _tIcon->Height - 2 && (x < 4 || x > _tIcon->Width - 5)) ||                                 (y == _tIcon->Height - 3 && (x < 3 || x > _tIcon->Width - 4)) ||                                 (y == _tIcon->Height - 4 && (x < 2 || x > _tIcon->Width - 3)) ||                                 (y == _tIcon->Height - 5 && (x < 1 || x > _tIcon->Width - 2)) ||                                 (y == _tIcon->Height - 6 && (x < 1 || x > _tIcon->Width - 2))                                 )                         {                                 ;                         }                         else                         {                                 if (_ucFocusMode != 0)        /* 1表示选中的图标 */                                 {                                         /* 降低原始像素的亮度,实现图标被激活选中的效果 */                                         uint16_t R,G,B;                                         uint16_t bright = 15;                                          /* rrrr rggg gggb bbbb */                                         R = (usNewRGB & 0xF800) >> 11;                                         G = (usNewRGB & 0x07E0) >> 5;                                         B =  usNewRGB & 0x001F;                                         if (R > bright)                                         {                                                 R -= bright;                                         }                                         else                                         {                                                 R = 0;                                         }                                         if (G > 2 * bright)                                         {                                                 G -= 2 * bright;                                         }                                         else                                         {                                                 G = 0;                                         }                                         if (B > bright)                                         {                                                 B -= bright;                                         }                                         else                                         {                                                 B = 0;                                         }                                         usNewRGB = (R << 11) + (G << 5) + B;                                 }                                  LCD_PutPixel(x + _tIcon->Left, y + _tIcon->Top, usNewRGB);                         }                 }         }          /* 绘制图标下的文字 */         {                 uint16_t len;                 uint16_t width;                  len = strlen(_tIcon->Text);                  if  (len == 0)                 {                         return;        /* 如果图标文本长度为0,则不显示 */                 }                  /* 计算文本的总宽度 */                 if (_tFont->FontCode == FC_ST_12)                /* 12点阵 */                 {                         width = 6 * (len + _tFont->Space);                 }                 else        /* FC_ST_16 */                 {                         width = 8 * (len + _tFont->Space);                 }                   /* 水平居中 */                 x = (_tIcon->Left + _tIcon->Width / 2) - width / 2;                 y = _tIcon->Top + _tIcon->Height + 2;                 LCD_DispStr(x, y, (char *)_tIcon->Text, _tFont);         } }  /* ********************************************************************************************************* *        函 数 名: LCD_Blend565 *        功能说明: 对像素透明化 颜色混合 *        形    参: src : 原始像素 *                          dst : 混合的颜色 *                          alpha : 透明度 0-32 *        返 回 值: 无 ********************************************************************************************************* */ uint16_t LCD_Blend565(uint16_t src, uint16_t dst, uint8_t alpha) {         uint32_t src2;         uint32_t dst2;          src2 = ((src << 16) |src) & 0x07E0F81F;         dst2 = ((dst << 16) | dst) & 0x07E0F81F;         dst2 = ((((dst2 - src2) * alpha) >> 5) + src2) & 0x07E0F81F;         return (dst2 >> 16) | dst2; }  /* ********************************************************************************************************* *        函 数 名: LCD_DrawIcon32 *        功能说明: 在LCD上绘制一个图标, 带有透明信息的位图(32位, RGBA). 图标下带文字 *        形    参: _pIcon : 图标结构 *                          _tFont : 字体属性 *                          _ucFocusMode : 焦点模式。0 表示正常图标  1表示选中的图标 *        返 回 值: 无 ********************************************************************************************************* */ void LCD_DrawIcon32(const ICON_T *_tIcon, FONT_T *_tFont, uint8_t _ucFocusMode) {         const uint8_t *p;         uint16_t usOldRGB, usNewRGB;         int16_t x, y;                /* 用于记录窗口内的相对坐标 */         uint8_t R1,G1,B1,A;        /* 新像素色彩分量 */         uint8_t R0,G0,B0;        /* 旧像素色彩分量 */          p = (const uint8_t *)_tIcon->pBmp;         p += 54;                /* 直接指向图像数据区 */          /* 按照BMP位图次序,从左至右,从上至下扫描 */         for (y = _tIcon->Height - 1; y >= 0; y--)         {                 for (x = 0; x < _tIcon->Width; x++)                 {                         B1 = *p++;                         G1 = *p++;                         R1 = *p++;                         A = *p++;        /* Alpha 值(透明度),0-255, 0表示透明,1表示不透明, 中间值表示透明度 */                          if (A == 0x00)        /* 需要透明,显示背景 */                         {                                 ;        /* 不用刷新背景 */                         }                         else if (A == 0xFF)        /* 完全不透明, 显示新像素 */                         {                                 usNewRGB = RGB(R1, G1, B1);                                 if (_ucFocusMode == 1)                                 {                                         usNewRGB = LCD_Blend565(usNewRGB, CL_YELLOW, 10);                                 }                                 LCD_PutPixel(x + _tIcon->Left, y + _tIcon->Top, usNewRGB);                         }                         else         /* 半透明 */                         {                                 /* 计算公式: 实际显示颜色 = 前景颜色 * Alpha / 255 + 背景颜色 * (255-Alpha) / 255 */                                 usOldRGB = LCD_GetPixel(x + _tIcon->Left, y + _tIcon->Top);                                 //usOldRGB = 0xFFFF;                                 R0 = RGB565_R(usOldRGB);                                 G0 = RGB565_G(usOldRGB);                                 B0 = RGB565_B(usOldRGB);                                  R1 = (R1 * A) / 255 + R0 * (255 - A) / 255;                                 G1 = (G1 * A) / 255 + G0 * (255 - A) / 255;                                 B1 = (B1 * A) / 255 + B0 * (255 - A) / 255;                                 usNewRGB = RGB(R1, G1, B1);                                 if (_ucFocusMode == 1)                                 {                                         usNewRGB = LCD_Blend565(usNewRGB, CL_YELLOW, 10);                                 }                                 LCD_PutPixel(x + _tIcon->Left, y + _tIcon->Top, usNewRGB);                         }                 }         }          /* 绘制图标下的文字 */         {                 uint16_t len;                 uint16_t width;                  len = strlen(_tIcon->Text);                  if  (len == 0)                 {                         return;        /* 如果图标文本长度为0,则不显示 */                 }                  /* 计算文本的总宽度 */                 if (_tFont->FontCode == FC_ST_12)                /* 12点阵 */                 {                         width = 6 * (len + _tFont->Space);                 }                 else        /* FC_ST_16 */                 {                         width = 8 * (len + _tFont->Space);                 }                   /* 水平居中 */                 x = (_tIcon->Left + _tIcon->Width / 2) - width / 2;                 y = _tIcon->Top + _tIcon->Height + 2;                 LCD_DispStr(x, y, (char *)_tIcon->Text, _tFont);         } }  /* ********************************************************************************************************* *        函 数 名: LCD_DrawBmp32 *        功能说明: 在LCD上绘制一个32位的BMP图, 带有透明信息的位图(32位, RGBA) *        形    参: _usX, _usY : 显示坐标 *                          _usHeight, _usWidth : 图片高度和宽度 *                          _pBmp : 图片数据(带BMP文件头) *        返 回 值: 无 ********************************************************************************************************* */ void LCD_DrawBmp32(uint16_t _usX, uint16_t _usY, uint16_t _usHeight, uint16_t _usWidth, uint8_t *_pBmp) {         const uint8_t *p;         uint16_t usOldRGB, usNewRGB;         int16_t x, y;                /* 用于记录窗口内的相对坐标 */         uint8_t R1,G1,B1,A;        /* 新像素色彩分量 */         uint8_t R0,G0,B0;        /* 旧像素色彩分量 */          p = (const uint8_t *)_pBmp;         p += 54;                /* 直接指向图像数据区 */          /* 按照BMP位图次序,从左至右,从上至下扫描 */         for (y = _usHeight - 1; y >= 0; y--)         {                 for (x = 0; x < _usWidth; x++)                 {                         B1 = *p++;                         G1 = *p++;                         R1 = *p++;                         A = *p++;        /* Alpha 值(透明度),0-255, 0表示透明,1表示不透明, 中间值表示透明度 */                          if (A == 0x00)        /* 需要透明,显示背景 */                         {                                 ;        /* 不用刷新背景 */                         }                         else if (A == 0xFF)        /* 完全不透明, 显示新像素 */                         {                                 usNewRGB = RGB(R1, G1, B1);                                 //if (_ucFocusMode == 1)                                 //{                                 //        usNewRGB = Blend565(usNewRGB, CL_YELLOW, 10);                                 //}                                 LCD_PutPixel(x + _usX, y + _usY, usNewRGB);                         }                         else         /* 半透明 */                         {                                 /* 计算公式: 实际显示颜色 = 前景颜色 * Alpha / 255 + 背景颜色 * (255-Alpha) / 255 */                                 usOldRGB = LCD_GetPixel(x + _usX, y + _usY);                                 R0 = RGB565_R(usOldRGB);                                 G0 = RGB565_G(usOldRGB);                                 B0 = RGB565_B(usOldRGB);                                  R1 = (R1 * A) / 255 + R0 * (255 - A) / 255;                                 G1 = (G1 * A) / 255 + G0 * (255 - A) / 255;                                 B1 = (B1 * A) / 255 + B0 * (255 - A) / 255;                                 usNewRGB = RGB(R1, G1, B1);                                 //if (_ucFocusMode == 1)                                 //{                                 //        usNewRGB = Blend565(usNewRGB, CL_YELLOW, 10);                                 //}                                 LCD_PutPixel(x + _usX, y + _usY, usNewRGB);                         }                 }         } }  /* ********************************************************************************************************* *        函 数 名: LCD_DrawLabel *        功能说明: 绘制一个文本标签 *        形    参: 结构体指针 *        返 回 值: 无 ********************************************************************************************************* */ void LCD_DrawLabel(LABEL_T *_pLabel) {         char dispbuf[256];         uint16_t i;         uint16_t NewLen;          NewLen = strlen(_pLabel->pCaption);          if (NewLen > _pLabel->MaxLen)         {                 LCD_DispStr(_pLabel->Left, _pLabel->Top, _pLabel->pCaption, _pLabel->Font);                 _pLabel->MaxLen = NewLen;         }         else         {                 for (i = 0; i < NewLen; i++)                 {                         dispbuf = _pLabel->pCaption;                 }                 for (; i < _pLabel->MaxLen; i++)                 {                         dispbuf = ' ';                /* 末尾填充空格 */                 }                 dispbuf = 0;                 LCD_DispStr(_pLabel->Left, _pLabel->Top, dispbuf, _pLabel->Font);         } }  /* ********************************************************************************************************* *        函 数 名: LCD_DrawCheckBox *        功能说明: 绘制一个检查框 *        形    参: 结构体指针 *        返 回 值: 无 ********************************************************************************************************* */ void LCD_DrawCheckBox(CHECK_T *_pCheckBox) {         uint16_t x, y;          /* 目前只做了16点阵汉字的大小 */          /* 绘制外框 */         x = _pCheckBox->Left;         LCD_DrawRect(x, _pCheckBox->Top, CHECK_BOX_H, CHECK_BOX_W, CHECK_BOX_BORDER_COLOR);         LCD_DrawRect(x + 1, _pCheckBox->Top + 1, CHECK_BOX_H - 2, CHECK_BOX_W - 2, CHECK_BOX_BORDER_COLOR);         LCD_Fill_Rect(x + 2, _pCheckBox->Top + 2, CHECK_BOX_H - 4, CHECK_BOX_W - 4, CHECK_BOX_BACK_COLOR);          /* 绘制文本标签 */         x = _pCheckBox->Left + CHECK_BOX_W + 2;         y = _pCheckBox->Top + CHECK_BOX_H / 2 - 8;         LCD_DispStr(x, y, _pCheckBox->pCaption, _pCheckBox->Font);          if (_pCheckBox->Checked)         {                 FONT_T font;              font.FontCode = FC_ST_16;                 font.BackColor = CL_MASK;                 font.FrontColor = CHECK_BOX_CHECKED_COLOR;        /* 钩的颜色 */                 font.Space = 0;                 x = _pCheckBox->Left;                 LCD_DispStr(x + 3, _pCheckBox->Top + 3, "√", &font);         } }  /* ********************************************************************************************************* *        函 数 名: LCD_DrawEdit *        功能说明: 在LCD上绘制一个编辑框 *        形    参: _pEdit 编辑框结构体指针 *        返 回 值: 无 ********************************************************************************************************* */ void LCD_DrawEdit(EDIT_T *_pEdit) {         uint16_t len, x, y;         uint8_t width;          /* 仿XP风格,平面编辑框 */         LCD_DrawRect(_pEdit->Left, _pEdit->Top, _pEdit->Height, _pEdit->Width, EDIT_BORDER_COLOR);         LCD_Fill_Rect(_pEdit->Left + 1, _pEdit->Top + 1, _pEdit->Height - 2, _pEdit->Width - 2, EDIT_BACK_COLOR);          /* 文字居中 */         if (_pEdit->Font->FontCode == FC_ST_12)         {                 width = 6;         }         else         {                 width = 8;         }         len = strlen(_pEdit->pCaption);         x = _pEdit->Left +  (_pEdit->Width - len * width) / 2;         y = _pEdit->Top + _pEdit->Height / 2 - width;          LCD_DispStr(x, y, _pEdit->pCaption, _pEdit->Font); }  /* ********************************************************************************************************* *        函 数 名: LCD_DrawEdit *        功能说明: 在LCD上绘制一个编辑框 *        形    参: *                        _usX, _usY : 图片的坐标 *                        _usHeight  : 图片高度 *                        _usWidth   : 图片宽度 *                        _ptr       : 图片点阵指针 *        返 回 值: 无 ********************************************************************************************************* */ void LCD_DrawButton(BUTTON_T *_pBtn) {         uint16_t x, y, h;         FONT_T font;        /* 按钮激活时,需要更改字体设置,因此需要一个变量来保存 */          font.FontCode = _pBtn->Font->FontCode;         font.FrontColor = _pBtn->Font->FrontColor;         font.BackColor = _pBtn->Font->BackColor;         font.Space = _pBtn->Font->Space;                                          if (_pBtn->Focus == 1)         {                 font.BackColor = BUTTON_ACTIVE_COLOR;         }         else         {                 /* 按钮的背景色统一管理,不能单独指定 */                 font.BackColor = BUTTON_BACK_COLOR;         }                  /* 仿XP风格,平面编辑框 */         LCD_DrawRect(_pBtn->Left, _pBtn->Top, _pBtn->Height, _pBtn->Width, BUTTON_BORDER_COLOR);         LCD_DrawRect(_pBtn->Left + 1, _pBtn->Top + 1, _pBtn->Height - 2, _pBtn->Width - 2, BUTTON_BORDER1_COLOR);         LCD_DrawRect(_pBtn->Left + 2, _pBtn->Top + 2, _pBtn->Height - 4, _pBtn->Width - 4, BUTTON_BORDER2_COLOR);          h =  LCD_GetFontHeight(&font);         x = _pBtn->Left + 3;         y = _pBtn->Top + _pBtn->Height / 2 - h / 2;                                  LCD_Fill_Rect(_pBtn->Left + 3, _pBtn->Top + 3, _pBtn->Height - 6, _pBtn->Width - 6, font.BackColor);        /* 选中后的底色 */         LCD_DispStrEx(x, y, _pBtn->pCaption, &font, _pBtn->Width - 6, ALIGN_CENTER);        /* 水平居中 */                 }  /* ********************************************************************************************************* *        函 数 名: LCD_DrawGroupBox *        功能说明: 在LCD上绘制一个分组框 *        形    参: _pBox 分组框 *        返 回 值: 无 ********************************************************************************************************* */ void LCD_DrawGroupBox(GROUP_T *_pBox) {         uint16_t x, y;          /* 画阴影线 */         LCD_DrawRect(_pBox->Left + 1, _pBox->Top + 5, _pBox->Height, _pBox->Width - 1, CL_BOX_BORDER2);          /* 画主框线 */         LCD_DrawRect(_pBox->Left, _pBox->Top + 4, _pBox->Height, _pBox->Width - 1, CL_BOX_BORDER1);          /* 显示分组框标题(文字在左上角) */         x = _pBox->Left + 9;         y = _pBox->Top;         LCD_DispStr(x, y, _pBox->pCaption, _pBox->Font); }  /* ********************************************************************************************************* *        函 数 名: LCD_DispControl *        功能说明: 绘制控件 *        形    参: _pControl 控件指针 *        返 回 值: 无 ********************************************************************************************************* */ void LCD_DispControl(void *_pControl) {         uint8_t id;          id = *(uint8_t *)_pControl;        /* 读取ID */          switch (id)         {                 case ID_ICON:                         //void LCD_DrawIcon(const ICON_T *_tIcon, FONT_T *_tFont, uint8_t _ucFocusMode);                         break;                  case ID_WIN:                         LCD_DrawWin((WIN_T *)_pControl);                         break;                  case ID_LABEL:                         LCD_DrawLabel((LABEL_T *)_pControl);                         break;                  case ID_BUTTON:                         LCD_DrawButton((BUTTON_T *)_pControl);                         break;                  case ID_CHECK:                         LCD_DrawCheckBox((CHECK_T *)_pControl);                         break;                  case ID_EDIT:                         LCD_DrawEdit((EDIT_T *)_pControl);                         break;                  case ID_GROUP:                         LCD_DrawGroupBox((GROUP_T *)_pControl);                         break;         } }  /* ********************************************************************************************************* *        函 数 名: LCD_SetDirection *        功能说明: 设置显示屏显示方向(横屏 竖屏) *        形    参: 显示方向代码 0 横屏正常, 1=横屏180度翻转, 2=竖屏, 3=竖屏180度翻转 *        返 回 值: 无 ********************************************************************************************************* */ void LCD_SetDirection(uint8_t _dir) {         g_LcdDirection =  _dir;                /* 保存在全局变量 */          LCDH7_SetDirection(_dir); }  /* ********************************************************************************************************* *        函 数 名: LCD_ButtonTouchDown *        功能说明: 判断按钮是否被按下. 检查触摸坐标是否在按钮的范围之内。并重绘按钮。 *        形    参:  _btn : 按钮对象 *                          _usX, _usY: 触摸坐标 *        返 回 值: 1 表示在范围内 ********************************************************************************************************* */ uint8_t LCD_ButtonTouchDown(BUTTON_T *_btn, uint16_t _usX, uint16_t _usY) {         if ((_usX > _btn->Left) && (_usX < _btn->Left + _btn->Width)                 && (_usY > _btn->Top) && (_usY < _btn->Top + _btn->Height))         {                 BUTTON_BEEP();        /* 按键提示音 bsp_tft_lcd.h 文件开头可以使能和关闭 */                 _btn->Focus = 1;                 LCD_DrawButton(_btn);                 return 1;         }         else         {                 return 0;         } }  /* ********************************************************************************************************* *        函 数 名: LCD_ButtonTouchRelease *        功能说明: 判断按钮是否被触摸释放. 并重绘按钮。在触摸释放事件中被调用。 *        形    参:  _btn : 按钮对象 *                          _usX, _usY: 触摸坐标 *        返 回 值: 1 表示在范围内 ********************************************************************************************************* */ uint8_t LCD_ButtonTouchRelease(BUTTON_T *_btn, uint16_t _usX, uint16_t _usY) {         _btn->Focus = 0;         LCD_DrawButton(_btn);          if ((_usX > _btn->Left) && (_usX < _btn->Left + _btn->Width)                 && (_usY > _btn->Top) && (_usY < _btn->Top + _btn->Height))         {                 return 1;         }         else         {                 return 0;         } }  /* ********************************************************************************************************* *        函 数 名: LCD_InitButton *        功能说明: 初始化按钮结构体成员。 *        形    参:  _x, _y : 坐标 *                          _h, _w : 高度和宽度 *                          _pCaption : 按钮文字 *                          _pFont : 按钮字体 *        返 回 值: 无 ********************************************************************************************************* */ void LCD_InitButton(BUTTON_T *_btn, uint16_t _x, uint16_t _y, uint16_t _h, uint16_t _w, char *_pCaption, FONT_T *_pFont) {         _btn->Left = _x;         _btn->Top = _y;         _btn->Height = _h;         _btn->Width = _w;         _btn->pCaption = _pCaption;                 _btn->Font = _pFont;         _btn->Focus = 0; }  /***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/
回复

使用道具 举报

0

主题

5

回帖

5

积分

新手上路

积分
5
发表于 2021-6-26 17:24:01 | 显示全部楼层
/*
*********************************************************************************************************
*
*        模块名称 : TFT液晶显示器驱动模块
*        文件名称 : bsp_tft_lcd.c
*        版    本 : V4.2
*        说    明 : 支持3.0, 3.5, 4.3, 5.0, 7.0寸显示模块.
*                          3.0寸的支持的LCD内部驱动芯片型号有: SPFD5420A、OTM4001A、R61509V
*        修改记录 :
*                版本号  日期       作者    说明
*                v1.0    2011-08-21 armfly  ST固件库版本 V3.5.0版本。
*                                        a) 取消访问寄存器的结构体,直接定义
*                V2.0    2011-10-16 armfly  增加R61509V驱动,实现图标显示函数
*                V2.1    2012-07-06 armfly  增加RA8875驱动,支持4.3寸屏
*                V2.2    2012-07-13 armfly  改进LCD_DispStr函数,支持12点阵字符;修改LCD_DrawRect,解决差一个像素问题
*                V2.3    2012-08-08 armfly  将底层芯片寄存器操作相关的函数放到单独的文件,支持RA8875
*           V3.0    2013-05-20 增加图标结构; 修改        LCD_DrawIconActive  修改DispStr函数支持文本透明
*                V3.1    2013-06-12 解决LCD_DispStr()函数BUG,如果内嵌字库中汉字个数多于256,则出现死循环。
*                V3.2    2013-06-28 完善Label控件, 当显示字符串比之前短时,自动清除多余的文字
*                V3.3    2013-06-29 FSMC初始化时,配置时序,写时序和读时序分开设置。 LCD_FSMCConfig 函数。
*                V3.4    2013-07-06 增加显示32位带Alpha图标的函数 LCD_DrawIcon32
*                V3.5    2013-07-24 增加显示32位带Alpha图片的函数 LCD_DrawBmp32
*                V3.6    2013-07-30 修改 DispEdit() 支持12点阵汉字对齐
*                V3.7    2014-09-06 修改 LCD_InitHard() 同时支持 RA8875-SPI接口和8080接口
*                V3.8    2014-09-15 增加若干函数:
*                                        (1) LCD_DispStrEx() 可以自动对齐自动填白的显示字符串函数
*                                        (2) LCD_GetStrWidth() 计算字符串的像素宽度
*                V3.9    2014-10-18
*                                        (1) 增加 LCD_ButtonTouchDown() LCD_ButtonTouchRelease 判断触摸坐标并重绘按钮
*                                        (2) 增加3.5寸LCD驱动
*                                        (3) 增加 LCD_SetDirection() 函数,设置显示屏方向(横屏 竖屏动态切换)
*                V4.0   2015-04-04
*                                (1) 按钮、编辑框控件增加RA8875字体,内嵌字库和RA8875字库统一编码。字体代码增加
*                                    FC_RA8875_16, FC_RA8875_24,        FC_RA8875_32
*                                (2) FONT_T结构体成员FontCode的类型由 uint16_t 修改为 FONT_CODE_E枚举,便于编译器查错;
*                                (3) 修改 LCD_DispStrEx(), 将读点阵的语句独立到函数:_LCD_ReadAsciiDot(), _LCD_ReadHZDot()
*                                (4) LCD_DispStr() 函数简化,直接调用 LCD_DispStrEx() 实现。
*                                (5) LCD_DispStrEx() 函数支持 RA8875字体。
*                                (6) LCD_ButtonTouchDown() 增加按键提示音
*                V4.1   2015-04-18
*                                (1) 添加RA885 ASCII字体的宽度表。LCD_DispStrEx() 函数可以支持RA8875 ASCII变长宽度计算。
*                                (2) 添加 LCD_HardReset()函数,支持LCD复位由GPIO控制的产品。STM32-V5 不需要GPIO控制。
*                V4.2   2015-07-23
*                                (1) 添加函数LCD_InitButton()
*                                (2) h文件中使能按键提示音 #define BUTTON_BEEP()        BEEP_KeyTone();
*
*        Copyright (C), 2015-2016, 安富莱电子 www.armfly.com
*
*********************************************************************************************************
*/

#include "bsp.h"
#include "fonts.h"

/* 下面3个变量,主要用于使程序同时支持不同的屏 */
uint16_t g_LcdHeight = 240;                        /* 显示屏分辨率-高度 */
uint16_t g_LcdWidth = 400;                        /* 显示屏分辨率-宽度 */
uint8_t s_ucBright;                                        /* 背光亮度参数 */
uint8_t g_LcdDirection = 0;                                /* 显示方向.0,1,2,3 */

static void LCD_HardReset(void);
static void LCD_SetPwmBackLight(uint8_t _bright);

/*
*********************************************************************************************************
*        函 数 名: LCD_InitHard
*        功能说明: 初始化LCD
*        形    参: 无
*        返 回 值: 无
*********************************************************************************************************
*/
void LCD_InitHard(void)
{
        LCD_HardReset();        /* 硬件复位 (STM32-V5, V6 无需),针对其他GPIO控制LCD复位的产品 */

        LCDH7_InitHard();
       
        LCD_SetDirection(0);

        LCD_ClrScr(CL_BLACK);        /* 清屏,显示全黑 */

        //LCD_SetBackLight(BRIGHT_DEFAULT);         /* 打开背光,设置为缺省亮度 */
}


/*
*********************************************************************************************************
*        函 数 名: LCD_SetPwmBackLight
*        功能说明: 初始化控制LCD背景光的GPIO,配置为PWM模式。
*                        当关闭背光时,将CPU IO设置为浮动输入模式(推荐设置为推挽输出,并驱动到低电平);将TIM3关闭 省电
*        形    参:  _bright 亮度,0是灭,255是最亮
*        返 回 值: 无
*********************************************************************************************************
*/
static void LCD_SetPwmBackLight(uint8_t _bright)
{
        /* 背光有CPU输出PWM控制,PA0/TIM5_CH1/TIM2_CH1 */
        //bsp_SetTIMOutPWM(GPIOA, GPIO_PIN_0, TIM5, 1, 100, (_bright * 10000) /255);
        //bsp_SetTIMOutPWM(GPIOA, GPIO_PIN_0, TIM5, 1, 20000, (_bright * 10000) /255);
        bsp_SetTIMOutPWM(GPIOA, GPIO_PIN_8, TIM1, 1, 20000, (_bright * 10000) /255);
}

/*
*********************************************************************************************************
*        函 数 名: LCD_SetBackLight
*        功能说明: 初始化控制LCD背景光的GPIO,配置为PWM模式。
*                        当关闭背光时,将CPU IO设置为浮动输入模式(推荐设置为推挽输出,并驱动到低电平);将TIM3关闭 省电
*        形    参: _bright 亮度,0是灭,255是最亮
*        返 回 值: 无
*********************************************************************************************************
*/
void LCD_SetBackLight(uint8_t _bright)
{
        s_ucBright =  _bright;        /* 保存背光值 */

        LCD_SetPwmBackLight(s_ucBright);
}

/*
*********************************************************************************************************
*        函 数 名: LCD_GetBackLight
*        功能说明: 获得背光亮度参数
*        形    参: 无
*        返 回 值: 背光亮度参数
*********************************************************************************************************
*/
uint8_t LCD_GetBackLight(void)
{
        return s_ucBright;
}

/*
*********************************************************************************************************
*        函 数 名: LCD_HardReset
*        功能说明: 硬件复位. 针对复位口线由GPIO控制的产品。
*        形    参: 无
*        返 回 值: 无
*********************************************************************************************************
*/
void LCD_HardReset(void)
{
#if 0       
        GPIO_InitTypeDef GPIO_InitStructure;

        /* 使能 GPIO时钟 */
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
       
        /* 配置背光GPIO为推挽输出模式 */
        GPIO_InitStructure.GPIO_Pin = GPIO_PIN_1;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
        GPIO_Init(GPIOB, &GPIO_InitStructure);

        GPIO_ResetBits(GPIOB, GPIO_PIN_1);
        bsp_DelayMS(20);
        GPIO_SetBits(GPIOB, GPIO_PIN_1);
#endif       
}

/*
*********************************************************************************************************
*        函 数 名: LCD_GetChipDescribe
*        功能说明: 读取LCD驱动芯片的描述符号,用于显示
*        形    参: char *_str : 描述符字符串填入此缓冲区
*        返 回 值: 无
*********************************************************************************************************
*/
void LCD_GetChipDescribe(char *_str)
{       
        LCDH7_GetChipDescribe(_str);
}

/*
*********************************************************************************************************
*        函 数 名: LCD_GetHeight
*        功能说明: 读取LCD分辨率之高度
*        形    参: 无
*        返 回 值: 无
*********************************************************************************************************
*/
uint16_t LCD_GetHeight(void)
{
        return g_LcdHeight;
}

/*
*********************************************************************************************************
*        函 数 名: LCD_GetWidth
*        功能说明: 读取LCD分辨率之宽度
*        形    参: 无
*        返 回 值: 无
*********************************************************************************************************
*/
uint16_t LCD_GetWidth(void)
{
        return g_LcdWidth;
}

/*
*********************************************************************************************************
*        函 数 名: LCD_DispOn
*        功能说明: 打开显示
*        形    参: 无
*        返 回 值: 无
*********************************************************************************************************
*/
void LCD_DispOn(void)
{
        ;
}

/*
*********************************************************************************************************
*        函 数 名: LCD_DispOff
*        功能说明: 关闭显示
*        形    参: 无
*        返 回 值: 无
*********************************************************************************************************
*/
void LCD_DispOff(void)
{
        ;
}

/*
*********************************************************************************************************
*        函 数 名: LCD_ClrScr
*        功能说明: 根据输入的颜色值清屏
*        形    参: _usColor : 背景色
*        返 回 值: 无
*********************************************************************************************************
*/
void LCD_ClrScr(uint16_t _usColor)
{
        LCDH7_ClrScr(_usColor);
}

/*
*********************************************************************************************************
*        函 数 名: LCD_DispStr
*        功能说明: 在LCD指定坐标(左上角)显示一个字符串
*        形    参:
*                _usX : X坐标
*                _usY : Y坐标
*                _ptr  : 字符串指针
*                _tFont : 字体结构体,包含颜色、背景色(支持透明)、字体代码、文字间距等参数
*        返 回 值: 无
*********************************************************************************************************
*/
void LCD_DispStr(uint16_t _usX, uint16_t _usY, char *_ptr, FONT_T *_tFont)
{
        LCD_DispStrEx(_usX, _usY, _ptr, _tFont, 0, 0);
}

/*
*********************************************************************************************************
*        函 数 名: LCD_GetFontWidth
*        功能说明: 读取字体的宽度(像素单位)
*        形    参:
*                _tFont : 字体结构体,包含颜色、背景色(支持透明)、字体代码、文字间距等参数
*        返 回 值: 字体的宽度(像素单位)
*********************************************************************************************************
*/
uint16_t LCD_GetFontWidth(FONT_T *_tFont)
{
        uint16_t font_width = 16;

        switch (_tFont->FontCode)
        {
                case FC_ST_12:
                        font_width = 12;
                        break;

                case FC_ST_16:
                case FC_RA8875_16:                       
                        font_width = 16;
                        break;
                       
                case FC_RA8875_24:                       
                case FC_ST_24:
                        font_width = 24;
                        break;
                       
                case FC_ST_32:
                case FC_RA8875_32:       
                        font_width = 32;
                        break;               

                case FC_ST_40:
                        font_width = 40;
                        break;       

                case FC_ST_48:
                        font_width = 48;
                        break;
               
        }
        return font_width;
}

/*
*********************************************************************************************************
*        函 数 名: LCD_GetFontHeight
*        功能说明: 读取字体的高度(像素单位)
*        形    参:
*                _tFont : 字体结构体,包含颜色、背景色(支持透明)、字体代码、文字间距等参数
*        返 回 值: 字体的宽度(像素单位)
*********************************************************************************************************
*/
uint16_t LCD_GetFontHeight(FONT_T *_tFont)
{
        uint16_t height = 16;

        switch (_tFont->FontCode)
        {
                case FC_ST_12:
                        height = 12;
                        break;

                case FC_ST_16:
                case FC_RA8875_16:                       
                        height = 16;
                        break;
                       
                case FC_RA8875_24:                       
                case FC_ST_24:
                        height = 24;
                        break;
                       
                case FC_ST_32:
                case FC_RA8875_32:       
                        height = 32;
                        break;
                case FC_ST_40:
                        height = 40;
                        break;       
                case FC_ST_48:
                        height = 48;
                        break;               
        }
        return height;
}

/*
*********************************************************************************************************
*        函 数 名: LCD_GetStrWidth
*        功能说明: 计算字符串宽度(像素单位)
*        形    参:
*                _ptr  : 字符串指针
*                _tFont : 字体结构体,包含颜色、背景色(支持透明)、字体代码、文字间距等参数
*        返 回 值: 无
*********************************************************************************************************
*/
uint16_t LCD_GetStrWidth(char *_ptr, FONT_T *_tFont)
{
        char *p = _ptr;
        uint16_t width = 0;
        uint8_t code1, code2;
        uint16_t font_width;

        font_width = LCD_GetFontWidth(_tFont);

        while (*p != 0)
        {
                code1 = *p;        /* 读取字符串数据, 该数据可能是ascii代码,也可能汉字代码的高字节 */
                if (code1 < 0x80)        /* ASCII */
                {
                        switch(_tFont->FontCode)
                        {
                                case FC_RA8875_16:
                                        font_width = g_RA8875_Ascii16_width[code1 - 0x20];
                                        break;
                               
                                case FC_RA8875_24:
                                        font_width = g_RA8875_Ascii24_width[code1 - 0x20];
                                        break;
                               
                                case FC_RA8875_32:
                                        font_width = g_RA8875_Ascii32_width[code1 - 0x20];
                                        break;
                               
                                case FC_ST_12:
                                        font_width = 6;
                                        break;

                                case FC_ST_16:               
                                        font_width = 8;
                                        break;
                                       
                                case FC_ST_24:                       
                                        font_width = 12;
                                        break;
                                       
                                case FC_ST_32:
                                        font_width = 16;
                                        break;
                               
                               
                                case FC_ST_40:
                                        font_width = 20;
                                        break;
                               
                                case FC_ST_48:
                                        font_width = 24;
                                        break;
                               
                               
                                default:
                                        font_width = 8;
                                        break;                                       
                        }
                       
                }
                else        /* 汉字 */
                {
                        code2 = *++p;
                        if (code2 == 0)
                        {
                                break;
                        }
                        font_width = LCD_GetFontWidth(_tFont);
                       
                }
                width += font_width;
                p++;
        }

        return width;
}

/*
*********************************************************************************************************
*        函 数 名: _LCD_ReadAsciiDot
*        功能说明: 读取1个ASCII字符的点阵数据
*        形    参:
*                _code : ASCII字符的编码,1字节。1-128
*                _fontcode :字体代码
*                _pBuf : 存放读出的字符点阵数据
*        返 回 值: 文字宽度
*********************************************************************************************************
*/
static void _LCD_ReadAsciiDot(uint8_t _code, uint8_t _fontcode, uint8_t *_pBuf)
{
        const uint8_t *pAscDot;
//        const uint16_t *pAscDot;
        uint8_t font_bytes = 0;
//        uint16_t font_bytes = 0;
       
        uint16_t m;
        uint16_t address;
//        uint32_t address;
        uint8_t fAllHz = 0;        /* 1表示程序中内嵌全部的ASCII字符集 */

        pAscDot = 0;
        switch (_fontcode)
        {
                case FC_ST_12:                /* 12点阵 */
                        font_bytes = 24/ 2;
                        pAscDot = g_Ascii12;
                        fAllHz = 1;               
                        break;
               
//                case FC_ST_24:

                case FC_ST_16:
                        /* 缺省是16点阵 */
                        font_bytes = 32/ 2;
                        pAscDot = g_Ascii16;
                        fAllHz = 1;       
                        break;
               
                case FC_ST_24:
//                        font_bytes = 24*2;
                        font_bytes = 24*2;
                        pAscDot = g_Ascii24;
                        break;

                       
                case FC_ST_32:
                        /* 缺省是16点阵 */
                        font_bytes = 64;
                        pAscDot = g_Ascii32;
                        break;
               
               
                case FC_RA8875_16:
                case FC_RA8875_24:
                case FC_RA8875_32:
                        return;
               
                case FC_ST_40:
                        /* 缺省是16点阵 */
                        font_bytes = 40*3;//不行16*7.5/40=3
                        pAscDot = g_Ascii40;
                        fAllHz = 0;       
                        break;
               
                case FC_ST_48:
                        /* 缺省是16点阵 */
                        font_bytes = 48*3;//没问题
                        pAscDot = g_Ascii48;
                        fAllHz = 0;               
                        break;
                        return;
        }       

//        /* 将CPU内部Flash中的ascii字符点阵复制到buf */
//        memcpy(_pBuf, &pAscDot[_code * (font_bytes / 2)], (font_bytes / 2));       
       
                if (fAllHz == 1)        /* 内嵌全部ASCII字符点阵 */
        {
                /* 将CPU内部Flash中的ascii字符点阵复制到buf */
                memcpy(_pBuf, &pAscDot[_code * (font_bytes)], (font_bytes));               
        }
        else        /* 内嵌部分字符,字模数组首字节是ASCII码 */
        {
                m = 0;
                while(1)
                {
                   address = m * (font_bytes + 1);
                   m++;
                   if (_code == pAscDot[address + 0])
                   {
                          address += 1;
                          memcpy(_pBuf, &pAscDot[address], font_bytes);
                          break;
                   }
                   else if ((pAscDot[address + 0] == 0xFF) && (pAscDot[address + 1] == 0xFF))
                   {
                          /* 字库搜索完毕,未找到,则填充全FF */
                          memset(_pBuf, 0xFF, font_bytes);
                          break;
                   }           
           }
   }
}

/*
*********************************************************************************************************
*        函 数 名: _LCD_ReadHZDot
*        功能说明: 读取1个汉字的点阵数据
*        形    参:
*                _code1, _cod2 : 汉字内码. GB2312编码
*                _fontcode :字体代码
*                _pBuf : 存放读出的字符点阵数据
*        返 回 值: 无
*********************************************************************************************************
*/
static void _LCD_ReadHZDot(uint8_t _code1, uint8_t _code2,  uint8_t _fontcode, uint8_t *_pBuf)
{
        #ifdef USE_SMALL_FONT        /* 使用CPU 内部Flash 小字库 */
                uint8_t *pDot;
//                uint8_t font_bytes = 0;
                uint16_t font_bytes = 0;
                uint32_t address;
                uint16_t m;

                pDot = 0;        /* 仅仅用于避免告警 */
                switch (_fontcode)
                {
                        case FC_ST_12:                /* 12点阵 */
                                font_bytes = 24;
                                pDot = (uint8_t *)g_Hz12;       
                                break;
                       
                        case FC_ST_16:
                                font_bytes = 32;
                                pDot = (uint8_t *)g_Hz16;
                                break;
       
                        case FC_ST_24:
                                font_bytes = 72;
                                pDot = (uint8_t *)g_Hz24;
                                break;                       
                               
                        case FC_ST_32:       
                                font_bytes = 128;
                                pDot = (uint8_t *)g_Hz32;
                                break;                                               
                       
                        case FC_ST_40:       
                                font_bytes = 200;//25*8=5^2*8
                                pDot = (uint8_t *)g_Hz40;
                                break;       

                        case FC_ST_48:       
                                font_bytes =288;//36*8=6^2*8
//                                font_bytes =255;//36*8=6^2*8
                                pDot = (uint8_t *)g_Hz48;
                                break;       
                       
                        case FC_RA8875_16:
                        case FC_RA8875_24:
                        case FC_RA8875_32:
                                return;
                }       

                m = 0;
                while(1)
                {
                        address = m * (font_bytes + 2);
                        m++;
                        if ((_code1 == pDot[address + 0]) && (_code2 == pDot[address + 1]))
                        {
                                address += 2;
                                memcpy(_pBuf, &pDot[address], font_bytes);
                                break;
                        }
                        else if ((pDot[address + 0] == 0xFF) && (pDot[address + 1] == 0xFF))
                        {
                                /* 字库搜索完毕,未找到,则填充全FF */
                                memset(_pBuf, 0xFF, font_bytes);
                                break;
                        }
                }
        #else        /* 用全字库 */
                uint8_t *pDot = 0;
                uint8_t font_bytes = 0;
                       
                switch (_fontcode)
                {
                        case FC_ST_12:                /* 12点阵 */
                                font_bytes = 24;
                                pDot = (uint8_t *)HZK12_ADDR;       
                                break;
                       
                        case FC_ST_16:
                                font_bytes = 32;
                                pDot = (uint8_t *)HZK16_ADDR;
                                break;
       
                        case FC_ST_24:
                                font_bytes = 72;
                                pDot = (uint8_t *)HZK24_ADDR;
                                break;                       
                               
                        case FC_ST_32:       
                                font_bytes = 128;
                                pDot = (uint8_t *)HZK32_ADDR;
                                break;                                               
                       
                        case FC_RA8875_16:
                        case FC_RA8875_24:
                        case FC_RA8875_32:
                                return;
                }                       
       
                /* 此处需要根据字库文件存放位置进行修改 */
                if (_code1 >=0xA1 && _code1 <= 0xA9 && _code2 >=0xA1)
                {
                        pDot += ((_code1 - 0xA1) * 94 + (_code2 - 0xA1)) * font_bytes;
                }
                else if (_code1 >=0xB0 && _code1 <= 0xF7 && _code2 >=0xA1)
                {
                        pDot += ((_code1 - 0xB0) * 94 + (_code2 - 0xA1) + 846) * font_bytes;
                }
                memcpy(_pBuf, pDot, font_bytes);
        #endif
}
                       
/*
*********************************************************************************************************
*        函 数 名: LCD_DispStrEx
*        功能说明: 在LCD指定坐标(左上角)显示一个字符串。 增强型函数。支持左\中\右对齐,支持定长清屏。
*        形    参:
*                _usX : X坐标
*                _usY : Y坐标
*                _ptr  : 字符串指针
*                _tFont : 字体结构体,包含颜色、背景色(支持透明)、字体代码、文字间距等参数。可以指定RA8875字库显示汉字
*                _Width : 字符串显示区域的宽度. 0 表示不处理留白区域,此时_Align无效
*                _Align :字符串在显示区域的对齐方式,
*                                ALIGN_LEFT = 0,
*                                ALIGN_CENTER = 1,
*                                ALIGN_RIGHT = 2
*        返 回 值: 无
*********************************************************************************************************
*/
void LCD_DispStrEx(uint16_t _usX, uint16_t _usY, char *_ptr, FONT_T *_tFont, uint16_t _Width,
        uint8_t _Align)
{
        uint32_t i;
        uint8_t code1;
        uint8_t code2;
//        uint8_t buf[64 * 64 / 8];        /* 最大支持24点阵汉字 */
        uint8_t buf[64 * 64 / 1];
//        uint8_t buf[48 * 48 / 8];
       
        uint8_t width;
        uint16_t m;
        uint8_t font_width = 0;
        uint8_t font_height = 0;
        uint16_t x, y;
        uint16_t offset;
        uint16_t str_width;        /* 字符串实际宽度  */
       
//        uint8_t num_timers=0;//将
       
         uint8_t line_bytes;
        uint8_t asc_bytes = 0;
    uint8_t hz_bytes = 0;

        switch (_tFont->FontCode)
        {
                case FC_ST_12:                /* 12点阵 */
                        font_height = 12;
                        font_width = 12;
//                        num_timers=2;
               
                        asc_bytes = 1;
                        hz_bytes = 2;
                        break;
               
                case FC_ST_16:
                case FC_RA8875_16:
                        font_height = 16;
                        font_width = 16;
//                        num_timers=2;
               
                        asc_bytes = 1;
                        hz_bytes = 2;
                        break;

                case FC_ST_24:
                case FC_RA8875_24:
                        font_height = 24;
                        font_width = 24;
//                        num_timers=3;
               
                        asc_bytes = 4;                //width = font_width / 2=12;
                                                                //((line_bytes * width) / font_width)=4*12/24=2
                        hz_bytes = 3;
                        break;
                                               
                case FC_ST_32:       
                case FC_RA8875_32:       
                        font_height = 32;
                        font_width = 32;
//                        num_timers=4;
               
                        asc_bytes = 2;
                        hz_bytes = 4;
                        break;       

                case FC_ST_40:       
                        font_height = 40;
                        font_width = 40;
//                        num_timers=5;

                        asc_bytes = 6;               
                        hz_bytes = 5;
                        break;       

                case FC_ST_48:       
                        font_height = 48;
                        font_width = 48;
//                        num_timers=6;
                        asc_bytes = 6;
                        hz_bytes = 6;
                        break;               
        }
       
        str_width = LCD_GetStrWidth(_ptr, _tFont);        /* 计算字符串实际宽度(RA8875内部ASCII点阵宽度为变长 */
        offset = 0;
        if (_Width > str_width)
        {
                if (_Align == ALIGN_RIGHT)        /* 右对齐 */
                {
                        offset = _Width - str_width;
                }
                else if (_Align == ALIGN_CENTER)        /* 左对齐 */
                {
                        offset = (_Width - str_width) / 2;
                }
                else        /* 左对齐 ALIGN_LEFT */
                {
                        ;
                }
        }

        /* 左侧填背景色, 中间对齐和右边对齐  */
        if (offset > 0)
        {
                LCD_Fill_Rect(_usX, _usY, LCD_GetFontHeight(_tFont), offset,  _tFont->BackColor);
                _usX += offset;
        }
       
        /* 右侧填背景色 */
        if (_Width > str_width)
        {
                LCD_Fill_Rect(_usX + str_width, _usY, LCD_GetFontHeight(_tFont), _Width - str_width - offset,  _tFont->BackColor);
        }
       
        /* 使用CPU内部字库. 点阵信息由CPU读取 */
        {
                /* 开始循环处理字符 */
                while (*_ptr != 0)
                {
                        code1 = *_ptr;        /* 读取字符串数据, 该数据可能是ascii代码,也可能汉字代码的高字节 */
                        if (code1 < 0x80)
                        {
                                /* 将ascii字符点阵复制到buf */
                                //memcpy(buf, &pAscDot[code1 * (font_bytes / 2)], (font_bytes / 2));
                                _LCD_ReadAsciiDot(code1, _tFont->FontCode, buf);        /* 读取ASCII字符点阵 */
                                width = font_width / 2;
                                line_bytes = asc_bytes;
                        }
                        else
                        {
                                code2 = *++_ptr;
                                if (code2 == 0)
                                {
                                        break;
                                }
                                /* 读1个汉字的点阵 */
                                _LCD_ReadHZDot(code1, code2, _tFont->FontCode, buf);
                                width = font_width;
                                line_bytes = hz_bytes;
                        }
       
                        y = _usY;
                        /* 开始刷LCD */
                        for (m = 0; m < font_height; m++)        /* 字符高度 */
                        {
                                x = _usX;
                                for (i = 0; i < width; i++)        /* 字符宽度 */
                                {
//                                        if ((buf[m * ((num_timers * width) / font_width) + i / 8] & (0x80 >> (i % 8 ))) != 0x00)
//                                        if ((buf[m * ((2 * width) / font_width) + i / 8] & (0x80 >> (i % 8 ))) != 0x00)
                                       
//                                         if ((buf[m * line_bytes + i / 8] & (0x80 >> (i % 8 ))) != 0x00)
                                        if ((buf[m * ((line_bytes * width) / font_width) + i / 8] & (0x80 >> (i % 8 ))) != 0x00)
                                        {
                                                LCD_PutPixel(x, y, _tFont->FrontColor);        /* 设置像素颜色为文字色 */
                                        }
                                        else
                                        {
                                                if (_tFont->BackColor != CL_MASK)        /* 透明色 */
                                                {
                                                        LCD_PutPixel(x, y, _tFont->BackColor);        /* 设置像素颜色为文字背景色 */
                                                }
                                        }
       
                                        x++;
                                }
                                y++;
                        }
       
                        if (_tFont->Space > 0)
                        {
                                /* 如果文字底色按_tFont->usBackColor,并且字间距大于点阵的宽度,那么需要在文字之间填充(暂时未实现) */
                        }
                        _usX += width + _tFont->Space;        /* 列地址递增 */
                        _ptr++;                        /* 指向下一个字符 */
                }
        }
}

/*
*********************************************************************************************************
*        函 数 名: LCD_PutPixel
*        功能说明: 画1个像素
*        形    参:
*                        _usX,_usY : 像素坐标
*                        _usColor  : 像素颜色
*        返 回 值: 无
*********************************************************************************************************
*/
void LCD_PutPixel(uint16_t _usX, uint16_t _usY, uint16_t _usColor)
{
        LCDH7_PutPixel(_usX, _usY, _usColor);
}

/*
*********************************************************************************************************
*        函 数 名: LCD_GetPixel
*        功能说明: 读取1个像素
*        形    参:
*                        _usX,_usY : 像素坐标
*                        _usColor  : 像素颜色
*        返 回 值: RGB颜色值
*********************************************************************************************************
*/
uint16_t LCD_GetPixel(uint16_t _usX, uint16_t _usY)
{
        uint16_t usRGB;

        usRGB = LCDH7_GetPixel(_usX, _usY);
        return usRGB;
}

/*
*********************************************************************************************************
*        函 数 名: LCD_DrawLine
*        功能说明: 采用 Bresenham 算法,在2点间画一条直线。
*        形    参:
*                        _usX1, _usY1 : 起始点坐标
*                        _usX2, _usY2 : 终止点Y坐标
*                        _usColor     : 颜色
*        返 回 值: 无
*********************************************************************************************************
*/
void LCD_DrawLine(uint16_t _usX1 , uint16_t _usY1 , uint16_t _usX2 , uint16_t _usY2 , uint16_t _usColor)
{
        LCDH7_DrawLine(_usX1 , _usY1 , _usX2, _usY2 , _usColor);
}

/*
*********************************************************************************************************
*        函 数 名: LCD_DrawPoints
*        功能说明: 采用 Bresenham 算法,绘制一组点,并将这些点连接起来。可用于波形显示。
*        形    参:
*                        x, y     : 坐标数组
*                        _usColor : 颜色
*        返 回 值: 无
*********************************************************************************************************
*/
void LCD_DrawPoints(uint16_t *x, uint16_t *y, uint16_t _usSize, uint16_t _usColor)
{
        uint16_t i;

        for (i = 0 ; i < _usSize - 1; i++)
        {
                LCD_DrawLine(x, y, x[i + 1], y[i + 1], _usColor);
        }
}

/*
*********************************************************************************************************
*        函 数 名: LCD_DrawRect
*        功能说明: 绘制水平放置的矩形。
*        形    参:
*                        _usX,_usY: 矩形左上角的坐标
*                        _usHeight : 矩形的高度
*                        _usWidth  : 矩形的宽度
*        返 回 值: 无
*********************************************************************************************************
*/
void LCD_DrawRect(uint16_t _usX, uint16_t _usY, uint16_t _usHeight, uint16_t _usWidth, uint16_t _usColor)
{
        LCDH7_DrawRect(_usX, _usY, _usHeight, _usWidth, _usColor);
}

/*
*********************************************************************************************************
*        函 数 名: LCD_Fill_Rect
*        功能说明: 用一个颜色值填充一个矩形。【emWin 中有同名函数 LCD_FillRect,因此加了下划线区分】
*        形    参:
*                        _usX,_usY: 矩形左上角的坐标
*                        _usHeight : 矩形的高度
*                        _usWidth  : 矩形的宽度
*        返 回 值: 无
*********************************************************************************************************
*/
void LCD_Fill_Rect(uint16_t _usX, uint16_t _usY, uint16_t _usHeight, uint16_t _usWidth, uint16_t _usColor)
{
        LCDH7_FillRect(_usX, _usY, _usHeight, _usWidth, _usColor);
}

/*
*********************************************************************************************************
*        函 数 名: LCD_DrawCircle
*        功能说明: 绘制一个圆,笔宽为1个像素
*        形    参:
*                        _usX,_usY  : 圆心的坐标
*                        _usRadius  : 圆的半径
*        返 回 值: 无
*********************************************************************************************************
*/
void LCD_DrawCircle(uint16_t _usX, uint16_t _usY, uint16_t _usRadius, uint16_t _usColor)
{
        LCDH7_DrawCircle(_usX, _usY, _usRadius, _usColor);
}

/*
*********************************************************************************************************
*        函 数 名: LCD_DrawBMP
*        功能说明: 在LCD上显示一个BMP位图,位图点阵扫描次序: 从左到右,从上到下
*        形    参:
*                        _usX, _usY : 图片的坐标
*                        _usHeight  : 图片高度
*                        _usWidth   : 图片宽度
*                        _ptr       : 图片点阵指针
*        返 回 值: 无
*********************************************************************************************************
*/
void LCD_DrawBMP(uint16_t _usX, uint16_t _usY, uint16_t _usHeight, uint16_t _usWidth, uint16_t *_ptr)
{
        LCDH7_DrawBMP(_usX, _usY, _usHeight, _usWidth, _ptr);
}

/*
*********************************************************************************************************
*        函 数 名: LCD_DrawWin
*        功能说明: 在LCD上绘制一个窗口
*        形    参: 结构体指针
*        返 回 值: 无
*********************************************************************************************************
*/
void LCD_DrawWin(WIN_T *_pWin)
{
        uint16_t TitleHegiht;

        TitleHegiht = 20;

        /* 绘制窗口外框 */
        LCD_DrawRect(_pWin->Left, _pWin->Top, _pWin->Height, _pWin->Width, WIN_BORDER_COLOR);
        LCD_DrawRect(_pWin->Left + 1, _pWin->Top + 1, _pWin->Height - 2, _pWin->Width - 2, WIN_BORDER_COLOR);

        /* 窗口标题栏 */
        LCD_Fill_Rect(_pWin->Left + 2, _pWin->Top + 2, TitleHegiht, _pWin->Width - 4, WIN_TITLE_COLOR);

        /* 窗体填充 */
        LCD_Fill_Rect(_pWin->Left + 2, _pWin->Top + TitleHegiht + 2, _pWin->Height - 4 - TitleHegiht,
                _pWin->Width - 4, WIN_BODY_COLOR);

        LCD_DispStr(_pWin->Left + 3, _pWin->Top + 2, _pWin->pCaption, _pWin->Font);
}


/*
*********************************************************************************************************
*        函 数 名: LCD_DrawIcon
*        功能说明: 在LCD上绘制一个图标,四角自动切为弧脚
*        形    参: _pIcon : 图标结构
*                          _tFont : 字体属性
*                          _ucFocusMode : 焦点模式。0 表示正常图标  1表示选中的图标
*        返 回 值: 无
*********************************************************************************************************
*/
void LCD_DrawIcon(const ICON_T *_tIcon, FONT_T *_tFont, uint8_t _ucFocusMode)
{
        const uint16_t *p;
        uint16_t usNewRGB;
        uint16_t x, y;                /* 用于记录窗口内的相对坐标 */

        p = _tIcon->pBmp;
        for (y = 0; y < _tIcon->Height; y++)
        {
                for (x = 0; x < _tIcon->Width; x++)
                {
                        usNewRGB = *p++;        /* 读取图标的颜色值后指针加1 */
                        /* 将图标的4个直角切割为弧角,弧角外是背景图标 */
                        if ((y == 0 && (x < 6 || x > _tIcon->Width - 7)) ||
                                (y == 1 && (x < 4 || x > _tIcon->Width - 5)) ||
                                (y == 2 && (x < 3 || x > _tIcon->Width - 4)) ||
                                (y == 3 && (x < 2 || x > _tIcon->Width - 3)) ||
                                (y == 4 && (x < 1 || x > _tIcon->Width - 2)) ||
                                (y == 5 && (x < 1 || x > _tIcon->Width - 2))        ||

                                (y == _tIcon->Height - 1 && (x < 6 || x > _tIcon->Width - 7)) ||
                                (y == _tIcon->Height - 2 && (x < 4 || x > _tIcon->Width - 5)) ||
                                (y == _tIcon->Height - 3 && (x < 3 || x > _tIcon->Width - 4)) ||
                                (y == _tIcon->Height - 4 && (x < 2 || x > _tIcon->Width - 3)) ||
                                (y == _tIcon->Height - 5 && (x < 1 || x > _tIcon->Width - 2)) ||
                                (y == _tIcon->Height - 6 && (x < 1 || x > _tIcon->Width - 2))
                                )
                        {
                                ;
                        }
                        else
                        {
                                if (_ucFocusMode != 0)        /* 1表示选中的图标 */
                                {
                                        /* 降低原始像素的亮度,实现图标被激活选中的效果 */
                                        uint16_t R,G,B;
                                        uint16_t bright = 15;

                                        /* rrrr rggg gggb bbbb */
                                        R = (usNewRGB & 0xF800) >> 11;
                                        G = (usNewRGB & 0x07E0) >> 5;
                                        B =  usNewRGB & 0x001F;
                                        if (R > bright)
                                        {
                                                R -= bright;
                                        }
                                        else
                                        {
                                                R = 0;
                                        }
                                        if (G > 2 * bright)
                                        {
                                                G -= 2 * bright;
                                        }
                                        else
                                        {
                                                G = 0;
                                        }
                                        if (B > bright)
                                        {
                                                B -= bright;
                                        }
                                        else
                                        {
                                                B = 0;
                                        }
                                        usNewRGB = (R << 11) + (G << 5) + B;
                                }

                                LCD_PutPixel(x + _tIcon->Left, y + _tIcon->Top, usNewRGB);
                        }
                }
        }

        /* 绘制图标下的文字 */
        {
                uint16_t len;
                uint16_t width;

                len = strlen(_tIcon->Text);

                if  (len == 0)
                {
                        return;        /* 如果图标文本长度为0,则不显示 */
                }

                /* 计算文本的总宽度 */
                if (_tFont->FontCode == FC_ST_12)                /* 12点阵 */
                {
                        width = 6 * (len + _tFont->Space);
                }
                else        /* FC_ST_16 */
                {
                        width = 8 * (len + _tFont->Space);
                }


                /* 水平居中 */
                x = (_tIcon->Left + _tIcon->Width / 2) - width / 2;
                y = _tIcon->Top + _tIcon->Height + 2;
                LCD_DispStr(x, y, (char *)_tIcon->Text, _tFont);
        }
}

/*
*********************************************************************************************************
*        函 数 名: LCD_Blend565
*        功能说明: 对像素透明化 颜色混合
*        形    参: src : 原始像素
*                          dst : 混合的颜色
*                          alpha : 透明度 0-32
*        返 回 值: 无
*********************************************************************************************************
*/
uint16_t LCD_Blend565(uint16_t src, uint16_t dst, uint8_t alpha)
{
        uint32_t src2;
        uint32_t dst2;

        src2 = ((src << 16) |src) & 0x07E0F81F;
        dst2 = ((dst << 16) | dst) & 0x07E0F81F;
        dst2 = ((((dst2 - src2) * alpha) >> 5) + src2) & 0x07E0F81F;
        return (dst2 >> 16) | dst2;
}

/*
*********************************************************************************************************
*        函 数 名: LCD_DrawIcon32
*        功能说明: 在LCD上绘制一个图标, 带有透明信息的位图(32位, RGBA). 图标下带文字
*        形    参: _pIcon : 图标结构
*                          _tFont : 字体属性
*                          _ucFocusMode : 焦点模式。0 表示正常图标  1表示选中的图标
*        返 回 值: 无
*********************************************************************************************************
*/
void LCD_DrawIcon32(const ICON_T *_tIcon, FONT_T *_tFont, uint8_t _ucFocusMode)
{
        const uint8_t *p;
        uint16_t usOldRGB, usNewRGB;
        int16_t x, y;                /* 用于记录窗口内的相对坐标 */
        uint8_t R1,G1,B1,A;        /* 新像素色彩分量 */
        uint8_t R0,G0,B0;        /* 旧像素色彩分量 */

        p = (const uint8_t *)_tIcon->pBmp;
        p += 54;                /* 直接指向图像数据区 */

        /* 按照BMP位图次序,从左至右,从上至下扫描 */
        for (y = _tIcon->Height - 1; y >= 0; y--)
        {
                for (x = 0; x < _tIcon->Width; x++)
                {
                        B1 = *p++;
                        G1 = *p++;
                        R1 = *p++;
                        A = *p++;        /* Alpha 值(透明度),0-255, 0表示透明,1表示不透明, 中间值表示透明度 */

                        if (A == 0x00)        /* 需要透明,显示背景 */
                        {
                                ;        /* 不用刷新背景 */
                        }
                        else if (A == 0xFF)        /* 完全不透明, 显示新像素 */
                        {
                                usNewRGB = RGB(R1, G1, B1);
                                if (_ucFocusMode == 1)
                                {
                                        usNewRGB = LCD_Blend565(usNewRGB, CL_YELLOW, 10);
                                }
                                LCD_PutPixel(x + _tIcon->Left, y + _tIcon->Top, usNewRGB);
                        }
                        else         /* 半透明 */
                        {
                                /* 计算公式: 实际显示颜色 = 前景颜色 * Alpha / 255 + 背景颜色 * (255-Alpha) / 255 */
                                usOldRGB = LCD_GetPixel(x + _tIcon->Left, y + _tIcon->Top);
                                //usOldRGB = 0xFFFF;
                                R0 = RGB565_R(usOldRGB);
                                G0 = RGB565_G(usOldRGB);
                                B0 = RGB565_B(usOldRGB);

                                R1 = (R1 * A) / 255 + R0 * (255 - A) / 255;
                                G1 = (G1 * A) / 255 + G0 * (255 - A) / 255;
                                B1 = (B1 * A) / 255 + B0 * (255 - A) / 255;
                                usNewRGB = RGB(R1, G1, B1);
                                if (_ucFocusMode == 1)
                                {
                                        usNewRGB = LCD_Blend565(usNewRGB, CL_YELLOW, 10);
                                }
                                LCD_PutPixel(x + _tIcon->Left, y + _tIcon->Top, usNewRGB);
                        }
                }
        }

        /* 绘制图标下的文字 */
        {
                uint16_t len;
                uint16_t width;

                len = strlen(_tIcon->Text);

                if  (len == 0)
                {
                        return;        /* 如果图标文本长度为0,则不显示 */
                }

                /* 计算文本的总宽度 */
                if (_tFont->FontCode == FC_ST_12)                /* 12点阵 */
                {
                        width = 6 * (len + _tFont->Space);
                }
                else        /* FC_ST_16 */
                {
                        width = 8 * (len + _tFont->Space);
                }


                /* 水平居中 */
                x = (_tIcon->Left + _tIcon->Width / 2) - width / 2;
                y = _tIcon->Top + _tIcon->Height + 2;
                LCD_DispStr(x, y, (char *)_tIcon->Text, _tFont);
        }
}

/*
*********************************************************************************************************
*        函 数 名: LCD_DrawBmp32
*        功能说明: 在LCD上绘制一个32位的BMP图, 带有透明信息的位图(32位, RGBA)
*        形    参: _usX, _usY : 显示坐标
*                          _usHeight, _usWidth : 图片高度和宽度
*                          _pBmp : 图片数据(带BMP文件头)
*        返 回 值: 无
*********************************************************************************************************
*/
void LCD_DrawBmp32(uint16_t _usX, uint16_t _usY, uint16_t _usHeight, uint16_t _usWidth, uint8_t *_pBmp)
{
        const uint8_t *p;
        uint16_t usOldRGB, usNewRGB;
        int16_t x, y;                /* 用于记录窗口内的相对坐标 */
        uint8_t R1,G1,B1,A;        /* 新像素色彩分量 */
        uint8_t R0,G0,B0;        /* 旧像素色彩分量 */

        p = (const uint8_t *)_pBmp;
        p += 54;                /* 直接指向图像数据区 */

        /* 按照BMP位图次序,从左至右,从上至下扫描 */
        for (y = _usHeight - 1; y >= 0; y--)
        {
                for (x = 0; x < _usWidth; x++)
                {
                        B1 = *p++;
                        G1 = *p++;
                        R1 = *p++;
                        A = *p++;        /* Alpha 值(透明度),0-255, 0表示透明,1表示不透明, 中间值表示透明度 */

                        if (A == 0x00)        /* 需要透明,显示背景 */
                        {
                                ;        /* 不用刷新背景 */
                        }
                        else if (A == 0xFF)        /* 完全不透明, 显示新像素 */
                        {
                                usNewRGB = RGB(R1, G1, B1);
                                //if (_ucFocusMode == 1)
                                //{
                                //        usNewRGB = Blend565(usNewRGB, CL_YELLOW, 10);
                                //}
                                LCD_PutPixel(x + _usX, y + _usY, usNewRGB);
                        }
                        else         /* 半透明 */
                        {
                                /* 计算公式: 实际显示颜色 = 前景颜色 * Alpha / 255 + 背景颜色 * (255-Alpha) / 255 */
                                usOldRGB = LCD_GetPixel(x + _usX, y + _usY);
                                R0 = RGB565_R(usOldRGB);
                                G0 = RGB565_G(usOldRGB);
                                B0 = RGB565_B(usOldRGB);

                                R1 = (R1 * A) / 255 + R0 * (255 - A) / 255;
                                G1 = (G1 * A) / 255 + G0 * (255 - A) / 255;
                                B1 = (B1 * A) / 255 + B0 * (255 - A) / 255;
                                usNewRGB = RGB(R1, G1, B1);
                                //if (_ucFocusMode == 1)
                                //{
                                //        usNewRGB = Blend565(usNewRGB, CL_YELLOW, 10);
                                //}
                                LCD_PutPixel(x + _usX, y + _usY, usNewRGB);
                        }
                }
        }
}

/*
*********************************************************************************************************
*        函 数 名: LCD_DrawLabel
*        功能说明: 绘制一个文本标签
*        形    参: 结构体指针
*        返 回 值: 无
*********************************************************************************************************
*/
void LCD_DrawLabel(LABEL_T *_pLabel)
{
        char dispbuf[256];
        uint16_t i;
        uint16_t NewLen;

        NewLen = strlen(_pLabel->pCaption);

        if (NewLen > _pLabel->MaxLen)
        {
                LCD_DispStr(_pLabel->Left, _pLabel->Top, _pLabel->pCaption, _pLabel->Font);
                _pLabel->MaxLen = NewLen;
        }
        else
        {
                for (i = 0; i < NewLen; i++)
                {
                        dispbuf = _pLabel->pCaption;
                }
                for (; i < _pLabel->MaxLen; i++)
                {
                        dispbuf = ' ';                /* 末尾填充空格 */
                }
                dispbuf = 0;
                LCD_DispStr(_pLabel->Left, _pLabel->Top, dispbuf, _pLabel->Font);
        }
}

/*
*********************************************************************************************************
*        函 数 名: LCD_DrawCheckBox
*        功能说明: 绘制一个检查框
*        形    参: 结构体指针
*        返 回 值: 无
*********************************************************************************************************
*/
void LCD_DrawCheckBox(CHECK_T *_pCheckBox)
{
        uint16_t x, y;

        /* 目前只做了16点阵汉字的大小 */

        /* 绘制外框 */
        x = _pCheckBox->Left;
        LCD_DrawRect(x, _pCheckBox->Top, CHECK_BOX_H, CHECK_BOX_W, CHECK_BOX_BORDER_COLOR);
        LCD_DrawRect(x + 1, _pCheckBox->Top + 1, CHECK_BOX_H - 2, CHECK_BOX_W - 2, CHECK_BOX_BORDER_COLOR);
        LCD_Fill_Rect(x + 2, _pCheckBox->Top + 2, CHECK_BOX_H - 4, CHECK_BOX_W - 4, CHECK_BOX_BACK_COLOR);

        /* 绘制文本标签 */
        x = _pCheckBox->Left + CHECK_BOX_W + 2;
        y = _pCheckBox->Top + CHECK_BOX_H / 2 - 8;
        LCD_DispStr(x, y, _pCheckBox->pCaption, _pCheckBox->Font);

        if (_pCheckBox->Checked)
        {
                FONT_T font;

            font.FontCode = FC_ST_16;
                font.BackColor = CL_MASK;
                font.FrontColor = CHECK_BOX_CHECKED_COLOR;        /* 钩的颜色 */
                font.Space = 0;
                x = _pCheckBox->Left;
                LCD_DispStr(x + 3, _pCheckBox->Top + 3, "√", &font);
        }
}

/*
*********************************************************************************************************
*        函 数 名: LCD_DrawEdit
*        功能说明: 在LCD上绘制一个编辑框
*        形    参: _pEdit 编辑框结构体指针
*        返 回 值: 无
*********************************************************************************************************
*/
void LCD_DrawEdit(EDIT_T *_pEdit)
{
        uint16_t len, x, y;
        uint8_t width;

        /* 仿XP风格,平面编辑框 */
        LCD_DrawRect(_pEdit->Left, _pEdit->Top, _pEdit->Height, _pEdit->Width, EDIT_BORDER_COLOR);
        LCD_Fill_Rect(_pEdit->Left + 1, _pEdit->Top + 1, _pEdit->Height - 2, _pEdit->Width - 2, EDIT_BACK_COLOR);

        /* 文字居中 */
        if (_pEdit->Font->FontCode == FC_ST_12)
        {
                width = 6;
        }
        else
        {
                width = 8;
        }
        len = strlen(_pEdit->pCaption);
        x = _pEdit->Left +  (_pEdit->Width - len * width) / 2;
        y = _pEdit->Top + _pEdit->Height / 2 - width;

        LCD_DispStr(x, y, _pEdit->pCaption, _pEdit->Font);
}

/*
*********************************************************************************************************
*        函 数 名: LCD_DrawEdit
*        功能说明: 在LCD上绘制一个编辑框
*        形    参:
*                        _usX, _usY : 图片的坐标
*                        _usHeight  : 图片高度
*                        _usWidth   : 图片宽度
*                        _ptr       : 图片点阵指针
*        返 回 值: 无
*********************************************************************************************************
*/
void LCD_DrawButton(BUTTON_T *_pBtn)
{
        uint16_t x, y, h;
        FONT_T font;        /* 按钮激活时,需要更改字体设置,因此需要一个变量来保存 */

        font.FontCode = _pBtn->Font->FontCode;
        font.FrontColor = _pBtn->Font->FrontColor;
        font.BackColor = _pBtn->Font->BackColor;
        font.Space = _pBtn->Font->Space;       
                       
        if (_pBtn->Focus == 1)
        {
                font.BackColor = BUTTON_ACTIVE_COLOR;
        }
        else
        {
                /* 按钮的背景色统一管理,不能单独指定 */
                font.BackColor = BUTTON_BACK_COLOR;
        }
       
        /* 仿XP风格,平面编辑框 */
        LCD_DrawRect(_pBtn->Left, _pBtn->Top, _pBtn->Height, _pBtn->Width, BUTTON_BORDER_COLOR);
        LCD_DrawRect(_pBtn->Left + 1, _pBtn->Top + 1, _pBtn->Height - 2, _pBtn->Width - 2, BUTTON_BORDER1_COLOR);
        LCD_DrawRect(_pBtn->Left + 2, _pBtn->Top + 2, _pBtn->Height - 4, _pBtn->Width - 4, BUTTON_BORDER2_COLOR);

        h =  LCD_GetFontHeight(&font);
        x = _pBtn->Left + 3;
        y = _pBtn->Top + _pBtn->Height / 2 - h / 2;               
       
        LCD_Fill_Rect(_pBtn->Left + 3, _pBtn->Top + 3, _pBtn->Height - 6, _pBtn->Width - 6, font.BackColor);        /* 选中后的底色 */
        LCD_DispStrEx(x, y, _pBtn->pCaption, &font, _pBtn->Width - 6, ALIGN_CENTER);        /* 水平居中 */               
}

/*
*********************************************************************************************************
*        函 数 名: LCD_DrawGroupBox
*        功能说明: 在LCD上绘制一个分组框
*        形    参: _pBox 分组框
*        返 回 值: 无
*********************************************************************************************************
*/
void LCD_DrawGroupBox(GROUP_T *_pBox)
{
        uint16_t x, y;

        /* 画阴影线 */
        LCD_DrawRect(_pBox->Left + 1, _pBox->Top + 5, _pBox->Height, _pBox->Width - 1, CL_BOX_BORDER2);

        /* 画主框线 */
        LCD_DrawRect(_pBox->Left, _pBox->Top + 4, _pBox->Height, _pBox->Width - 1, CL_BOX_BORDER1);

        /* 显示分组框标题(文字在左上角) */
        x = _pBox->Left + 9;
        y = _pBox->Top;
        LCD_DispStr(x, y, _pBox->pCaption, _pBox->Font);
}

/*
*********************************************************************************************************
*        函 数 名: LCD_DispControl
*        功能说明: 绘制控件
*        形    参: _pControl 控件指针
*        返 回 值: 无
*********************************************************************************************************
*/
void LCD_DispControl(void *_pControl)
{
        uint8_t id;

        id = *(uint8_t *)_pControl;        /* 读取ID */

        switch (id)
        {
                case ID_ICON:
                        //void LCD_DrawIcon(const ICON_T *_tIcon, FONT_T *_tFont, uint8_t _ucFocusMode);
                        break;

                case ID_WIN:
                        LCD_DrawWin((WIN_T *)_pControl);
                        break;

                case ID_LABEL:
                        LCD_DrawLabel((LABEL_T *)_pControl);
                        break;

                case ID_BUTTON:
                        LCD_DrawButton((BUTTON_T *)_pControl);
                        break;

                case ID_CHECK:
                        LCD_DrawCheckBox((CHECK_T *)_pControl);
                        break;

                case ID_EDIT:
                        LCD_DrawEdit((EDIT_T *)_pControl);
                        break;

                case ID_GROUP:
                        LCD_DrawGroupBox((GROUP_T *)_pControl);
                        break;
        }
}

/*
*********************************************************************************************************
*        函 数 名: LCD_SetDirection
*        功能说明: 设置显示屏显示方向(横屏 竖屏)
*        形    参: 显示方向代码 0 横屏正常, 1=横屏180度翻转, 2=竖屏, 3=竖屏180度翻转
*        返 回 值: 无
*********************************************************************************************************
*/
void LCD_SetDirection(uint8_t _dir)
{
        g_LcdDirection =  _dir;                /* 保存在全局变量 */

        LCDH7_SetDirection(_dir);
}

/*
*********************************************************************************************************
*        函 数 名: LCD_ButtonTouchDown
*        功能说明: 判断按钮是否被按下. 检查触摸坐标是否在按钮的范围之内。并重绘按钮。
*        形    参:  _btn : 按钮对象
*                          _usX, _usY: 触摸坐标
*        返 回 值: 1 表示在范围内
*********************************************************************************************************
*/
uint8_t LCD_ButtonTouchDown(BUTTON_T *_btn, uint16_t _usX, uint16_t _usY)
{
        if ((_usX > _btn->Left) && (_usX < _btn->Left + _btn->Width)
                && (_usY > _btn->Top) && (_usY < _btn->Top + _btn->Height))
        {
                BUTTON_BEEP();        /* 按键提示音 bsp_tft_lcd.h 文件开头可以使能和关闭 */
                _btn->Focus = 1;
                LCD_DrawButton(_btn);
                return 1;
        }
        else
        {
                return 0;
        }
}

/*
*********************************************************************************************************
*        函 数 名: LCD_ButtonTouchRelease
*        功能说明: 判断按钮是否被触摸释放. 并重绘按钮。在触摸释放事件中被调用。
*        形    参:  _btn : 按钮对象
*                          _usX, _usY: 触摸坐标
*        返 回 值: 1 表示在范围内
*********************************************************************************************************
*/
uint8_t LCD_ButtonTouchRelease(BUTTON_T *_btn, uint16_t _usX, uint16_t _usY)
{
        _btn->Focus = 0;
        LCD_DrawButton(_btn);

        if ((_usX > _btn->Left) && (_usX < _btn->Left + _btn->Width)
                && (_usY > _btn->Top) && (_usY < _btn->Top + _btn->Height))
        {
                return 1;
        }
        else
        {
                return 0;
        }
}

/*
*********************************************************************************************************
*        函 数 名: LCD_InitButton
*        功能说明: 初始化按钮结构体成员。
*        形    参:  _x, _y : 坐标
*                          _h, _w : 高度和宽度
*                          _pCaption : 按钮文字
*                          _pFont : 按钮字体
*        返 回 值: 无
*********************************************************************************************************
*/
void LCD_InitButton(BUTTON_T *_btn, uint16_t _x, uint16_t _y, uint16_t _h, uint16_t _w, char *_pCaption, FONT_T *_pFont)
{
        _btn->Left = _x;
        _btn->Top = _y;
        _btn->Height = _h;
        _btn->Width = _w;
        _btn->pCaption = _pCaption;       
        _btn->Font = _pFont;
        _btn->Focus = 0;
}

/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/


bsp_tft_lcd.rar

3.12 KB, 下载次数: 0

回复

使用道具 举报

0

主题

5

回帖

5

积分

新手上路

积分
5
发表于 2021-6-26 17:25:08 | 显示全部楼层
/*
*********************************************************************************************************
*        函 数 名: HardInfo
*        功能说明: 自动检测硬件
*        形    参: 无
*        返 回 值: 无
*********************************************************************************************************
*/
void HardInfo(void)
{
       
        FONT_T tFont24,tFont32,tFont40, tFont48;        /* 定义一个字体结构体变量,用于设置字体参数 */       
       
        /* 设置字体参数 */
        {
        tFont24.FontCode = FC_ST_24;            /* 字体代码 32点阵 */
        tFont24.FrontColor = CL_WHITE;                /* 字体颜色 */
        tFont24.BackColor = CL_MASK;            /* 文字背景颜色 */
        tFont24.Space = 0;                                        /* 文字间距,单位 = 像素 */
               
       
        tFont32.FontCode = FC_ST_32;            /* 字体代码 32点阵 */
        tFont32.FrontColor = CL_WHITE;                /* 字体颜色 */
        tFont32.BackColor = CL_MASK;            /* 文字背景颜色 */
        tFont32.Space = 0;                                        /* 文字间距,单位 = 像素 */
               
        tFont40.FontCode = FC_ST_40;        /* 字体代码 32点阵 */
        tFont40.FrontColor = CL_WHITE;                /* 字体颜色 0 或 1 */
        tFont40.BackColor = CL_MASK;                /* 文字背景颜色 0 或 1 */
        tFont40.Space = 0;                        /* 文字间距,单位 = 像素 */
               
        tFont48.FontCode = FC_ST_48;        /* 字体代码 32点阵 */
        tFont48.FrontColor = CL_WHITE;                /* 字体颜色 0 或 1 */
        tFont48.BackColor = CL_MASK;                /* 文字背景颜色 0 或 1 */
        tFont48.Space = 0;                        /* 文字间距,单位 = 像素 */
       

        }       
       
       
//        LCDH7_FillRect(0, 0, 70, 800,CL_GREY4);       
////        LCD_DrawBmp32(45, 20, 40, 156, (uint8_t *)acLOGO);
//        LCD_DispStr(90,20,"航天润普",&tFont32);
//               
//        LCDH7_FillRect(0, 70, 410, 800,CL_BLUE);
       
        LCD_DispStr(90, 100, "01", &tFont40);
        LCD_DispStr(90, 200, "HT-211", &tFont48);       
        LCD_DispStr(235,200,"多功能存储介质销毁机",&tFont48);
       
//        LCDH7_FillRect(0, 410, 70, 800,CL_GREY1);
        LCD_DispStr(50,433,"北京航天润普科技发展有限公司",&tFont24);
        LCD_DispStr(500, 433, "400-666-7018", &tFont24);
       
//        LCD_DrawBmp32(0, 440,40, 156, (uint8_t *)acLOGO);                //下菜单
       

       

回复

使用道具 举报

0

主题

5

回帖

5

积分

新手上路

积分
5
发表于 2021-6-26 17:25:31 | 显示全部楼层
/* ********************************************************************************************************* *        函 数 名: HardInfo *        功能说明: 自动检测硬件 *        形    参: 无 *        返 回 值: 无 ********************************************************************************************************* */ void HardInfo(void) {                  FONT_T tFont24,tFont32,tFont40, tFont48;        /* 定义一个字体结构体变量,用于设置字体参数 */                          /* 设置字体参数 */         {         tFont24.FontCode = FC_ST_24;            /* 字体代码 32点阵 */         tFont24.FrontColor = CL_WHITE;                /* 字体颜色 */         tFont24.BackColor = CL_MASK;            /* 文字背景颜色 */         tFont24.Space = 0;                                        /* 文字间距,单位 = 像素 */                                   tFont32.FontCode = FC_ST_32;            /* 字体代码 32点阵 */         tFont32.FrontColor = CL_WHITE;                /* 字体颜色 */         tFont32.BackColor = CL_MASK;            /* 文字背景颜色 */         tFont32.Space = 0;                                        /* 文字间距,单位 = 像素 */                          tFont40.FontCode = FC_ST_40;        /* 字体代码 32点阵 */         tFont40.FrontColor = CL_WHITE;                /* 字体颜色 0 或 1 */         tFont40.BackColor = CL_MASK;                /* 文字背景颜色 0 或 1 */         tFont40.Space = 0;                        /* 文字间距,单位 = 像素 */                          tFont48.FontCode = FC_ST_48;        /* 字体代码 32点阵 */         tFont48.FrontColor = CL_WHITE;                /* 字体颜色 0 或 1 */         tFont48.BackColor = CL_MASK;                /* 文字背景颜色 0 或 1 */         tFont48.Space = 0;                        /* 文字间距,单位 = 像素 */                   }                           //        LCDH7_FillRect(0, 0, 70, 800,CL_GREY4);         ////        LCD_DrawBmp32(45, 20, 40, 156, (uint8_t *)acLOGO); //        LCD_DispStr(90,20,"航天润普",&tFont32); //                 //        LCDH7_FillRect(0, 70, 410, 800,CL_BLUE);                  LCD_DispStr(90, 100, "01", &tFont40);         LCD_DispStr(90, 200, "HT-211", &tFont48);                 LCD_DispStr(235,200,"多功能存储介质销毁机",&tFont48);          //        LCDH7_FillRect(0, 410, 70, 800,CL_GREY1);         LCD_DispStr(50,433,"北京航天润普科技发展有限公司",&tFont24);         LCD_DispStr(500, 433, "400-666-7018", &tFont24);          //        LCD_DrawBmp32(0, 440,40, 156, (uint8_t *)acLOGO);                //下菜单                  
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-8 23:25 , Processed in 0.395491 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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