硬汉嵌入式论坛

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

[emWin教程入门篇] 【emWin实战教程V2.0】第22章     C文件格式的汉字生成和实现

[复制链接]

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
发表于 2017-1-17 16:52:51 | 显示全部楼层 |阅读模式
完整65章+12章附件教程下载地址:
http://www.armbbs.cn/forum.php?mod=viewthread&tid=19834




第22章     C文件格式的汉字生成和实现(Unicode编码)


    本章节主要为大家讲解官方的字体生成软件FontCvt的使用方法,使用此软件可以生成C文件格式的汉字全字库,也可以生成C文件格式的小字库,所谓小字库就是需要显示什么汉字就仅生成这些汉字。
   FontCvt全称FontConverter。
    22.1 初学者重要提示
    22.2  使用FontCvt生成字库C文件的方法
     22.3 C文件格式汉字的使用方法
    22..4生成的是Unicode编码字体,而使用时为什么是UTF-8
    22.5 MDK4.74,MDK5.21a和IAR7.5的UTF-8编码问题
   22.6 实验例程说明(RTOS)
    22.7 实验例程说明(裸机)
    22.8 总结
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2017-1-17 16:56:48 | 显示全部楼层
22.1   初学者重要提示

1、emWin官方提供的字体生成软件FontCvt不支持GB编码,所以只能使用FontCvt支持的Unicode编码。
2、这个字体小工具必须得使用STemWin软件包里面的,SEGGER官网下载的和MDK安装目录里面带的都是评估版
3、教程中让大家将要显示汉字的C文件转换为UTF-8编码,指的是将这个汉字所在的C文件转换为UTF-8编码,这点要切记,详情请看22.4小节的说明。
4、FontCvt的使用方法在emWin手册中有讲解,这个只有英文版手册进行了详细说明:
22.1.png
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2017-1-17 17:02:08 | 显示全部楼层
22.2使用FontCvt生成C文件格式小字库的方法


        所谓小字库就是需要显示什么汉字就仅生成什么汉字,下面为大家讲解如何生成C文件格式的小字库。这里以生成“安富莱电子”五个字为例进行说明。
第1步:在电脑桌面右击鼠标->新建->文本文档,即新建一个txt文本。
22.2.png

创建了文本文档后,输入“安富莱电子”五个字:
22.3.png

然后点击菜单选项文件->另存为:
22.4.png

弹出如下窗口:
22.5.png

此时桌面上就会生成一个名字为FontSong16的文本文档。
第2步:打开字体生成软件FontCvt,选择字体类型Standard,编码选择16bit Unicode
22.6.png

点击OK后,弹出如下窗口:
22.7.png

再点击确定后弹出FontCvt界面变成如下效果:
22.8.png

第3步:点击EDIT->Disable all characters
22.9.png

禁止所有字符后,字符区就全部变成灰色的了:
22.10.png

第4步:点击Edit->Read pattern file
22.11.png

5:加载文件FontSong16.txt
22.12.png

点击打开后,FontCvt软件的字符显示区中“安富莱电子”五个字的背景已经变成白色,下面是其中一个“莱”字的显示效果:
22.13.png

第6步:最后一步,点击File->Save As
22.14.png

弹出如下窗口:
22.15.png

至此就生成了我们所需要的16点阵字体。以同样的方法,我们再以此生成以下几种字体:
1. 字体类型Standard,16bitUnicode编码,32点阵,宋体,生成的文件名为FontSong32.c。
2. 字体类型Standard,16bitUnicode编码,72点阵,宋体,生成的文件名为FontSong72.c。
3. 字体类型Standard,16bitUnicode编码,144点阵,宋体,生成的文件名为FontSong144.c。
4. 字体类型Antialiased 4bpp(4倍抗锯齿),16bit Unicode编码,144点阵,宋体,生成的文件名FontSongA144.c
5. 字体类型Extended framed(扩展模式,带边框),16bit Unicode编码,144点阵,宋体,生成的文件名为FontSongExF144.c
6. 字体类型Extended antialiased 4bpp(扩展模式,4倍抗锯齿),16bit Unicode编码,144点阵,宋体,生成的文件名为FontSongExA144.c。
    通过小软件FontCvt,共生成了7种字体文件:
22.16.png


    有了这几个文件就可以进行相应字体的汉字显示了,由于仅生成了“安富莱电子”这五个字,所以仅支持这五个字的显示。接下来讲解这7种字体文件如何使用。
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2017-1-17 17:03:50 | 显示全部楼层
22.3 使用FontCvt生成C文件格式全字库的方法


    由于FontCvt生成C文件格式的全字库比较大,放在内部Flash非常占空间,所以基本不使用,不过生成方法要简单说明下。
第1步:打开字体生成软件FontCvt,选择字体类型Standard,编码选择16bit Unicode
22.17.png

点击OK后,弹出如下窗口:
22.18.png

再点击确定后弹出FontCvt界面变成如下效果:
22.19.png

第2步:点击File->Save As
22.20.png

弹出如下窗口:
22.21.png

此时,桌面上就生成了一个名为FontSong16.c的文件,实际在MDK工程中测试,此文件要占用1147060字节,即1MB多,所以实际项目中不推荐。
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2017-1-17 17:11:48 | 显示全部楼层
22.4C文件格式汉字的使用方法


    下面讲解22.2小节生成的7种字体C文件的使用方法,这里将MDK和IAR分别进行说明:

22.4.1   MDK编译器中使用C文件格式汉字的方法


第1步:将生成的7种字体文件添加到MDK工程目录里面,本章节配套的例子是将其放在User->fonts文件夹下
22.22.png


第2步:将生成的7种字体文件添加到MDK工程中
22.23.png

第3步:调用函数GUI_UC_SetEncodeUTF8()来使能UTF-8编码,这一步是必须的,切不可以忘了。
第4步:此时就可以使用这7种字体了,打开这7个字体文件,每个文件的开头都有一个extern的字体声明。
    extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSong16;
    extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSong32;
    extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSong72;
    extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSong144;
    extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSongA144;
    extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSongExA144;
    extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSongExF144;
    如果用户要在哪个源码文件里面使用这些字体,就把这些字体声明放在相应源文件的开头就行。使用方法,跟使用emWin自带的ASCII和ISO8859-1字体基本是一样的,唯一区别的地方是:调用FontCvt生成的字体时要加上取地址操作&。下面举一个完整的例子,代码在本章节配套例子的MainTask.c文件里面(对于初学者来说,对话框,按钮控件和文本控件还没有讲到,这里只是举个例子,会使用这些新生成的字体即可,后面会讲到这些控件):
  1. #include "MainTask.h"
  2. #include "includes.h"
  3. /*
  4. *********************************************************************************************************
  5. *                     调用外部字体声明,这个就是第4步中所说的问题
  6. *********************************************************************************************************
  7. */
  8. extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSong16;
  9. extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSong32;                                               
  10. extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSong72;
  11. extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSong144;
  12. extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSongA144;
  13. extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSongExA144;
  14. extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSongExF144;
  15. /*
  16. *********************************************************************************************************
  17. *                                      对话框资源列表
  18. *********************************************************************************************************
  19. */
  20. static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
  21.     { FRAMEWIN_CreateIndirect,  "armfly", 0,         0,  0,  800,480,FRAMEWIN_CF_MOVEABLE,0},
  22.     { BUTTON_CreateIndirect,    "安富莱我们我们",    GUI_ID_BUTTON0,          350,20,420,150,0,0},
  23.     { TEXT_CreateIndirect,      "安富莱电子",        GUI_ID_TEXT0,            5, 10, 300, 33, 0,0},
  24.     { TEXT_CreateIndirect,      "安富莱电子",        GUI_ID_TEXT1,            5, 40,250, 50, 0,0},
  25.     { TEXT_CreateIndirect,      "安富莱",            GUI_ID_TEXT2,            5, 100,360, 90, 0,0},
  26.     { TEXT_CreateIndirect,      "富",                GUI_ID_TEXT3,            5, 220,144, 144, 0,0},
  27.     { TEXT_CreateIndirect,      "富",                GUI_ID_TEXT4,            205, 230,144, 144, 0,0},
  28.     { TEXT_CreateIndirect,      "富",                GUI_ID_TEXT5,            405, 230,144, 144, 0,0},
  29.     { TEXT_CreateIndirect,      "富",                GUI_ID_TEXT6,            605, 230,144, 144, 0,0}
  30. };
  31. /*
  32. *********************************************************************************************************
  33. *    函 数 名: PaintDialog
  34. *    功能说明: 对话框重绘函数
  35. *    形    参:pMsg   消息指针
  36. *    返 回 值: 无
  37. *********************************************************************************************************
  38. */
  39. void PaintDialog(WM_MESSAGE   * pMsg)
  40. {
  41. //    WM_HWIN hWin = pMsg->hWin;
  42.    
  43. }
  44. /*
  45. *********************************************************************************************************
  46. *    函 数 名: 对话框初始化
  47. *    功能说明: 对话框初始化
  48. *    形    参: pMsg   消息指针
  49. *    返 回 值: 无
  50. *********************************************************************************************************
  51. */
  52. void InitDialog(WM_MESSAGE * pMsg)
  53. {
  54.     WM_HWIN hWin = pMsg->hWin;
  55.    
  56.     //
  57.     // 配置FrameWin
  58.     //
  59.     FRAMEWIN_SetFont(hWin,&GUI_Font32B_ASCII);
  60.     FRAMEWIN_SetTextAlign(hWin,GUI_TA_VCENTER|GUI_TA_CENTER);
  61.     FRAMEWIN_AddCloseButton(hWin, FRAMEWIN_BUTTON_RIGHT, 0);
  62.     FRAMEWIN_AddMaxButton(hWin, FRAMEWIN_BUTTON_RIGHT, 1);
  63.     FRAMEWIN_AddMinButton(hWin, FRAMEWIN_BUTTON_RIGHT, 2);
  64.     FRAMEWIN_SetTitleHeight(hWin,35);
  65.    
  66. /* 外部的7种字体在文件控件TEXT和按钮控件BUTTON中都使用了,具体调用方法如下,
  67. 跟使用emWin自带的字体是一样的。*/
  68.     //
  69.     // 按钮的字体是4倍抗锯齿,144点阵
  70.     //                                                               
  71.     BUTTON_SetFont(WM_GetDialogItem(hWin,GUI_ID_BUTTON0),&GUI_FontFontSongA144);                  
  72.    
  73.     //
  74.     // 分别用16点阵,32点阵和72点阵字体显示 安富莱电子 五个字。
  75.     //
  76.      TEXT_SetTextColor(WM_GetDialogItem(hWin,GUI_ID_TEXT0), GUI_RED);
  77.     TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT0),&GUI_FontFontSong16);
  78.      TEXT_SetTextColor(WM_GetDialogItem(hWin,GUI_ID_TEXT1), GUI_GREEN);
  79.      TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT1),&GUI_FontFontSong32);
  80.      TEXT_SetTextColor(WM_GetDialogItem(hWin,GUI_ID_TEXT2), GUI_BLUE);
  81.      TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT2),&GUI_FontFontSong72);
  82.     //
  83.     // 分别用144点阵汉字,144点阵的扩展模式且4倍抗锯齿汉字,144点阵的4倍抗锯齿汉字和
  84.      // 144点阵的扩展模式且带边框汉字。
  85.     //
  86.      TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT3),&GUI_FontFontSong144);
  87.      TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT4),&GUI_FontFontSongExA144);
  88.      TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT5),&GUI_FontFontSongA144);
  89.      TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT6),&GUI_FontFontSongExF144);
  90. }
  91. /*
  92. *********************************************************************************************************
  93. *    函 数 名: _cbCallback
  94. *    功能说明: 对话框回调函数
  95. *    形    参: pMsg   消息指针
  96. *    返 回 值: 无
  97. *********************************************************************************************************
  98. */
  99. static void _cbCallback(WM_MESSAGE * pMsg)
  100. {
  101.     int NCode, Id;
  102.     WM_HWIN hWin = pMsg->hWin;
  103.     switch (pMsg->MsgId)
  104.     {
  105.         case WM_PAINT:
  106.             PaintDialog(pMsg);
  107.             break;
  108.         
  109.         case WM_INIT_DIALOG:
  110.             InitDialog(pMsg);
  111.             break;
  112.         
  113.         case WM_KEY:
  114.             switch (((WM_KEY_INFO*)(pMsg->Data.p))->Key)
  115.             {
  116.                 case GUI_KEY_ESCAPE:
  117.                     GUI_EndDialog(hWin, 1);
  118.                     break;
  119.                 case GUI_KEY_ENTER:
  120.                     GUI_EndDialog(hWin, 0);
  121.                     break;
  122.             }
  123.             break;
  124.             
  125.         case WM_NOTIFY_PARENT:
  126.             Id = WM_GetId(pMsg->hWinSrc);
  127.             NCode = pMsg->Data.v;      
  128.             switch (Id)
  129.             {
  130.                 case GUI_ID_OK:
  131.                     if(NCode==WM_NOTIFICATION_RELEASED)
  132.                         GUI_EndDialog(hWin, 0);
  133.                     break;
  134.                      
  135.                 case GUI_ID_CANCEL:
  136.                     if(NCode==WM_NOTIFICATION_RELEASED)
  137.                         GUI_EndDialog(hWin, 0);
  138.                     break;
  139.             }
  140.             break;
  141.             
  142.         default:
  143.             WM_DefaultProc(pMsg);
  144.     }
  145. }
  146. /*
  147. *********************************************************************************************************
  148. *    函 数 名: MainTask
  149. *    功能说明: GUI主函数
  150. *    形    参: 无
  151. *    返 回 值: 无
  152. *********************************************************************************************************
  153. */
  154. void MainTask(void)
  155. {
  156.      /* 初始化 */
  157.      GUI_Init();
  158.       
  159.      WM_MULTIBUF_Enable(1);
  160.    
  161.      /* 使能UTF-8编码,这个是第3步中所说的问题,不必限制一定要放在这个位置,使用外部字体之前调用了即可 */   
  162.      GUI_UC_SetEncodeUTF8();
  163.    
  164.      /* 调用此函数会自动的刷新桌面窗口 */
  165.      WM_SetDesktopColor(GUI_WHITE);
  166.      /* 创建对话框 */
  167.      GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), &_cbCallback, 0, 0, 0);
  168.    
  169.      while(1)
  170.      {
  171.          GUI_Delay(10);
  172.      }
  173. }
