×
单片机 > 单片机程序设计 > 详情

为OLED屏增加GUI支持7:综合实例

发布时间:2020-06-06 发布时间:
|

环境:

主机:WIN10

开发环境:MDK5.13

MCU:STM32F103


说明:

前面的文章已经介绍了本GUI的基本功能,目前有的控件有文本控件,图片控件,以及进度条控件,这是我项目中所需要的,读者可以参考这些代码增加自己所需的控件。本文展示一个综合实例,显示一个完整的界面。文中用到调度框架pt-thread。


实现效果:



源代码:

gui.h:gui头文件


  1. /** 

  2. * Copyright (c), 2015-2025 

  3. * @file gui.h 

  4. * @brief gui头文件 

  5. * @author jdh 

  6. * @version 1.0 

  7. * @date 2015/9/6 

  8. */  

  9.   

  10. #ifndef _GUI_H_  

  11. #define _GUI_H_  

  12.   

  13. /********************************************************************* 

  14. *                           头文件 

  15. **********************************************************************/  

  16.   

  17. #include "gui_interface.h"  

  18. #include "gui_text_lib.h"  

  19. #include "gui_2d_lib.h"  

  20. #include "gui_widget_text.h"  

  21. #include "gui_widget_image.h"  

  22. #include "gui_widget_progbar.h"  

  23.   

  24. /********************************************************************* 

  25. *                           函数 

  26. **********************************************************************/  

  27.   

  28. /** 

  29. * @brief 初始化gui 

  30. */  

  31.   

  32. void gui_init(void);  

  33.   

  34. /** 

  35. * @brief 销毁控件 

  36. * @param handle:控件句柄 

  37. */  

  38.   

  39. void gui_widget_delete(void *handle);  

  40.   

  41. #endif  




gui.c:gui主文件


  1. /** 

  2. * Copyright (c), 2015-2025 

  3. * @file gui.c 

  4. * @brief gui主文件 

  5. * @author jdh 

  6. * @date 2015/9/6 

  7. */  

  8.   

  9. /********************************************************************* 

  10. *                           头文件 

  11. **********************************************************************/  

  12.   

  13. #include "gui.h"  

  14. #include "stdlib.h"  

  15.   

  16. /********************************************************************* 

  17. *                           函数 

  18. **********************************************************************/  

  19.   

  20. /** 

  21. * @brief 初始化gui 

  22. */  

  23.   

  24. void gui_init(void)  

  25. {  

  26. //  //初始化字库  

  27. //  font_init();  

  28. }  

  29.   

  30. /** 

  31. * @brief 销毁控件 

  32. * @param handle:控件句柄 

  33. */  

  34.   

  35. void gui_widget_delete(void *handle)  

  36. {  

  37.     free(handle);  

  38.     handle = (void *)0;  

  39. }  




实例:

gui_mode_fence.h


  1. /** 

  2. * Copyright (c), 2015-2025 

  3. * @file gui_mode_fence.h 

  4. * @brief 围栏界面模块头文件 

  5. * @author jdh 

  6. * @date 2015/11/22 

  7. */  

  8.   

  9. #ifndef _GUI_MODE_FENCE_H_  

  10. #define _GUI_MODE_FENCE_H_  

  11.   

  12. /********************************************************************* 

  13. *                           头文件 

  14. **********************************************************************/  

  15.   

  16. #include "world.h"   

  17.   

  18. /********************************************************************* 

  19. *                           宏定义 

  20. **********************************************************************/  

  21.   

  22. /** 

  23. * @brief 工作间隔,单位:ms 

  24. */  

  25.   

  26. #define INTERVAL_GUI_MODE_FENCE         100    

  27.   

  28. /********************************************************************* 

  29. *                           函数 

  30. **********************************************************************/  

  31.   

  32. /** 

  33. * @brief 模块载入 

  34. */  

  35.   

  36. void gui_mode_fence_load(void);  

  37.   

  38. /** 

  39. * @brief 模块运行 

  40. */  

  41.   

  42. void gui_mode_fence_run(void);  

  43.   

  44. /** 

  45. * @brief 设置显示状态 

  46. * @param enable:0:关闭显示,1:打开显示 

  47. */  

  48.   

  49. void gui_mode_fence_show(uint8_t enable);  

  50.   

  51. /** 

  52. * @brief 得到当前的显示状态 

  53. * @retval 0:关闭显示,1:打开显示 

  54. */  

  55.   

  56. uint8_t gui_mode_fence_get_show(void);  

  57.   

  58. #endif  