复制代码
通过上面的代码就实现了这7种字体的显示,具体效果可以看实验例程说明。
第5步:这个是最重要的一步,很多初学者显示汉字失败就是因为这一步了。
    修改汉字显示所在的源文件,即MainTask.c文件为UTF-8编码,并不是修改FontCvt生成的C文件为UTF-8编码,因为FontCvt软件生成的C文件已经是UTF-8编码了。也就是说哪个文件用到这种汉字显示了,哪个文件就修改编码类型为UTF-8,只有这样,MDK才可以将这些汉字的编码识别出来,要不识别出来的汉字编码与FontCvt生成字体的编码类型不匹配,从而无法正确显示。
    修改编码类型也比较容易,使用电脑自带的记事本即可,将MainTask.C文件用记事本打开:
22.24.png

点击文件->另存为
22.25.png

弹出如下窗口:
22.26.png

点击保存后,会弹出如下窗口:
22.27.png

重新切换回MDK工程,也会弹出一个窗口:
22.28.png

这样MainTask.c文件就变成UTF-8编码了。此时就可以全编译工程并下载例子到开发板进行测试了。

22.4.2   IAR编译器中使用C文件格式汉字的方法


第1步:将生成的7种字体文件添加到IAR工程目录里面,本章节配套的例子是将其放在User->fonts文件夹下
22.29.png


第2步:将生成的7种字体文件添加到IAR工程中
    22.30.png

第3步:调用函数GUI_UC_SetEncodeUTF8()来使能UTF-8编码,这一步是必须的,切不可以忘了。
第4步:此时就可以使用这7种字体了,打开这7个字体文件,每个文件的开头都有一个extern的字体声明。
    extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSong16;
    extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSong32;
    extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSong72;
    extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSong144;
    extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSongA144;
    extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSongExA144;
    extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSongExF144;
    如果用户要在哪个源码文件里面使用这些字体,就把这些字体声明放在相应源文件的开头就行。使用方法,跟使用emWin自带的ASCII和ISO8859-1字体基本是一样的,唯一区别的地方是:调用FontCvt生成的字体时要加上取地址操作&。下面举一个完整的例子,代码在本章节配套例子的MainTask.c文件里面(对于初学者来说,对话框,按钮控件和文本控件还没有讲到,这里只是举个例子,会使用这些新生成的字体即可,后面会讲到这些控件):
  1. #include "MainTask.h"
  2. #include "includes.h"
  3. /*
  4. *********************************************************************************************************
  5. *                     调用外部字体声明,这个就是第4步中所说的问题
  6. *********************************************************************************************************
  7. */
  8. extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSong16;
  9. extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSong32;                                                
  10. extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSong72;
  11. extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSong144;
  12. extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSongA144;
  13. extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSongExA144;
  14. extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSongExF144;
  15. /*
  16. *********************************************************************************************************
  17. *                                      对话框资源列表
  18. *********************************************************************************************************
  19. */
  20. static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
  21.     { FRAMEWIN_CreateIndirect,  "armfly", 0,         0,  0,  800,480,FRAMEWIN_CF_MOVEABLE,0},
  22.     { BUTTON_CreateIndirect,    "安富莱我们我们",    GUI_ID_BUTTON0,          350,20,420,150,0,0},
  23.     { TEXT_CreateIndirect,      "安富莱电子",        GUI_ID_TEXT0,            5, 10, 300, 33, 0,0},
  24.     { TEXT_CreateIndirect,      "安富莱电子",        GUI_ID_TEXT1,            5, 40,250, 50, 0,0},
  25.     { TEXT_CreateIndirect,      "安富莱",            GUI_ID_TEXT2,            5, 100,360, 90, 0,0},
  26.     { TEXT_CreateIndirect,      "富",                GUI_ID_TEXT3,            5, 220,144, 144, 0,0},
  27.     { TEXT_CreateIndirect,      "富",                GUI_ID_TEXT4,            205, 230,144, 144, 0,0},
  28.     { TEXT_CreateIndirect,      "富",                GUI_ID_TEXT5,            405, 230,144, 144, 0,0},
  29.     { TEXT_CreateIndirect,      "富",                GUI_ID_TEXT6,            605, 230,144, 144, 0,0}
  30. };
  31. /*
  32. *********************************************************************************************************
  33. *    函 数 名: PaintDialog
  34. *    功能说明: 对话框重绘函数
  35. *    形    参:pMsg   消息指针
  36. *    返 回 值: 无
  37. *********************************************************************************************************
  38. */
  39. void PaintDialog(WM_MESSAGE   * pMsg)
  40. {
  41. //    WM_HWIN hWin = pMsg->hWin;
  42.    
  43. }
  44. /*
  45. *********************************************************************************************************
  46. *    函 数 名: 对话框初始化
  47. *    功能说明: 对话框初始化
  48. *    形    参: pMsg   消息指针
  49. *    返 回 值: 无
  50. *********************************************************************************************************
  51. */
  52. void InitDialog(WM_MESSAGE * pMsg)
  53. {
  54.     WM_HWIN hWin = pMsg->hWin;
  55.    
  56.     //
  57.     // 配置FrameWin
  58.     //
  59.     FRAMEWIN_SetFont(hWin,&GUI_Font32B_ASCII);
  60.     FRAMEWIN_SetTextAlign(hWin,GUI_TA_VCENTER|GUI_TA_CENTER);
  61.     FRAMEWIN_AddCloseButton(hWin, FRAMEWIN_BUTTON_RIGHT, 0);
  62.     FRAMEWIN_AddMaxButton(hWin, FRAMEWIN_BUTTON_RIGHT, 1);
  63.     FRAMEWIN_AddMinButton(hWin, FRAMEWIN_BUTTON_RIGHT, 2);
  64.     FRAMEWIN_SetTitleHeight(hWin,35);
  65.    
  66. /* 外部的7种字体在文件控件TEXT和按钮控件BUTTON中都使用了,具体调用方法如下,
  67. 跟使用emWin自带的字体是一样的。*/
  68.     //
  69.     // 按钮的字体是4倍抗锯齿,144点阵
  70.     //                                                               
  71.     BUTTON_SetFont(WM_GetDialogItem(hWin,GUI_ID_BUTTON0),&GUI_FontFontSongA144);                  
  72.    
  73.     //
  74.     // 分别用16点阵,32点阵和72点阵字体显示 安富莱电子 五个字。
  75.     //
  76.      TEXT_SetTextColor(WM_GetDialogItem(hWin,GUI_ID_TEXT0), GUI_RED);
  77.     TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT0),&GUI_FontFontSong16);
  78.      TEXT_SetTextColor(WM_GetDialogItem(hWin,GUI_ID_TEXT1), GUI_GREEN);
  79.      TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT1),&GUI_FontFontSong32);
  80.      TEXT_SetTextColor(WM_GetDialogItem(hWin,GUI_ID_TEXT2), GUI_BLUE);
  81.      TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT2),&GUI_FontFontSong72);
  82.     //
  83.     // 分别用144点阵汉字,144点阵的扩展模式且4倍抗锯齿汉字,144点阵的4倍抗锯齿汉字和
  84.      // 144点阵的扩展模式且带边框汉字。
  85.     //
  86.      TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT3),&GUI_FontFontSong144);
  87.      TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT4),&GUI_FontFontSongExA144);
  88.      TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT5),&GUI_FontFontSongA144);
  89.      TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT6),&GUI_FontFontSongExF144);
  90. }
  91. /*
  92. *********************************************************************************************************
  93. *    函 数 名: _cbCallback
  94. *    功能说明: 对话框回调函数
  95. *    形    参: pMsg   消息指针
  96. *    返 回 值: 无
  97. *********************************************************************************************************
  98. */
  99. static void _cbCallback(WM_MESSAGE * pMsg)
  100. {
  101.     int NCode, Id;
  102.     WM_HWIN hWin = pMsg->hWin;
  103.     switch (pMsg->MsgId)
  104.     {
  105.         case WM_PAINT:
  106.             PaintDialog(pMsg);
  107.             break;
  108.         
  109.         case WM_INIT_DIALOG:
  110.             InitDialog(pMsg);
  111.             break;
  112.         
  113.         case WM_KEY:
  114.             switch (((WM_KEY_INFO*)(pMsg->Data.p))->Key)
  115.             {
  116.                 case GUI_KEY_ESCAPE:
  117.                     GUI_EndDialog(hWin, 1);
  118.                     break;
  119.                 case GUI_KEY_ENTER:
  120.                     GUI_EndDialog(hWin, 0);
  121.                     break;
  122.             }
  123.             break;
  124.             
  125.         case WM_NOTIFY_PARENT:
  126.             Id = WM_GetId(pMsg->hWinSrc);
  127.             NCode = pMsg->Data.v;      
  128.             switch (Id)
  129.             {
  130.                 case GUI_ID_OK:
  131.                     if(NCode==WM_NOTIFICATION_RELEASED)
  132.                         GUI_EndDialog(hWin, 0);
  133.                     break;
  134.                      
  135.                 case GUI_ID_CANCEL:
  136.                     if(NCode==WM_NOTIFICATION_RELEASED)
  137.                         GUI_EndDialog(hWin, 0);
  138.                     break;
  139.             }
  140.             break;
  141.             
  142.         default:
  143.             WM_DefaultProc(pMsg);
  144.     }
  145. }
  146. /*
  147. *********************************************************************************************************
  148. *    函 数 名: MainTask
  149. *    功能说明: GUI主函数
  150. *    形    参: 无
  151. *    返 回 值: 无
  152. *********************************************************************************************************
  153. */
  154. void MainTask(void)
  155. {
  156.      /* 初始化 */
  157.      GUI_Init();
  158.       
  159.      WM_MULTIBUF_Enable(1);
  160.    
  161.      /* 使能UTF-8编码,这个是第3步中所说的问题,不必限制一定要放在这个位置,使用外部字体之前调用了即可 */   
  162.      GUI_UC_SetEncodeUTF8();
  163.    
  164.      /* 调用此函数会自动的刷新桌面窗口 */
  165.      WM_SetDesktopColor(GUI_WHITE);
  166.      /* 创建对话框 */
  167.      GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), &_cbCallback, 0, 0, 0);
  168.    
  169.      while(1)
  170.      {
  171.          GUI_Delay(10);
  172.      }
  173. }