gui_mode_fence.c


  1. /** 

  2. * Copyright (c), 2015-2025 

  3. * @file gui_mode_fence.c 

  4. * @brief 围栏模式界面模块主文件 

  5. * @author jdh 

  6. * @date 2015/11/22 

  7. * @update 2015/12/11 

  8. */  

  9.   

  10. /********************************************************************* 

  11. *                           头文件 

  12. **********************************************************************/  

  13.   

  14. #include "gui_mode_fence.h"  

  15. #include "status_bar.h"  

  16. #include "gui_schedule.h"  

  17. #include "para_manage.h"  

  18. #include "slave_manage.h"  

  19.   

  20. /********************************************************************* 

  21. *                           数据结构 

  22. **********************************************************************/  

  23.   

  24. /** 

  25. * @brief 按键状态 

  26. */  

  27.   

  28. struct _Key_State  

  29. {  

  30.     uint8_t ok;  

  31.     uint8_t cancel;  

  32.     uint8_t left;  

  33.     uint8_t right;  

  34. };  

  35.   

  36. /********************************************************************* 

  37. *                           静态变量 

  38. **********************************************************************/  

  39.   

  40. /** 

  41. * @brief pt任务变量 

  42. */  

  43.   

  44. static struct pt pt_task;  

  45.   

  46. /** 

  47. * @brief 当前显示状态.0:未显示,1显示 

  48. */  

  49.   

  50. static uint8_t State_Show = 0;  

  51.   

  52. /** 

  53. * @brief 控件 

  54. */  

  55.   

  56. //警报距离  

  57. static Widget_Text_Handle Widget_Text_Alarm_Distance;  

  58. //状态  

  59. static Widget_Text_Handle Widget_Text_State;  

  60. //距离  

  61. static Widget_Text_Handle Widget_Text_Distance;  

  62.   

  63. /** 

  64. * @brief 按键状态 

  65. */  

  66.   

  67. static struct _Key_State Key_State =   

  68. {  

  69.     .ok = 0,  

  70.     .cancel = 0,  

  71.     .left = 0,  

  72.     .right = 0  

  73. };  

  74.   

  75. /** 

  76. * @brief 从机信息 

  77. */  

  78.   

  79. static struct _Slave_Info Slave_Info_Show;  

  80.   

  81. /********************************************************************* 

  82. *                           静态函数 

  83. **********************************************************************/  

  84.   

  85. /** 

  86. * @brief 任务运行 

  87. * @retval 任务状态 

  88. */  

  89.   

  90. static int pt_run(struct pt *pt);  

  91.   

  92. /** 

  93. * @brief 按键处理 

  94. */  

  95.   

  96. static void deal_key(void);  

  97.   

  98. /** 

  99. * @brief 更新界面 

  100. */  

  101.   

  102. static void refresh_ui(void);  

  103.   

  104. /********************************************************************* 

  105. *                           函数 

  106. **********************************************************************/  

  107.   

  108. /** 

  109. * @brief 模块载入 

  110. */  

  111.   

  112. void gui_mode_fence_load(void)  

  113. {  

  114.     //载入任务  

  115.     PT_INIT(&pt_task);  

  116. }  

  117.   

  118. /** 

  119. * @brief 模块运行 

  120. */  

  121.   

  122. void gui_mode_fence_run(void)  

  123. {  

  124.     //启动任务  

  125.     pt_run(&pt_task);  

  126. }  

  127.   

  128. /** 

  129. * @brief 设置显示状态 

  130. * @param enable:0:关闭显示,1:打开显示 

  131. */  

  132.   

  133. void gui_mode_fence_show(uint8_t enable)  

  134. {  

  135.     uint8_t distance_alarm = 0;  

  136.     char str[32] = {0};  

  137.       

  138.     //判断当前状态  

  139.     if (State_Show == enable)  

  140.     {  

  141.         return;  

  142.     }  

  143.       

  144.     State_Show = enable;  

  145.     if (State_Show)  

  146.     {  

  147.         //清屏  

  148.         gui_fill_rect(0,0,LCD_WIDTH - 1,LCD_HEIGHT - 1,0);  

  149.           

  150.         //显示状态栏  

  151.         status_bar_show(ON);  

  152.         //显示其他控件  

  153.         //读取报警距离  

  154.         distance_alarm = para_manage_read_distance_alarm();  

  155.         sprintf(str,"%dm",distance_alarm);  

  156.         Widget_Text_Alarm_Distance = gui_widget_text_create(93,20,30,20,GB18030_20X20,str);  

  157.         Widget_Text_State = gui_widget_text_create(93,40,30,20,GB18030_20X20,"正常");  

  158.         Widget_Text_Distance = gui_widget_text_create(0,27,87,30,GB18030_37X37B,"0.0m");  

  159.         refresh_ui();  

  160.     }  

  161.     else  

  162.     {  

  163.         status_bar_show(OFF);  

  164.         gui_widget_delete(Widget_Text_Alarm_Distance);  

  165.         gui_widget_delete(Widget_Text_State);  

  166.         gui_widget_delete(Widget_Text_Distance);  

  167.     }  

  168. }  

  169.   

  170. /** 

  171. * @brief 得到当前的显示状态 

  172. * @retval 0:关闭显示,1:打开显示 

  173. */  

  174.   

  175. uint8_t gui_mode_fence_get_show(void)  

  176. {  

  177.     return State_Show;  

  178. }  

  179.   

  180. /** 

  181. * @brief 任务运行 

  182. * @retval 任务状态 

  183. */  

  184.   

  185. static int pt_run(struct pt *pt)  

  186. {  

  187.     static T_Time time_delay;  

  188.       

  189.     PT_BEGIN(pt);  

  190.       

  191.     //等待显示  

  192.     PT_WAIT_UNTIL(pt,State_Show);  

  193.       

  194.     //等待  

  195.     time_delay = get_time();  

  196.     PT_WAIT_UNTIL(pt,sub_time_safe(get_time(),&time_delay) > INTERVAL_GUI_MODE_FENCE * 1000 || State_Show == OFF);  

  197.       

  198.     if (State_Show)  

  199.     {  

  200.         //更新状态栏  

  201.         status_bar_refresh();  

  202.         //更新界面  

  203.         refresh_ui();  

  204.         //处理按键  

  205.         deal_key();  

  206.     }  

  207.       

  208.     PT_END(pt);  

  209. }  

  210.   

  211. /** 

  212. * @brief 按键处理 

  213. */  

  214.   

  215. static void deal_key(void)  

  216. {     

  217.     uint8_t distance_alarm = 0;  

  218.     char str[32] = {0};  

  219.       

  220.     if (inf_key_detect_hold(KEY_CANCEL))  

  221.     {  

  222.         if (Key_State.cancel == 0)  

  223.         {  

  224.             Key_State.cancel = 1;  

  225.             return;  

  226.         }  

  227.     }  

  228.     else  

  229.     {  

  230.         if (Key_State.cancel == 1)  

  231.         {  

  232.             Key_State.cancel = 0;  

  233.             return;  

  234.         }  

  235.     }  

  236.       

  237.     if (inf_key_detect_hold(KEY_OK))  

  238.     {  

  239.         if (Key_State.ok == 0)  

  240.         {  

  241.             Key_State.ok = 1;  

  242.               

  243.             distance_alarm = para_manage_read_distance_alarm();  

  244.             switch (distance_alarm)  

  245.             {  

  246.                 case 5:  

  247.                 {  

  248.                     distance_alarm = 10;  

  249.                     break;  

  250.                 }  

  251.                 case 10:  

  252.                 {  

  253.                     distance_alarm = 20;  

  254.                     break;  

  255.                 }  

  256.                 case 20:  

  257.                 {  

  258.                     distance_alarm = 30;  

  259.                     break;  

  260.                 }  

  261.                 case 30:  

  262.                 {  

  263.                     distance_alarm = 5;  

  264.                     break;  

  265.                 }  

  266.                 default:  

  267.                 {  

  268.                     distance_alarm = 10;  

  269.                     break;  

  270.                 }  

  271.             }  

  272.             para_manage_earase_para(2);  

  273.             para_manage_save_valid(2);  

  274.             para_manage_save_distance_alarm(distance_alarm);  

  275.             sprintf(str,"%dm",distance_alarm);  

  276.             gui_widget_text_set_text(Widget_Text_Alarm_Distance,GB18030_20X20,str);  

  277.             return;  

  278.         }  

  279.     }  

  280.     else  

  281.     {  

  282.         if (Key_State.ok == 1)  

  283.         {  

  284.             Key_State.ok = 0;  

  285.             return;  

  286.         }  

  287.     }  

  288.       

  289.     if (inf_key_detect_hold(KEY_LEFT))  

  290.     {  

  291.         if (Key_State.left == 0)  

  292.         {  

  293.             Key_State.left = 1;  

  294.               

  295.             //设置为停止中模式  

  296.             para_manage_save_work_mode(MODE_STOPING);  

  297.             //切换到停止进度界面  

  298.             gui_schedule_switch(GUI_STOP_PROGRESS);  

  299.               

  300.             return;  

  301.         }  

  302.     }  

  303.     else  

  304.     {  

  305.         if (Key_State.left == 1)  

  306.         {  

  307.             Key_State.left = 0;  

  308.             return;  

  309.         }  

  310.     }  

  311.       

  312.     if (inf_key_detect_hold(KEY_RIGHT))  

  313.     {  

  314.         if (Key_State.right == 0)  

  315.         {  

  316.             Key_State.right = 1;  

  317.               

  318.             //设置为搜索模式  

  319.             para_manage_save_work_mode(MODE_SEARCH);  

  320.             //切换到搜索模式界面  

  321.             gui_schedule_switch(GUI_MODE_SEARCH);  

  322.             return;  

  323.         }  

  324.     }  

  325.     else  

  326.     {  

  327.         if (Key_State.right == 1)  

  328.         {  

  329.             Key_State.right = 0;  

  330.             return;  

  331.         }  

  332.     }  

  333. }  

  334.   

  335. /** 

  336. * @brief 更新界面 

  337. */  

  338.   

  339. static void refresh_ui(void)  

  340. {     

  341.     char str[32] = {0};  

  342.     uint16_t slave_id = 0;  

  343.     struct _Slave_Info slave_info;  

  344.       

  345.     //从机数量  

  346.     if (para_manage_read_slave_num() == 0)  

  347.     {  

  348.         return;  

  349.     }  

  350.     //读取从机id  

  351.     slave_id = para_manage_read_slave_id(1);  

  352.     //读取从机信息  

  353.     slave_info = slave_manage_read_slave(slave_id);  

  354.       

  355.     //状态  

  356.     if (Slave_Info_Show.state != slave_info.state)  

  357.     {  

  358.         Slave_Info_Show.state = slave_info.state;  

  359.         switch (Slave_Info_Show.state)  

  360.         {  

  361.             case 0:  

  362.             {  

  363.                 gui_widget_text_set_text(Widget_Text_State,GB18030_20X20,"正常");  

  364.                 break;  

  365.             }  

  366.             case 1:  

  367.             {  

  368.                 gui_widget_text_set_text(Widget_Text_State,GB18030_20X20,"低电");  

  369.                 break;  

  370.             }  

  371.             case 2:  

  372.             {  

  373.                 gui_widget_text_set_text(Widget_Text_State,GB18030_20X20,"超距");  

  374.                 break;  

  375.             }  

  376.             case 3:  

  377.             {  

  378.                 gui_widget_text_set_text(Widget_Text_State,GB18030_20X20,"失踪");  

  379.                 break;  

  380.             }  

  381.         }  

  382.     }  

  383.       

  384.     //距离  

  385.     if (Slave_Info_Show.distance != slave_info.distance)  

  386.     {  

  387.         Slave_Info_Show.distance = slave_info.distance;  

  388.         sprintf(str,"%.1fm",Slave_Info_Show.distance);  

  389.         gui_widget_text_set_text(Widget_Text_Distance,GB18030_37X37B,str);  

  390.     }  

  391. }  







『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
如何为单片机选择合适的负载电容