复制代码
通过上面的代码就实现了这7种字体的显示,具体效果可以看实验例程说明。
第5步:这个是最重要的一步,很多初学者显示汉字失败就是因为这一步了。
    修改汉字显示所在的源文件,即MainTask.c文件为UTF-8编码,并不是修改FontCvt生成的C文件为UTF-8编码,因为FontCvt软件生成的C文件已经是UTF-8编码了。也就是说哪个文件用到这种汉字显示了,哪个文件就修改编码类型为UTF-8,只有这样,IAR将这些汉字的编码识别出来,要不识别出来的汉字编码与FontCvt生成字体的编码类型不匹配,从而无法正确显示。
    修改编码类型也比较容易,使用IAR的话,不要使用记事本来修改了(为什么不可以使用,在22.5小节有讲解),IAR编辑器支持编码类型的修改。

    IAR编码方面的小知识:
    默认情况下,IAR创建的工程都是System编码,也就是你的电脑系统是什么编码类型,使用IAR创建的.C和.H文件就是什么编码类型,一般大陆都是用的GBK编码,查看电脑系统编码类型可以通过:单击开始->所有程序->附件->命令提示符,打开命令提示符,输入chcp,然后点击键盘的回车键。
22.31.png
    这里的936就是代表GBK编码。而IAR的编码设置在这里,点击菜单Tools->Options,弹出如下窗口
22.32.png
默认的编码类型是System


    在IAR编译器中如何查看.C和.H文件的编码类型,又如何修改呢?查看编码类型可以任意打开一个文件,然后查看右下角。
22.33.png

这里打开的就是一个中文简体,GB2312编码,GBK向下是完全兼容GB2312的。修改单个.C和.H文件的编码类型也比较简单,这里我们需要修改MainTask.c文件的编码类型为UTF-8,直接在MainTask.c文件里面右击鼠标,选择CharacterEncoding->Convert to UTF-8。
22.34.png

设置后就可以看到右下角已经修改为UTF-8了。
22.35.png

此时就可以全编译工程并下载例子到开发板进行测试了。
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2017-1-17 17:13:47 | 显示全部楼层
22.5 生成的是Unicode编码字体,而使用时为什么是UTF-8


    初学者容易有这样的疑问,FontCvt软件生成的是Unicode编码的汉字,为什么emWin使用的时候不直接使用,还要多一次转换,即我们操作的时候是用的UTF-8编码字体,emWin的库函数会将这个编码转换成Unicode编码,然后从Unicode编码的字符集中获取相应的点阵数据。

    补充点小知识,方便大家理解:
    Unicode编码
    各个国家都有一套自己的编码标准,但谁也不懂谁的编码,谁也不支持别人的编码。基于此,国际组织决定着手解决这个问题,即重新弄一套包括了地球上所有文化、所有字母和符号的编码。将其命名为"UniversalMultiple-Octet Coded Character Set“(通用多八位编码字符集),简称 UCS,俗称Unicode。Unicode有两种编码UCS-2和UCS-4,其中UCS-2用两个字节编码,UCS-4用4个字节编码。
    UTF-8编码
    事实证明,对可以用ASCⅡ表示的字符使用UNICODE并不高效,因为UNICODE比ASCⅡ占用大一倍的空间,而对ASCⅡ来说高字节的0对他毫无用处。为了解决这个问题,就出现了一些中间格式的字符集,他们被称为通用转换格式,即UTF(Universal Transformation Format)。目前存在的UTF格式有:UTF-7,UTF-7.5,UTF-8,UTF-16以及 UTF-32。

    那么问题来了,emWin中为什么不直接使用Unicode编码,而要使用UTF-8。
1.  MDK和IAR的编辑器都不支持Unicode编码,仅支持UTF-8,笔者认为,这个是最主要的原因。
2.  UTF-8编码相对于Unicode编码的优势。
    (1) UTF-8表示与ASCII字符表示是一样的,只占一个字节,解决了Unicode浪费空间的情况。
    (2) 与CPU字节顺序无关, 可以在不同平台之间交流。
    (3) 容错能力高, 任何一个字节损坏后, 最多只会导致一个编码码位损失, 不会连锁错误。
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2017-1-17 17:15:07 | 显示全部楼层
22.6 MDK4.74,MDK5.21a和IAR7.5的UTF-8编码问题


    对于初学者来说,下面的问题是必看的,初次看可能不太理解,实际用这三个编译器操作了本章节配套的例子就有深刻的体会了。

22.6.1   MDK4.74的UTF-8说明


    MDK4.74是MDK4系列里面的最后一个版本了。
    一直以来都是将汉字显示所在的源文件使用记事本另存为UTF-8编码类型,特别注意,记事本另存的是UTF-8 带 BOM。且用户修改了这个文件的任何地方,MDK都会自动将这个文件存储为UTF-8编码无BOM。实际用Notepad++另存为UTF-8带BOM或者不带BOM,使用MDK4.74都可以正确显示汉字的。

22.6.2   MDK5.21a的UTF-8说明


    从MDK5.13版本开始,到今天最新的MDK5.21a,MDK5一直存在这个问题。对于初学者来说,这个问题要特别注意。
    对于MDK5.21a来说,也可以使用记事本将汉字显示所在的源文件另存为UTF-8编码类型,此时MDK5.21a是可以正确编译的。但是,用户一旦修改了这个文件的任何地方,直接编译或者保存后编译,MDK都会将这个文件存储为UTF-8编码无BOM,而MDK5.21a无法像MDK4.74那样带BOM或者不带BOM都能够识别,所以编译会出错,用户不得不再次用记事本另存编码类型。
       笔者认为这个是MDK5的bug。

22.6.3   IAR7.5的UTF-8说明


    对于IAR7.5来说,他仅支持UTF-8无BOM,修改的时候不要使用记事本,直接在汉字显示所在的源文件右击选择即可(在22.4.2小节已经讲解),或者用Notepad++选择UTF-8无BOM。

22.6.4   编码问题总结

1、IAR7.5仅支持UTF-8编码无BOM文件的汉字显示,带BOM的话,编译不通过。
2、MDK4.74对于UTF-8带BOM或者不带BOM都支持,但会将带BOM文件修改为不带BOM,两种编码形式显示汉字都不受影响。
3、MDK5.21a对于UTF-8带BOM或者不带BOM都支持,同样会将带BOM文件修改为不带BOM,修改后文件带有汉字会编译不通过。带BOM时,显示是不受影响的。所以用户每修改一次这个文件就得另存文件的编码类型为带BOM,笔者认为这个是MDK5的bug。

    名词解释:BOM
         BOM(Byte OrderMark),字节顺序标记,出现在文本文件头部,Unicode编码标准中用于标识文件是采用哪种格式的编码。UTF-8 不需要 BOM 来表明字节顺序,但可以用 BOM 来表明编码方式。字符 "Zero Width No-BreakSpace" 的 UTF-8 编码是 EF BBBF。所以如果接收者收到以 EF BB BF 开头的字节流,就知道这是 UTF-8编码了。Windows 就是使用 BOM 来标记文本文件的编码方式的。
         WINDOWS自带的记事本等软件,在保存一个以UTF-8编码的文件时,会在文件开始的地方插入三个不可见的字符(0xEF 0xBB0xBF,即BOM)。它是一串隐藏的字符,用于让记事本等编辑器识别这个文件是否以UTF-8编码。
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2017-1-17 17:19:27 | 显示全部楼层
22.7 实验例程说明(RTOS)


配套例子:
    V6-526_STemWin实验_C文件格式的汉字生成和实现,Unicode编码(RTOS)
实验目的:
    1.     学习emWin的C文件格式汉字的使用方法,Unicode编码。
    2.     emWin功能的实现在MainTask.c文件里面。
实验内容:
      1.     K1按键按下,串口打印任务执行情况(波特率115200,数据位8,奇偶校验位无,停止位1)。
      2.     K2按键按下,实现截图功能,将图片以BMP格式保存到SD卡中。
      3.     各个任务实现的功能如下:
              App Task Start   任务:实现按键和触摸扫描。
              App Task MspPro任务 :实现截图功能,将图片以BMP格式保存到SD卡中。
              App Task UserIF  任务:按键消息处理。
              App Task COM   任务:暂未使用。
App Task GUI    任务:GUI任务。
μCOS-III任务调试信息(按K1按键,串口打印):
22.36.png

STemWin界面显示效果:
    800*480分辨率界面效果。
22.37.png

STemWin动态内存配置:
    GUIConf.c文件中的配置如下:
  1. #define EX_SRAM   1/*1 used extern sram, 0 used internal sram */
  2. #if EX_SRAM
  3. #define GUI_NUMBYTES  (1024*1024*8)
  4. #else
  5. #define GUI_NUMBYTES  (100*1024)
  6. #endif
复制代码
    通过宏定义来配置使用内部SRAM还是外部的SDRAM做为emWin的动态内存,当配置:
#define EX_SRAM    1 表示使用外部SDRAM作为emWin动态内存,大小8MB。
#define EX_SRAM    0 表示使用内部SRAM作为emWin动态内存,大小100KB。
默认情况下,本教程配套的所有emWin例子都是用外部SDRAM作为emWin动态内存。
STemWin底层接口配置:
   LCDConf_Lin_Template.c文件中共12项emWin配置:
  1. /*
  2. **********************************************************************************************************
  3.                                           用户可以配置的选项
  4. **********************************************************************************************************
  5. */
  6. /* 0. 在官方代码的基础上再做优化,官方的部分函数效率低,耗内存, 0表示优化 */
  7. #define emWin_Optimize   0
  8. /*
  9.   1. 显示屏的物理分辨率,驱动已经做了显示屏自适应,支持4.3寸,5寸和7寸屏
  10.      这里填写自适应显示屏中的最大分辨率。
  11. */
  12. #define XSIZE_PHYS       800
  13. #define YSIZE_PHYS       480
  14. /* 2. 多缓冲 / 虚拟屏,多缓冲和虚拟屏不可同时使用,emWin不支持 */
  15. #define NUM_BUFFERS      3 /* 定义多缓冲个数,仅可以设置1,2和3,也就是最大支持三缓冲 */
  16. #define NUM_VSCREENS     1 /* 定义虚拟屏个数 */
  17. /* 3. 没有图层激活时,背景色设置, 暂时未用到 */
  18. #define BK_COLOR         GUI_DARKBLUE
  19. /*
  20.    4. 重定义图层数,对于STM32F429/439,用户可以选择一个图层或者两个图层,不支持三图层
  21.       (1). 设置GUI_NUM_LAYERS = 1时,即仅使用图层1时,默认触摸值是发送给图层1的。
  22.        (2). 设置GUI_NUM_LAYERS = 2时,即图层1和图层2都已经使能,此时图层2是顶层,
  23.             用户需要根据自己的使用情况设置如下两个地方。
  24.             a. 在bsp_touch.c文件中的函数TOUCH_InitHard里面设置参数State.Layer = 1,1就表示
  25.                给图层2发送触摸值。
  26.             b. 调用GUI_Init函数后,调用函数GUI_SelectLayer(1), 设置当前操作的是图层2。
  27. */
  28. #undef  GUI_NUM_LAYERS
  29. #define GUI_NUM_LAYERS    1
  30. /*
  31.    5. 设置图层1和图层2对应的显存地址
  32.       (1) EXT_SDRAM_ADDR 是SDRAM的首地址。
  33.       (2) LCD_LAYER0_FRAME_BUFFER 是图层1的显存地址。
  34.        (3) LCD_LAYER1_FRAME_BUFFER 是图层2的显存地址。
  35.        (4) 每个图层的显存大小比较考究,这里进行下简单的说明。
  36.            如果用户选择的颜色模式 = 32位色ARGB8888,显存的大小:
  37.            XSIZE_PHYS * YSIZE_PHYS * 4 * NUM_VSCREENS * NUM_BUFFERS
  38.          
  39.            颜色模式 = 24位色RGB888,显存的大小:
  40.            XSIZE_PHYS * YSIZE_PHYS * 3 * NUM_VSCREENS * NUM_BUFFERS
  41.          
  42.            颜色模式 = 16位色RGB566,ARGB1555, ARGB4444,AL88,那么显存的大小就是:
  43.            XSIZE_PHYS * YSIZE_PHYS * 2 * NUM_VSCREENS * NUM_BUFFERS
  44.            颜色模式 = 8位色L8,AL44,那么显存的大小就是:
  45.            XSIZE_PHYS * YSIZE_PHYS * 1 * NUM_VSCREENS * NUM_BUFFERS  
  46.      
  47.       这里为了方便起见,将开发板配套的16MB的SDRAM前8MB分配给LCD显存使用,后8MB用于emWin动态内存。
  48.        对于24位色,16位色,8位色,用户可以对其使能三缓冲,并且使能双图层。但是32位色也使能三缓冲和双
  49.        图层的话会超出8MB,所以用户根据自己的情况做显存和emWin动态内存的分配调整。
  50.          举一个例子,对于800*480分辨率的显示屏,使能32位色,三缓冲,那么最终一个图层需要的大小就是
  51.       800 * 480 * 4 * 3  = 4.394MB的空间,如果是双图层,已经超出8MB的分配范围。
  52.      
  53.       (5)为了方便起见,图层2的宏定义LCD_LAYER1_FRAME_BUFFER中的参数4是按照32位色设置的,如果用户的图层1
  54.          使用的是8位色,这里填数字1,如果是16位色,这里填2,如果是24位色,这里填3。
  55. */
  56. #define LCD_LAYER0_FRAME_BUFFER  EXT_SDRAM_ADDR
  57. #define LCD_LAYER1_FRAME_BUFFER  (LCD_LAYER0_FRAME_BUFFER + XSIZE_PHYS * YSIZE_PHYS * 4 * NUM_VSCREENS *
  58. NUM_BUFFERS)
  59. /*
  60.    6. STM32F429/439支持的颜色模式,所有模式都支持,用户可任意配置。
  61.       特别注意如下两个问题:
  62.        (1) 如果用户选择了ARGB8888或者RGB888模式,LCD闪烁比较厉害的话,
  63.            请降低LTDC的时钟大小,在文件bsp_tft_429.c的函数LCD_ConfigLTDC里面设置。
  64.            a. 一般800*480分辨率的显示屏,ARGB8888或者RGB888模式LTDC时钟选择10-20MHz即可。
  65.            b. 480*272分辨率的可以高些,取20MHz左右即可。
  66.        (2) 16位色或者8位色模式,LTDC的时钟频率一般可以比24位色或者32位色的高一倍。
  67. */
  68. #define _CM_ARGB8888      1
  69. #define _CM_RGB888        2
  70. #define _CM_RGB565        3
  71. #define _CM_ARGB1555      4
  72. #define _CM_ARGB4444      5
  73. #define _CM_L8            6
  74. #define _CM_AL44          7
  75. #define _CM_AL88          8
  76. /* 7. 配置图层1的颜色模式和分辨率大小 */
  77. #define COLOR_MODE_0      _CM_RGB565
  78. #define XSIZE_0           XSIZE_PHYS
  79. #define YSIZE_0           YSIZE_PHYS
  80. /* 8. 配置图层2的的颜色模式和分辨率大小 */
  81. #define COLOR_MODE_1      _CM_RGB565
  82. #define XSIZE_1           XSIZE_PHYS
  83. #define YSIZE_1           YSIZE_PHYS
  84. /* 9. 单图层情况下,根据用户选择的颜色模式可自动选择图层1的emWin的驱动和颜色模式 */
  85. #if   (COLOR_MODE_0 == _CM_ARGB8888)
  86.   #define COLOR_CONVERSION_0 GUICC_M8888I
  87.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_32
  88. #elif (COLOR_MODE_0 == _CM_RGB888)
  89.   #define COLOR_CONVERSION_0 GUICC_M888
  90.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_24
  91. #elif (COLOR_MODE_0 == _CM_RGB565)
  92.   #define COLOR_CONVERSION_0 GUICC_M565
  93.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_16
  94. #elif (COLOR_MODE_0 == _CM_ARGB1555)
  95.   #define COLOR_CONVERSION_0 GUICC_M1555I
  96.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_16
  97. #elif (COLOR_MODE_0 == _CM_ARGB4444)
  98.   #define COLOR_CONVERSION_0 GUICC_M4444I
  99.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_16
  100. #elif (COLOR_MODE_0 == _CM_L8)
  101.   #define COLOR_CONVERSION_0 GUICC_8666
  102.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_8
  103. #elif (COLOR_MODE_0 == _CM_AL44)
  104.   #define COLOR_CONVERSION_0 GUICC_1616I
  105.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_8
  106. #elif (COLOR_MODE_0 == _CM_AL88)
  107.   #define COLOR_CONVERSION_0 GUICC_88666I
  108.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_16
  109. #else
  110.   #error Illegal color mode 0!
  111. #endif
  112. /* 10. 双图层情况下,根据用户选择的颜色模式可自动选择图层2的emWin的驱动和颜色模式 */
  113. #if (GUI_NUM_LAYERS > 1)
  114. #if   (COLOR_MODE_1 == _CM_ARGB8888)
  115.   #define COLOR_CONVERSION_1 GUICC_M8888I
  116.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_32
  117. #elif (COLOR_MODE_1 == _CM_RGB888)
  118.   #define COLOR_CONVERSION_1 GUICC_M888
  119.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_24
  120. #elif (COLOR_MODE_1 == _CM_RGB565)
  121.   #define COLOR_CONVERSION_1 GUICC_M565
  122.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_16
  123. #elif (COLOR_MODE_1 == _CM_ARGB1555)
  124.   #define COLOR_CONVERSION_1 GUICC_M1555I
  125.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_16
  126. #elif (COLOR_MODE_1 == _CM_ARGB4444)
  127.   #define COLOR_CONVERSION_1 GUICC_M4444I
  128.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_16
  129. #elif (COLOR_MODE_1 == _CM_L8)
  130.   #define COLOR_CONVERSION_1 GUICC_8666
  131.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_8
  132. #elif (COLOR_MODE_1 == _CM_AL44)
  133.   #define COLOR_CONVERSION_1 GUICC_1616I
  134.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_8
  135. #elif (COLOR_MODE_1 == _CM_AL88)
  136.   #define COLOR_CONVERSION_1 GUICC_88666I
  137.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_16
  138. #else
  139.   #error Illegal color mode 1!
  140. #endif
  141. #else
  142. #undef XSIZE_0
  143. #undef YSIZE_0
  144. #define XSIZE_0       XSIZE_PHYS
  145. #define YSIZE_0       YSIZE_PHYS
  146. #endif
  147. /*11. 配置选项检测,防止配置错误或者某些选项没有配置 */
  148. #ifndef   XSIZE_PHYS
  149.   #error Physical X size of display is not defined!
  150. #endif
  151. #ifndef   YSIZE_PHYS
  152.   #error Physical Y size of display is not defined!
  153. #endif
  154. #ifndef   NUM_VSCREENS
  155.   #define NUM_VSCREENS 1
  156. #else
  157.   #if (NUM_VSCREENS <= 0)
  158.     #error At least one screeen needs to be defined!
  159.   #endif
  160. #endif
  161. #if (NUM_VSCREENS > 1) && (NUM_BUFFERS > 1)
  162.   #error Virtual screens and multiple buffers are not allowed!
  163. #endif
复制代码
    对于这12个配置选项,注释说明已经比较详细。默认情况下,本教程配套的emWin例子都是用的三缓冲,RGB565格式,且仅使用单图层。
程序设计:
任务栈大小分配:
    μCOS-III任务栈大小在os_cfg.h文件中配置:
        #define  APP_CFG_TASK_START_STK_SIZE                     512u
        #define  APP_CFG_TASK_MsgPro_STK_SIZE                    512u
        #define  APP_CFG_TASK_COM_STK_SIZE                       512u
        #define  APP_CFG_TASK_USER_IF_STK_SIZE                    512u
        #define  APP_CFG_TASK_GUI_STK_SIZE                        1024u
    任务栈大小的单位是4字节,那么每个任务的栈大小如下:
        App Task Start   任务:2048字节。
               App Task MspPro任务 :2048字节。
               App Task UserIF  任务:2048字节。
              App Task COM   任务:2048字节。
        App Task GUI    任务:4096字节。
系统栈大小分配:
    μCOS-III的系统栈大小在os_cfg_app.h文件中配置:
        #define  OS_CFG_ISR_STK_SIZE                      512u      
        系统栈大小的单位是4字节,那么这里就是配置系统栈大小为2KB。
μCOS-III初始化:
  1. /*
  2. *********************************************************************************************************
  3. *    函 数 名: main
  4. *    功能说明: 标准c程序入口。
  5. *    形    参: 无
  6. *    返 回 值: 无
  7. *********************************************************************************************************
  8. */
  9. int main(void)
  10. {
  11.     OS_ERR  err;
  12.    
  13.      /* 初始化uC/OS-III 内核 */
  14.     OSInit(&err);
  15.      /* 创建一个启动任务(也就是主任务)。启动任务会创建所有的应用程序任务 */
  16.      OSTaskCreate((OS_TCB       *)&AppTaskStartTCB,  /* 任务控制块地址 */           
  17.                  (CPU_CHAR     *)"App Task Start",  /* 任务名 */
  18.                  (OS_TASK_PTR   )AppTaskStart,      /* 启动任务函数地址 */
  19.                  (void         *)0,                 /* 传递给任务的参数 */
  20.                  (OS_PRIO       )APP_CFG_TASK_START_PRIO, /* 任务优先级 */
  21.                  (CPU_STK      *)&AppTaskStartStk[0],     /* 堆栈基地址 */
  22.                  (CPU_STK_SIZE  )APP_CFG_TASK_START_STK_SIZE / 10, /* 堆栈监测区,这里表示后10%作为监测区 */
  23.                  (CPU_STK_SIZE  )APP_CFG_TASK_START_STK_SIZE,      /* 堆栈空间大小 */
  24.                  (OS_MSG_QTY    )0,  /* 本任务支持接受的最大消息数 */
  25.                  (OS_TICK       )0,  /* 设置时间片 */
  26.                  (void         *)0,  /* 堆栈空间大小 */
  27.                  (OS_OPT        )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
  28.         
  29.                     /*  定义如下:
  30.                        OS_OPT_TASK_STK_CHK      使能检测任务栈,统计任务栈已用的和未用的
  31.                        OS_OPT_TASK_STK_CLR      在创建任务时,清零任务栈
  32.                        OS_OPT_TASK_SAVE_FP      如果CPU有浮点寄存器,则在任务切换时保存浮点寄存器的内容
  33.                     */
  34.                  (OS_ERR       *)&err);
  35.      /* 启动多任务系统,控制权交给uC/OS-III */
  36.     OSStart(&err);                                             
  37.    
  38.     (void)&err;
  39.    
  40.     return (0);
  41. }
复制代码
硬件外设初始化
     硬件外设的初始化是在bsp.c文件实现:
  1. /*
  2. *********************************************************************************************************
  3. *    函 数 名: bsp_Init
  4. *    功能说明: 初始化所有的硬件设备。该函数配置CPU寄存器和外设的寄存器并初始化一些全局变量。只需要调用一次
  5. *    形    参:无
  6. *    返 回 值: 无
  7. *********************************************************************************************************
  8. */
  9. void bsp_Init(void)
  10. {
  11.      /*
  12.          由于ST固件库的启动文件已经执行了CPU系统时钟的初始化,所以不必再次重复配置系统时钟。
  13.          启动文件配置了CPU主时钟频率、内部Flash访问速度和可选的外部SRAM FSMC初始化。
  14.          系统时钟缺省配置为168MHz,如果需要更改,可以修改 system_stm32f4xx.c 文件
  15.      */
  16.      /* 使能CRC 因为使用STemWin前必须要使能 */
  17.     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE);
  18.    
  19.      /* 优先级分组设置为4,可配置0-15级抢占式优先级,0级子优先级,即不存在子优先级。*/
  20.      NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
  21.    
  22.      SystemCoreClockUpdate();    /* 根据PLL配置更新系统时钟频率变量 SystemCoreClock */
  23.      bsp_InitUart();        /* 初始化串口 */
  24.      bsp_InitKey();         /* 初始化按键变量(必须在 bsp_InitTimer() 之前调用) */
  25.    
  26.      bsp_InitExtIO();       /* FMC总线上扩展了32位输出IO, 操作LED等外设必须初始化 */
  27.      bsp_InitLed();         /* 初始LED指示灯端口 */
  28.    
  29.      bsp_InitI2C();         /* 配置I2C总线 */
  30.    
  31.      bsp_InitExtSDRAM();   /* 初始化SDRAM */
  32.      bsp_DetectLcdType();  /* 检测触摸板和LCD面板型号, 结果存在全局变量 g_TouchType, g_LcdType */
  33.    
  34.      TOUCH_InitHard();    /* 初始化配置触摸芯片 */
  35.      LCD_ConfigLTDC();     /* 初始化配置LTDC */
  36.    
  37.      result = f_mount(&fs, "0:/", 0);     /* 挂载文件系统 */
  38. }
复制代码
五个μCOS-III任务的实现:
  1. /*
  2. *********************************************************************************************************
  3. *    函 数 名: AppTaskStart
  4. *    功能说明: 这是一个启动任务,在多任务系统启动后,必须初始化滴答计数器。本任务主要实现按键和触摸检测。
  5. *    形    参: p_arg 是在创建该任务时传递的形参
  6. *    返 回 值: 无
  7.      优 先 级: 2
  8. *********************************************************************************************************
  9. */
  10. static  void  AppTaskStart (void *p_arg)
  11. {
  12.      OS_ERR      err;
  13.      uint8_t  ucCount = 0;
  14.      uint8_t  ucCount1 = 0;
  15.    
  16.     /* 仅用于避免编译器告警,编译器不会产生任何目标代码 */  
  17.     (void)p_arg;
  18.    
  19.      /* BSP 初始化。 BSP = Board Support Package 板级支持包,可以理解为底层驱动。*/
  20.      CPU_Init();  /* 此函数要优先调用,因为外设驱动中使用的us和ms延迟是基于此函数的 */
  21.      bsp_Init();      
  22.      BSP_Tick_Init();
  23.    
  24. #if OS_CFG_STAT_TASK_EN > 0u
  25.      OSStatTaskCPUUsageInit(&err);  
  26. #endif
  27. #ifdef CPU_CFG_INT_DIS_MEAS_EN
  28.     CPU_IntDisMeasMaxCurReset();
  29. #endif
  30.         
  31.      /* 创建应用程序的任务 */
  32.      AppTaskCreate();
  33.    
  34.      /* 创建任务通信 */
  35.      AppObjCreate();
  36.    
  37.     while(1)
  38.     {
  39.          /* 1ms一次触摸扫描,电阻触摸屏 */
  40.          if(g_tTP.Enable == 1)
  41.          {
  42.               TOUCH_Scan();
  43.             
  44.               /* 按键扫描 */
  45.               ucCount++;
  46.               if(ucCount == 10)
  47.               {
  48.                    ucCount = 0;
  49.                    bsp_KeyScan();
  50.               }
  51.              OSTimeDly(1, OS_OPT_TIME_DLY, &err);         
  52.          }
  53.         
  54.          /* 20ms一次触摸扫描,电容触摸屏GT811
  55.             GT811取20ms比较稳定,取10ms偶尔会有跳动。
  56.          */
  57.          if(g_GT811.Enable == 1)
  58.          {
  59.               bsp_KeyScan();
  60.               ucCount1++;
  61.               if(ucCount1 == 2)
  62.               {
  63.                    ucCount1 = 0;
  64.                    GT811_OnePiontScan();
  65.               }
  66.              OSTimeDly(10, OS_OPT_TIME_DLY, &err);     
  67.          }
  68.         
  69.          /* 10ms一次触摸扫描,电容触摸屏FT5X06 */
  70.          if(g_tFT5X06.Enable == 1)
  71.          {
  72.               bsp_KeyScan();
  73.               FT5X06_OnePiontScan();
  74.              OSTimeDly(10, OS_OPT_TIME_DLY, &err);
  75.          }
  76.     }   
  77. }
  78. /*
  79. *********************************************************************************************************
  80. *    函 数 名: AppTaskMsgPro
  81. *    功能说明: 实现截图功能,将图片以BMP格式保存到SD卡中
  82. *    形    参: p_arg 是在创建该任务时传递的形参
  83. *    返 回 值: 无
  84.      优 先 级: 3
  85. *********************************************************************************************************
  86. */
  87. static void AppTaskMsgPro(void *p_arg)
  88. {
  89.      uint32_t ulStart, ulEnd;
  90.      OS_ERR      err;
  91.      uint8_t       Pic_Name = 0;
  92.      char buf[20];
  93.      (void)p_arg;
  94.          
  95.      while(1)
  96.      {   
  97.           /* 等待获取信号量同步消息,接收到后执行串口打印 */
  98.          OSSemPend((OS_SEM *)&SEM_SYNCH,
  99.                      (OS_TICK )0,
  100.                      (OS_OPT  )OS_OPT_PEND_BLOCKING,
  101.                      (CPU_TS  )0,
  102.                      (OS_ERR *)&err);
  103.         
  104.          if(err == OS_ERR_NONE)
  105.          {   
  106.               sprintf(buf,"0:/PicSave/%d.bmp",Pic_Name);
  107.             
  108.               /* 记录截图前起始时间 */
  109.               ulStart = OSTimeGet(&err);
  110.             
  111.               /* 开启调度锁 */
  112.               OSSchedLock(&err);
  113.             
  114.               /* 如果SD卡中没有PicSave文件,会进行创建 */
  115.               result = f_mkdir("0:/PicSave");
  116.             
  117.               /* 创建截图 */
  118.               result = f_open(&file,buf, FA_WRITE|FA_CREATE_ALWAYS);
  119.             
  120.               /* 向SD卡绘制BMP图片 */
  121.               GUI_BMP_Serialize(_WriteByte2File, &file);
  122.             
  123.               /* 创建完成后关闭file */
  124.              result = f_close(&file);
  125.             
  126.               /* 开启调度锁 */
  127.               OSSchedUnlock(&err);
  128.             
  129.               /* 记录截图后时间并获取截图过程耗时 */
  130.               ulEnd = OSTimeGet(&err);
  131.               ulEnd -= ulStart;
  132.             
  133.               App_Printf("截图完成,耗时 = %dms\\r\\n", ulEnd);
  134.               Pic_Name++;      
  135.          }                                                                                                                  
  136.      }  
  137. }
  138. /*
  139. *********************************************************************************************************
  140. *    函 数 名: AppTaskUserIF
  141. *    功能说明: 按键消息处理
  142. *    形    参: p_arg 是在创建该任务时传递的形参
  143. *    返 回 值: 无
  144.      优 先 级: 4
  145. *********************************************************************************************************
  146. */
  147. static void AppTaskUserIF(void *p_arg)
  148. {
  149.      OS_ERR      err;
  150.      uint8_t  ucKeyCode;
  151.    
  152.      (void)p_arg;                /* 避免编译器报警 */
  153.    
  154.      while (1)
  155.      {      
  156.          ucKeyCode = bsp_GetKey();
  157.         
  158.          if (ucKeyCode != KEY_NONE)
  159.          {
  160.               switch (ucKeyCode)
  161.               {
  162.                    case KEY_DOWN_K1:             /* K1键按下 打印任务执行情况 */
  163.                        DispTaskInfo();        
  164.                        break;
  165.                   
  166.                    case KEY_DOWN_K2:             /* K2键按下 向消息队列发送数据 */
  167.                        OSSemPost((OS_SEM *)&SEM_SYNCH,
  168.                                   (OS_OPT  )OS_OPT_POST_1,
  169.                                   (OS_ERR *)&err);
  170.                        break;
  171.                   
  172.                    default:                     /* 其他的键值不处理 */
  173.                        break;
  174.               }
  175.          }
  176.         
  177.          OSTimeDly(20, OS_OPT_TIME_DLY, &err);
  178.      }
  179. }
  180. /*
  181. *********************************************************************************************************
  182. *    函 数 名: AppTaskCom
  183. *    功能说明: 暂未使用
  184. *    形    参: p_arg 是在创建该任务时传递的形参
  185. *    返 回 值: 无
  186.      优 先 级: 5
  187. *********************************************************************************************************
  188. */
  189. static void AppTaskCOM(void *p_arg)
  190. {
  191.      OS_ERR  err;      
  192.    
  193.      (void)p_arg;
  194.    
  195.      while(1)
  196.      {   
  197.          OSTimeDly(500, OS_OPT_TIME_DLY, &err);
  198.      }                                                                                                
  199. }
  200. /*
  201. *********************************************************************************************************
  202. *    函 数 名: AppTaskGUI
  203. *    功能说明: GUI任务,最低优先级                        
  204. *    形    参:p_arg 是在创建该任务时传递的形参
  205. *    返 回 值: 无
  206. *   优 先 级:OS_CFG_PRIO_MAX - 4u
  207. *********************************************************************************************************
  208. */
  209. static void AppTaskGUI(void *p_arg)
  210. {
  211.     (void)p_arg;       /* 避免编译器告警 */
  212.         
  213.      while (1)
  214.      {
  215.          MainTask();
  216.      }
  217. }
复制代码
emWin任务的具体实现(在MainTask.c文件里面):
  1. #include "MainTask.h"
  2. #include "includes.h"
  3. /*
  4. *********************************************************************************************************
  5. *                                      调用外部字体
  6. *********************************************************************************************************
  7. */
  8. extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSong16;
  9. extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSong32;                                               
  10. extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSong72;
  11. extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSong144;
  12. extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSongA144;
  13. extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSongExA144;
  14. extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSongExF144;
  15. /*
  16. *********************************************************************************************************
  17. *                                      对话框资源列表
  18. *********************************************************************************************************
  19. */
  20. static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
  21.     { FRAMEWIN_CreateIndirect,  "armfly",     0,     0,  0,  800,480,FRAMEWIN_CF_MOVEABLE,0},
  22.     { BUTTON_CreateIndirect,    "安富莱我们我们",    GUI_ID_BUTTON0,          350,20,420,150,0,0},
  23.     { TEXT_CreateIndirect,      "安富莱电子",        GUI_ID_TEXT0,            5, 10, 300, 33, 0,0},
  24.     { TEXT_CreateIndirect,      "安富莱电子",        GUI_ID_TEXT1,            5, 40,250, 50, 0,0},
  25.     { TEXT_CreateIndirect,      "安富莱",            GUI_ID_TEXT2,            5, 100,360, 90, 0,0},
  26.     { TEXT_CreateIndirect,      "富",                GUI_ID_TEXT3,            5, 220,144, 144, 0,0},
  27.     { TEXT_CreateIndirect,      "富",                GUI_ID_TEXT4,            205, 230,144, 144, 0,0},
  28.     { TEXT_CreateIndirect,      "富",                GUI_ID_TEXT5,            405, 230,144, 144, 0,0},
  29.     { TEXT_CreateIndirect,      "富",                GUI_ID_TEXT6,            605, 230,144, 144, 0,0}
  30. };
  31. /*
  32. *********************************************************************************************************
  33. *    函 数 名: PaintDialog
  34. *    功能说明: 对话框重绘函数
  35. *    形    参:pMsg   消息指针
  36. *    返 回 值: 无
  37. *********************************************************************************************************
  38. */
  39. void PaintDialog(WM_MESSAGE   * pMsg)
  40. {
  41. //    WM_HWIN hWin = pMsg->hWin;
  42.    
  43. }
  44. /*
  45. *********************************************************************************************************
  46. *    函 数 名: 对话框初始化
  47. *    功能说明: 对话框初始化
  48. *    形    参: pMsg   消息指针
  49. *    返 回 值: 无
  50. *********************************************************************************************************
  51. */
  52. void InitDialog(WM_MESSAGE * pMsg)
  53. {
  54.     WM_HWIN hWin = pMsg->hWin;
  55.    
  56.     //
  57.     // 配置FrameWin
  58.     //
  59.     FRAMEWIN_SetFont(hWin,&GUI_Font32B_ASCII);
  60.     FRAMEWIN_SetTextAlign(hWin,GUI_TA_VCENTER|GUI_TA_CENTER);
  61.     FRAMEWIN_AddCloseButton(hWin, FRAMEWIN_BUTTON_RIGHT, 0);
  62.     FRAMEWIN_AddMaxButton(hWin, FRAMEWIN_BUTTON_RIGHT, 1);
  63.     FRAMEWIN_AddMinButton(hWin, FRAMEWIN_BUTTON_RIGHT, 2);
  64.     FRAMEWIN_SetTitleHeight(hWin,35);
  65.    
  66.     //
  67.     // 按钮的字体是4倍抗锯齿,144点阵
  68.     //                                                               
  69.     BUTTON_SetFont(WM_GetDialogItem(hWin,GUI_ID_BUTTON0),&GUI_FontFontSongA144);                  
  70.    
  71.     //
  72.     // 分别用16点阵,32点阵和72点阵字体显示 安富莱电子 五个字。
  73.     //
  74.      TEXT_SetTextColor(WM_GetDialogItem(hWin,GUI_ID_TEXT0), GUI_RED);
  75.     TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT0),&GUI_FontFontSong16);
  76.      TEXT_SetTextColor(WM_GetDialogItem(hWin,GUI_ID_TEXT1), GUI_GREEN);
  77.      TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT1),&GUI_FontFontSong32);
  78.      TEXT_SetTextColor(WM_GetDialogItem(hWin,GUI_ID_TEXT2), GUI_BLUE);
  79.      TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT2),&GUI_FontFontSong72);
  80.     //
  81.     // 分别用144点阵汉字,144点阵的扩展模式且4倍抗锯齿汉字,144点阵的4倍抗锯齿汉字和
  82.      // 144点阵的扩展模式且带边框汉字。
  83.     //
  84.      TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT3),&GUI_FontFontSong144);
  85.      TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT4),&GUI_FontFontSongExA144);
  86.      TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT5),&GUI_FontFontSongA144);
  87.      TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT6),&GUI_FontFontSongExF144);
  88. }
  89. /*
  90. *********************************************************************************************************
  91. *    函 数 名: _cbCallback
  92. *    功能说明: 对话框回调函数
  93. *    形    参: pMsg   消息指针
  94. *    返 回 值: 无
  95. *********************************************************************************************************
  96. */
  97. static void _cbCallback(WM_MESSAGE * pMsg)
  98. {
  99.     int NCode, Id;
  100.     WM_HWIN hWin = pMsg->hWin;
  101.     switch (pMsg->MsgId)
  102.     {
  103.         case WM_PAINT:
  104.             PaintDialog(pMsg);
  105.             break;
  106.         
  107.         case WM_INIT_DIALOG:
  108.             InitDialog(pMsg);
  109.             break;
  110.         
  111.         case WM_KEY:
  112.             switch (((WM_KEY_INFO*)(pMsg->Data.p))->Key)
  113.             {
  114.                 case GUI_KEY_ESCAPE:
  115.                     GUI_EndDialog(hWin, 1);
  116.                     break;
  117.                 case GUI_KEY_ENTER:
  118.                     GUI_EndDialog(hWin, 0);
  119.                     break;
  120.             }
  121.             break;
  122.             
  123.         case WM_NOTIFY_PARENT:
  124.             Id = WM_GetId(pMsg->hWinSrc);
  125.             NCode = pMsg->Data.v;      
  126.             switch (Id)
  127.             {
  128.                 case GUI_ID_OK:
  129.                     if(NCode==WM_NOTIFICATION_RELEASED)
  130.                         GUI_EndDialog(hWin, 0);
  131.                     break;
  132.                      
  133.                 case GUI_ID_CANCEL:
  134.                     if(NCode==WM_NOTIFICATION_RELEASED)
  135.                         GUI_EndDialog(hWin, 0);
  136.                     break;
  137.             }
  138.             break;
  139.             
  140.         default:
  141.             WM_DefaultProc(pMsg);
  142.     }
  143. }
  144. /*
  145. *********************************************************************************************************
  146. *    函 数 名: MainTask
  147. *    功能说明: GUI主函数
  148. *    形    参: 无
  149. *    返 回 值: 无
  150. *********************************************************************************************************
  151. */
  152. void MainTask(void)
  153. {
  154.      /* 初始化 */
  155.      GUI_Init();
  156.       
  157.      /*
  158.       关于多缓冲和窗口内存设备的设置说明
  159.         1. 使能多缓冲是调用的如下函数,用户要在LCDConf_Lin_Template.c文件中配置了多缓冲,调用此函数才有效:
  160.            WM_MULTIBUF_Enable(1);
  161.         2. 窗口使能使用内存设备是调用函数:WM_SetCreateFlags(WM_CF_MEMDEV);
  162.         3. 如果emWin的配置多缓冲和窗口内存设备都支持,二选一即可,且务必优先选择使用多缓冲,实际使用
  163.            STM32F429BIT6 + 32位SDRAM + RGB565/RGB888平台测试,多缓冲可以有效的降低窗口移动或者滑动时的撕裂
  164.            感,并有效的提高流畅性,通过使能窗口使用内存设备是做不到的。
  165.         4. 所有emWin例子默认是开启三缓冲。
  166.      */
  167.      WM_MULTIBUF_Enable(1);
  168.    
  169.      /*
  170.        触摸校准函数默认是注释掉的,电阻屏需要校准,电容屏无需校准。如果用户需要校准电阻屏的话,执行
  171.         此函数即可,会将触摸校准参数保存到EEPROM里面,以后系统上电会自动从EEPROM里面加载。
  172.      */
  173.     //TOUCH_Calibration();
  174.      /* 使能UTF-8编码 */   
  175.      GUI_UC_SetEncodeUTF8();
  176.    
  177.      /* 调用此函数会自动的刷新桌面窗口 */
  178.      WM_SetDesktopColor(GUI_WHITE);
  179.      /* 创建对话框 */
  180.      GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), &_cbCallback, 0, 0, 0);
  181.    
  182.      while(1)
  183.      {
  184.          GUI_Delay(10);
  185.      }
  186. }
复制代码
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2017-1-17 17:22:14 | 显示全部楼层
22.8 实验例程说明(裸机)


配套例子:
    V6-527_STemWin实验_C文件格式的汉字生成和实现,Unicode编码(RTOS)
实验目的:
    1.     学习emWin的C文件格式汉字的使用方法,Unicode编码。
    2.     emWin功能的实现在MainTask.c文件里面。
STemWin界面显示效果:
    800*480分辨率界面效果。
22.38.png


STemWin动态内存配置:
    GUIConf.c文件中的配置如下:
  1. #define EX_SRAM   1/*1 used extern sram, 0 used internal sram */
  2. #if EX_SRAM
  3. #define GUI_NUMBYTES  (1024*1024*8)
  4. #else
  5. #define GUI_NUMBYTES  (100*1024)
  6. #endif
复制代码
   通过宏定义来配置使用内部SRAM还是外部的SDRAM做为emWin的动态内存,当配置:
#define EX_SRAM    1 表示使用外部SDRAM作为emWin动态内存,大小8MB。
#define EX_SRAM    0 表示使用内部SRAM作为emWin动态内存,大小100KB。
默认情况下,本教程配套的所有emWin例子都是用外部SDRAM作为emWin动态内存。
STemWin底层接口配置:
   LCDConf_Lin_Template.c文件中共12项emWin配置:
  1. /*
  2. **********************************************************************************************************
  3.                                           用户可以配置的选项
  4. **********************************************************************************************************
  5. */
  6. /* 0. 在官方代码的基础上再做优化,官方的部分函数效率低,耗内存, 0表示优化 */
  7. #define emWin_Optimize   0
  8. /*
  9.   1. 显示屏的物理分辨率,驱动已经做了显示屏自适应,支持4.3寸,5寸和7寸屏
  10.      这里填写自适应显示屏中的最大分辨率。
  11. */
  12. #define XSIZE_PHYS       800
  13. #define YSIZE_PHYS       480
  14. /* 2. 多缓冲 / 虚拟屏,多缓冲和虚拟屏不可同时使用,emWin不支持 */
  15. #define NUM_BUFFERS      3 /* 定义多缓冲个数,仅可以设置1,2和3,也就是最大支持三缓冲 */
  16. #define NUM_VSCREENS     1 /* 定义虚拟屏个数 */
  17. /* 3. 没有图层激活时,背景色设置, 暂时未用到 */
  18. #define BK_COLOR         GUI_DARKBLUE
  19. /*
  20.    4. 重定义图层数,对于STM32F429/439,用户可以选择一个图层或者两个图层,不支持三图层
  21.       (1). 设置GUI_NUM_LAYERS = 1时,即仅使用图层1时,默认触摸值是发送给图层1的。
  22.        (2). 设置GUI_NUM_LAYERS = 2时,即图层1和图层2都已经使能,此时图层2是顶层,
  23.             用户需要根据自己的使用情况设置如下两个地方。
  24.             a. 在bsp_touch.c文件中的函数TOUCH_InitHard里面设置参数State.Layer = 1,1就表示
  25.                给图层2发送触摸值。
  26.             b. 调用GUI_Init函数后,调用函数GUI_SelectLayer(1), 设置当前操作的是图层2。
  27. */
  28. #undef  GUI_NUM_LAYERS
  29. #define GUI_NUM_LAYERS    1
  30. /*
  31.    5. 设置图层1和图层2对应的显存地址
  32.       (1) EXT_SDRAM_ADDR 是SDRAM的首地址。
  33.       (2) LCD_LAYER0_FRAME_BUFFER 是图层1的显存地址。
  34.        (3) LCD_LAYER1_FRAME_BUFFER 是图层2的显存地址。
  35.        (4) 每个图层的显存大小比较考究,这里进行下简单的说明。
  36.            如果用户选择的颜色模式 = 32位色ARGB8888,显存的大小:
  37.            XSIZE_PHYS * YSIZE_PHYS * 4 * NUM_VSCREENS * NUM_BUFFERS
  38.          
  39.            颜色模式 = 24位色RGB888,显存的大小:
  40.            XSIZE_PHYS * YSIZE_PHYS * 3 * NUM_VSCREENS * NUM_BUFFERS
  41.          
  42.            颜色模式 = 16位色RGB566,ARGB1555, ARGB4444,AL88,那么显存的大小就是:
  43.            XSIZE_PHYS * YSIZE_PHYS * 2 * NUM_VSCREENS * NUM_BUFFERS
  44.            颜色模式 = 8位色L8,AL44,那么显存的大小就是:
  45.            XSIZE_PHYS * YSIZE_PHYS * 1 * NUM_VSCREENS * NUM_BUFFERS  
  46.      
  47.       这里为了方便起见,将开发板配套的16MB的SDRAM前8MB分配给LCD显存使用,后8MB用于emWin动态内存。
  48.        对于24位色,16位色,8位色,用户可以对其使能三缓冲,并且使能双图层。但是32位色也使能三缓冲和双
  49.        图层的话会超出8MB,所以用户根据自己的情况做显存和emWin动态内存的分配调整。
  50.          举一个例子,对于800*480分辨率的显示屏,使能32位色,三缓冲,那么最终一个图层需要的大小就是
  51.       800 * 480 * 4 * 3  = 4.394MB的空间,如果是双图层,已经超出8MB的分配范围。
  52.      
  53.       (5)为了方便起见,图层2的宏定义LCD_LAYER1_FRAME_BUFFER中的参数4是按照32位色设置的,如果用户的图层1
  54.          使用的是8位色,这里填数字1,如果是16位色,这里填2,如果是24位色,这里填3。
  55. */
  56. #define LCD_LAYER0_FRAME_BUFFER  EXT_SDRAM_ADDR
  57. #define LCD_LAYER1_FRAME_BUFFER  (LCD_LAYER0_FRAME_BUFFER + XSIZE_PHYS * YSIZE_PHYS * 4 * NUM_VSCREENS *
  58. NUM_BUFFERS)
  59. /*
  60.    6. STM32F429/439支持的颜色模式,所有模式都支持,用户可任意配置。
  61.       特别注意如下两个问题:
  62.        (1) 如果用户选择了ARGB8888或者RGB888模式,LCD闪烁比较厉害的话,
  63.            请降低LTDC的时钟大小,在文件bsp_tft_429.c的函数LCD_ConfigLTDC里面设置。
  64.            a. 一般800*480分辨率的显示屏,ARGB8888或者RGB888模式LTDC时钟选择10-20MHz即可。
  65.            b. 480*272分辨率的可以高些,取20MHz左右即可。
  66.        (2) 16位色或者8位色模式,LTDC的时钟频率一般可以比24位色或者32位色的高一倍。
  67. */
  68. #define _CM_ARGB8888      1
  69. #define _CM_RGB888        2
  70. #define _CM_RGB565        3
  71. #define _CM_ARGB1555      4
  72. #define _CM_ARGB4444      5
  73. #define _CM_L8            6
  74. #define _CM_AL44          7
  75. #define _CM_AL88          8
  76. /* 7. 配置图层1的颜色模式和分辨率大小 */
  77. #define COLOR_MODE_0      _CM_RGB565
  78. #define XSIZE_0           XSIZE_PHYS
  79. #define YSIZE_0           YSIZE_PHYS
  80. /* 8. 配置图层2的的颜色模式和分辨率大小 */
  81. #define COLOR_MODE_1      _CM_RGB565
  82. #define XSIZE_1           XSIZE_PHYS
  83. #define YSIZE_1           YSIZE_PHYS
  84. /* 9. 单图层情况下,根据用户选择的颜色模式可自动选择图层1的emWin的驱动和颜色模式 */
  85. #if   (COLOR_MODE_0 == _CM_ARGB8888)
  86.   #define COLOR_CONVERSION_0 GUICC_M8888I
  87.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_32
  88. #elif (COLOR_MODE_0 == _CM_RGB888)
  89.   #define COLOR_CONVERSION_0 GUICC_M888
  90.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_24
  91. #elif (COLOR_MODE_0 == _CM_RGB565)
  92.   #define COLOR_CONVERSION_0 GUICC_M565
  93.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_16
  94. #elif (COLOR_MODE_0 == _CM_ARGB1555)
  95.   #define COLOR_CONVERSION_0 GUICC_M1555I
  96.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_16
  97. #elif (COLOR_MODE_0 == _CM_ARGB4444)
  98.   #define COLOR_CONVERSION_0 GUICC_M4444I
  99.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_16
  100. #elif (COLOR_MODE_0 == _CM_L8)
  101.   #define COLOR_CONVERSION_0 GUICC_8666
  102.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_8
  103. #elif (COLOR_MODE_0 == _CM_AL44)
  104.   #define COLOR_CONVERSION_0 GUICC_1616I
  105.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_8
  106. #elif (COLOR_MODE_0 == _CM_AL88)
  107.   #define COLOR_CONVERSION_0 GUICC_88666I
  108.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_16
  109. #else
  110.   #error Illegal color mode 0!
  111. #endif
  112. /* 10. 双图层情况下,根据用户选择的颜色模式可自动选择图层2的emWin的驱动和颜色模式 */
  113. #if (GUI_NUM_LAYERS > 1)
  114. #if   (COLOR_MODE_1 == _CM_ARGB8888)
  115.   #define COLOR_CONVERSION_1 GUICC_M8888I
  116.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_32
  117. #elif (COLOR_MODE_1 == _CM_RGB888)
  118.   #define COLOR_CONVERSION_1 GUICC_M888
  119.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_24
  120. #elif (COLOR_MODE_1 == _CM_RGB565)
  121.   #define COLOR_CONVERSION_1 GUICC_M565
  122.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_16
  123. #elif (COLOR_MODE_1 == _CM_ARGB1555)
  124.   #define COLOR_CONVERSION_1 GUICC_M1555I
  125.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_16
  126. #elif (COLOR_MODE_1 == _CM_ARGB4444)
  127.   #define COLOR_CONVERSION_1 GUICC_M4444I
  128.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_16
  129. #elif (COLOR_MODE_1 == _CM_L8)
  130.   #define COLOR_CONVERSION_1 GUICC_8666
  131.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_8
  132. #elif (COLOR_MODE_1 == _CM_AL44)
  133.   #define COLOR_CONVERSION_1 GUICC_1616I
  134.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_8
  135. #elif (COLOR_MODE_1 == _CM_AL88)
  136.   #define COLOR_CONVERSION_1 GUICC_88666I
  137.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_16
  138. #else
  139.   #error Illegal color mode 1!
  140. #endif
  141. #else
  142. #undef XSIZE_0
  143. #undef YSIZE_0
  144. #define XSIZE_0       XSIZE_PHYS
  145. #define YSIZE_0       YSIZE_PHYS
  146. #endif
  147. /*11. 配置选项检测,防止配置错误或者某些选项没有配置 */
  148. #ifndef   XSIZE_PHYS
  149.   #error Physical X size of display is not defined!
  150. #endif
  151. #ifndef   YSIZE_PHYS
  152.   #error Physical Y size of display is not defined!
  153. #endif
  154. #ifndef   NUM_VSCREENS
  155.   #define NUM_VSCREENS 1
  156. #else
  157.   #if (NUM_VSCREENS <= 0)
  158.     #error At least one screeen needs to be defined!
  159.   #endif
  160. #endif
  161. #if (NUM_VSCREENS > 1) && (NUM_BUFFERS > 1)
  162.   #error Virtual screens and multiple buffers are not allowed!
  163. #endif
复制代码
    对于这12个配置选项,注释说明已经比较详细。默认情况下,本教程配套的emWin例子都是用的三缓冲,RGB565格式,且仅使用单图层。
程序设计:
栈大小分配:
    系统栈大小在startup_stm32f429_439xx.s文件中配置:
22.39.png

    栈大小的单位是字节,那么这里配置的系统栈大小就是8192字节。
主函数初始化:
  1. /*
  2. *********************************************************************************************************
  3. *    函 数 名: main
  4. *    功能说明: 标准c程序入口。
  5. *    形    参: 无
  6. *    返 回 值: 无
  7. *********************************************************************************************************
  8. */
  9. int main (void)
  10. {   
  11.      /* 初始化外设 */
  12.      bsp_Init();
  13.      /* 进入emWin主函数 */
  14.      MainTask();
  15. }
复制代码
硬件外设初始化
    硬件外设的初始化是在bsp.c文件实现:
  1. /*
  2. *********************************************************************************************************
  3. *    函 数 名: bsp_Init
  4. *    功能说明: 初始化所有的硬件设备。该函数配置CPU寄存器和外设的寄存器并初始化一些全局变量。只需要调用一次
  5. *    形    参:无
  6. *    返 回 值: 无
  7. *********************************************************************************************************
  8. */
  9. void bsp_Init(void)
  10. {
  11.      /*
  12.          由于ST固件库的启动文件已经执行了CPU系统时钟的初始化,所以不必再次重复配置系统时钟。
  13.          启动文件配置了CPU主时钟频率、内部Flash访问速度和可选的外部SRAM FSMC初始化。
  14.          系统时钟缺省配置为168MHz,如果需要更改,可以修改 system_stm32f4xx.c 文件
  15.      */
  16.      /* 使能CRC 因为使用STemWin前必须要使能 */
  17.     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE);
  18.    
  19.      /* 优先级分组设置为4,可配置0-15级抢占式优先级,0级子优先级,即不存在子优先级。*/
  20.      NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
  21.    
  22.      SystemCoreClockUpdate();    /* 根据PLL配置更新系统时钟频率变量 SystemCoreClock */
  23.      bsp_InitUart();        /* 初始化串口 */
  24.      bsp_InitKey();         /* 初始化按键变量(必须在 bsp_InitTimer() 之前调用) */
  25.    
  26.      bsp_InitExtIO();       /* FMC总线上扩展了32位输出IO, 操作LED等外设必须初始化 */
  27.      bsp_InitLed();         /* 初始LED指示灯端口 */
  28.    
  29.      bsp_InitI2C();         /* 配置I2C总线 */
  30.    
  31.      bsp_InitExtSDRAM();   /* 初始化SDRAM */
  32.      bsp_DetectLcdType();  /* 检测触摸板和LCD面板型号, 结果存在全局变量 g_TouchType, g_LcdType */
  33.    
  34.      TOUCH_InitHard();    /* 初始化配置触摸芯片 */
  35.      LCD_ConfigLTDC();     /* 初始化配置LTDC */
  36.    
  37.      result = f_mount(&fs, "0:/", 0);     /* 挂载文件系统 */
  38. }
复制代码
emWin功能的具体实现(在MainTask.c文件里面):
  1. #include "MainTask.h"
  2. #include "bsp.h"
  3. /*
  4. *********************************************************************************************************
  5. *                                      调用外部字体
  6. *********************************************************************************************************
  7. */
  8. extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSong16;
  9. extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSong32;                                               
  10. extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSong72;
  11. extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSong144;
  12. extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSongA144;
  13. extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSongExA144;
  14. extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSongExF144;
  15. /*
  16. *********************************************************************************************************
  17. *                                      对话框资源列表
  18. *********************************************************************************************************
  19. */
  20. static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
  21.     { FRAMEWIN_CreateIndirect,  "armfly",     0,     0,  0,  800,480,FRAMEWIN_CF_MOVEABLE,0},
  22.     { BUTTON_CreateIndirect,    "安富莱我们我们",    GUI_ID_BUTTON0,          350,20,420,150,0,0},
  23.     { TEXT_CreateIndirect,      "安富莱电子",        GUI_ID_TEXT0,            5, 10, 300, 33, 0,0},
  24.     { TEXT_CreateIndirect,      "安富莱电子",        GUI_ID_TEXT1,            5, 40,250, 50, 0,0},
  25.     { TEXT_CreateIndirect,      "安富莱",            GUI_ID_TEXT2,            5, 100,360, 90, 0,0},
  26.     { TEXT_CreateIndirect,      "富",                GUI_ID_TEXT3,            5, 220,144, 144, 0,0},
  27.     { TEXT_CreateIndirect,      "富",                GUI_ID_TEXT4,            205, 230,144, 144, 0,0},
  28.     { TEXT_CreateIndirect,      "富",                GUI_ID_TEXT5,            405, 230,144, 144, 0,0},
  29.     { TEXT_CreateIndirect,      "富",                GUI_ID_TEXT6,            605, 230,144, 144, 0,0}
  30. };
  31. /*
  32. *********************************************************************************************************
  33. *    函 数 名: PaintDialog
  34. *    功能说明: 对话框重绘函数
  35. *    形    参:pMsg   消息指针
  36. *    返 回 值: 无
  37. *********************************************************************************************************
  38. */
  39. void PaintDialog(WM_MESSAGE   * pMsg)
  40. {
  41. //    WM_HWIN hWin = pMsg->hWin;
  42.    
  43. }
  44. /*
  45. *********************************************************************************************************
  46. *    函 数 名: 对话框初始化
  47. *    功能说明: 对话框初始化
  48. *    形    参: pMsg   消息指针
  49. *    返 回 值: 无
  50. *********************************************************************************************************
  51. */
  52. void InitDialog(WM_MESSAGE * pMsg)
  53. {
  54.     WM_HWIN hWin = pMsg->hWin;
  55.    
  56.     //
  57.     // 配置FrameWin
  58.     //
  59.     FRAMEWIN_SetFont(hWin,&GUI_Font32B_ASCII);
  60.     FRAMEWIN_SetTextAlign(hWin,GUI_TA_VCENTER|GUI_TA_CENTER);
  61.     FRAMEWIN_AddCloseButton(hWin, FRAMEWIN_BUTTON_RIGHT, 0);
  62.     FRAMEWIN_AddMaxButton(hWin, FRAMEWIN_BUTTON_RIGHT, 1);
  63.     FRAMEWIN_AddMinButton(hWin, FRAMEWIN_BUTTON_RIGHT, 2);
  64.     FRAMEWIN_SetTitleHeight(hWin,35);
  65.    
  66.     //
  67.     // 按钮的字体是4倍抗锯齿,144点阵
  68.     //                                                               
  69.     BUTTON_SetFont(WM_GetDialogItem(hWin,GUI_ID_BUTTON0),&GUI_FontFontSongA144);                    
  70.    
  71.     //
  72.     // 分别用16点阵,32点阵和72点阵字体显示 安富莱电子 五个字。
  73.     //
  74.      TEXT_SetTextColor(WM_GetDialogItem(hWin,GUI_ID_TEXT0), GUI_RED);
  75.     TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT0),&GUI_FontFontSong16);
  76.      TEXT_SetTextColor(WM_GetDialogItem(hWin,GUI_ID_TEXT1), GUI_GREEN);
  77.      TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT1),&GUI_FontFontSong32);
  78.      TEXT_SetTextColor(WM_GetDialogItem(hWin,GUI_ID_TEXT2), GUI_BLUE);
  79.      TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT2),&GUI_FontFontSong72);
  80.     //
  81.     // 分别用144点阵汉字,144点阵的扩展模式且4倍抗锯齿汉字,144点阵的4倍抗锯齿汉字和
  82.      // 144点阵的扩展模式且带边框汉字。
  83.     //
  84.      TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT3),&GUI_FontFontSong144);
  85.      TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT4),&GUI_FontFontSongExA144);
  86.      TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT5),&GUI_FontFontSongA144);
  87.      TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT6),&GUI_FontFontSongExF144);
  88. }
  89. /*
  90. *********************************************************************************************************
  91. *    函 数 名: _cbCallback
  92. *    功能说明: 对话框回调函数
  93. *    形    参: pMsg   消息指针
  94. *    返 回 值: 无
  95. *********************************************************************************************************
  96. */
  97. static void _cbCallback(WM_MESSAGE * pMsg)
  98. {
  99.     int NCode, Id;
  100.     WM_HWIN hWin = pMsg->hWin;
  101.     switch (pMsg->MsgId)
  102.     {
  103.         case WM_PAINT:
  104.             PaintDialog(pMsg);
  105.             break;
  106.         
  107.         case WM_INIT_DIALOG:
  108.             InitDialog(pMsg);
  109.             break;
  110.         
  111.         case WM_KEY:
  112.             switch (((WM_KEY_INFO*)(pMsg->Data.p))->Key)
  113.             {
  114.                 case GUI_KEY_ESCAPE:
  115.                     GUI_EndDialog(hWin, 1);
  116.                     break;
  117.                 case GUI_KEY_ENTER:
  118.                     GUI_EndDialog(hWin, 0);
  119.                     break;
  120.             }
  121.             break;
  122.             
  123.         case WM_NOTIFY_PARENT:
  124.             Id = WM_GetId(pMsg->hWinSrc);
  125.             NCode = pMsg->Data.v;      
  126.             switch (Id)
  127.             {
  128.                 case GUI_ID_OK:
  129.                     if(NCode==WM_NOTIFICATION_RELEASED)
  130.                         GUI_EndDialog(hWin, 0);
  131.                     break;
  132.                      
  133.                 case GUI_ID_CANCEL:
  134.                     if(NCode==WM_NOTIFICATION_RELEASED)
  135.                         GUI_EndDialog(hWin, 0);
  136.                     break;
  137.             }
  138.             break;
  139.             
  140.         default:
  141.             WM_DefaultProc(pMsg);
  142.     }
  143. }
  144. /*
  145. *********************************************************************************************************
  146. *    函 数 名: MainTask
  147. *    功能说明: GUI主函数
  148. *    形    参: 无
  149. *    返 回 值: 无
  150. *********************************************************************************************************
  151. */
  152. void MainTask(void)
  153. {
  154.      /* 初始化 */
  155.      GUI_Init();
  156.       
  157.      /*
  158.       关于多缓冲和窗口内存设备的设置说明
  159.         1. 使能多缓冲是调用的如下函数,用户要在LCDConf_Lin_Template.c文件中配置了多缓冲,调用此函数才有效:
  160.            WM_MULTIBUF_Enable(1);
  161.         2. 窗口使能使用内存设备是调用函数:WM_SetCreateFlags(WM_CF_MEMDEV);
  162.         3. 如果emWin的配置多缓冲和窗口内存设备都支持,二选一即可,且务必优先选择使用多缓冲,实际使用
  163.            STM32F429BIT6 + 32位SDRAM + RGB565/RGB888平台测试,多缓冲可以有效的降低窗口移动或者滑动时的撕裂
  164.            感,并有效的提高流畅性,通过使能窗口使用内存设备是做不到的。
  165.         4. 所有emWin例子默认是开启三缓冲。
  166.      */
  167.      WM_MULTIBUF_Enable(1);
  168.    
  169.      /*
  170.        触摸校准函数默认是注释掉的,电阻屏需要校准,电容屏无需校准。如果用户需要校准电阻屏的话,执行
  171.         此函数即可,会将触摸校准参数保存到EEPROM里面,以后系统上电会自动从EEPROM里面加载。
  172.      */
  173.     //TOUCH_Calibration();
  174.      /* 使能UTF-8编码 */   
  175.      GUI_UC_SetEncodeUTF8();
  176.    
  177.      /* 调用此函数会自动的刷新桌面窗口 */
  178.      WM_SetDesktopColor(GUI_WHITE);
  179.      /* 创建对话框 */
  180.      GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), &_cbCallback, 0, 0, 0);
  181.    
  182.      while(1)
  183.      {
  184.          GUI_Delay(10);
  185.      }
  186. }
复制代码
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2017-1-17 17:22:37 | 显示全部楼层
22.9总结


    本章节讲解的内容较多,特别是涉及到UTF-8编码的问题时,望初学者务必将其掌握,有了本章节的基础,后面几个章节的汉字显示操作起来将更加的得心应手。
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

6

主题

231

回帖

249

积分

高级会员

积分
249
发表于 2017-1-18 14:56:36 | 显示全部楼层
UTF8只是对ASCII字符友好,对双字节的DBCS字符是非常恶劣的,一个中文用UTF8格式储存的时候变成3个字节。
UTF8的一种作用是避免了一些C语言写的程序由于不识别UNICODE码把字符串折断(遇到零认为字符串结束),它是一种用于传输的编码格式。
回复

使用道具 举报

6

主题

231

回帖

249

积分

高级会员

积分
249
发表于 2017-1-18 14:57:57 | 显示全部楼层
目前大多数的嵌入式开发工具仍然不支持UNICODE,这多少都有点跟不上潮流。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-16 19:44 , Processed in 0.230890 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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