STemWin
emWin是Segger公司针对嵌入式平台开发的稳定、高效的图形软件库,适合用于任何图形LCD的操作应用,并可输出高质量的无锯齿的文字和图形,通过调用emWin提供的函数接口,开发嵌入式图形界面应用变得简单而快捷。
1. 三者都是Segger 公司的产品。
2.emWin是Segger 公司图形系统的正式统称。
3.ucGui 是Segger公司为 Micrium 公司(uCOS-II 、uCOS-III)量身定制的 emWin
4.STemWin是Segger 公司为 ST公司量身定制的emWin,适合stm32使用
STenWin免费在ST单片机运行,也只能在ST的芯片运行,支持裸机和操作系统运行,结合CubeMX工具使用那就是事半功倍,可以进行快速的嵌入式开发图形界面。
顺便记录一下在我使用STemWin之前想爆头脑参照网上写的一个菜单索引,比较适合数码管和OLED这类小显示屏菜单目录。
1 #define Null 0 2 #define MENUGRADE 3 //菜单级数 3 4 5 6 7 typedef struct MenuItem 8 { 9 char MenuCount; //结构体数组的元素个数 10 char *DisplayString; //当前LCD显示的信息 11 void (*Subs)(); //执行的函数的指针 12 struct MenuItem *Childrenms; //指向子节点的指针 13 struct MenuItem *Parentms; //指向父节点的指针 14 }MenuItem_typedef; //每个菜单选项的结构体 15 16 17 18 typedef struct MenuData 19 { 20 MenuItem_typedef *GUI_ID; //菜单地址 21 unsigned char ID_Offset[MENUGRADE]; //菜单偏移地址 22 unsigned char mark; //菜单等级下标 23 }MenuData_typedef; //菜单系统数据 24 MenuData_typedef MenuData; 25 26 27 //==========声明=====================// 28 29 MenuItem_typedef M0Main[4]; 30 MenuItem_typedef M1One[5]; 31 MenuItem_typedef M1Two[4]; 32 MenuItem_typedef M1Three[3]; 33 MenuItem_typedef M1Four[3]; 34 MenuItem_typedef M1Two_M2One[3]; 35 MenuItem_typedef M1Three_M2One[3]; 36 MenuItem_typedef M1Three_M2Two[3]; 37 38 39 void Nop(void); 40 void DoSomething(struct MenuItem *manyou); 41 void GameOver(void); 42 void Locate(struct MenuItem *manyou); 43 void Run(struct MenuItem *manyou); 44 //====================================// 45 46 47 void GUI_M0Main(MenuItem_typedef *id) 48 { 49 LCD_Clear(WHITE); 50 POINT_COLOR = BLACK; 51 LCD_ShowString(0,40,320,24,24, M0Main[0].DisplayString); 52 LCD_ShowString(0,60,320,24,24, M0Main[1].DisplayString); 53 LCD_ShowString(0,80,320,24,24, M0Main[2].DisplayString); 54 LCD_ShowString(0,100,320,24,24, M0Main[3].DisplayString); 55 56 POINT_COLOR = RED; 57 LCD_ShowString(0,40,320,24,24, id->DisplayString); 58 59 } 60 61 62 //=====================================// 63 64 MenuItem_typedef M0Main[4]= 65 { 66 {4,"M1One",GUI_M0Main,M1One,Null}, 67 {4,"M1Two",Nop,M1Two,Null}, 68 {4,"M1Three",Nop,M1Three,Null}, 69 {4,"M1Four",Nop,M1Four,Null}, 70 }; 71 72 MenuItem_typedef M1One[5]= 73 { 74 {5,"M1One-text1",DoSomething,Null,M0Main}, 75 {5,"M1One-text2",DoSomething,Null,M0Main}, 76 {5,"M1One-text3",DoSomething,Null,M0Main}, 77 {5,"M1One-text4",DoSomething,Null,M0Main}, 78 {5,"exit",DoSomething,Null,M0Main}, 79 }; 80 81 MenuItem_typedef M1Two[4]= 82 { 83 {4,"M1Two_M2One",Nop,M1Two_M2One,M0Main}, 84 {4,"M1Two-text1",DoSomething,Null,M0Main}, 85 {4,"M1Two-text2",DoSomething,Null,M0Main}, 86 {4,"exit",DoSomething,Null,M0Main}, 87 }; 88 89 MenuItem_typedef M1Three[3]= 90 { 91 {3,"M1Three_M2One",Nop,M1Three_M2One,M0Main}, 92 {3,"M1Three_M2Two",Nop,M1Three_M2Two,M0Main}, 93 {3,"exit",DoSomething,Null,M0Main}, 94 }; 95 96 97 MenuItem_typedef M1Four[3]= 98 { 99 {3,"M1Four-text1",DoSomething,Null,M0Main}, 100 {3,"M1Four-text2",DoSomething,Null,M0Main}, 101 {3,"exit",DoSomething,Null,M0Main}, 102 }; 103 104 MenuItem_typedef M1Two_M2One[3]= 105 { 106 {3,"M1Two_M2One-text1",DoSomething,Null,M1Two}, 107 {3,"M1Two_M2One-text2",DoSomething,Null,M1Two}, 108 {3,"exit",DoSomething,Null,M1Two}, 109 }; 110 111 MenuItem_typedef M1Three_M2One[3]= 112 { 113 {3,"M1Three_M2One-text1",DoSomething,Null,M1Three}, 114 {3,"M1Three_M2One-text2",DoSomething,Null,M1Three}, 115 {3,"exit",DoSomething,Null,M1Three}, 116 }; 117 118 MenuItem_typedef M1Three_M2Two[3]= 119 { 120 {3,"M1Three_M2Two-text1",DoSomething,Null,M1Three}, 121 {3,"M1Three_M2Two-text2",DoSomething,Null,M1Three}, 122 {3,"exit",DoSomething,Null,M1Three}, 123 }; 124 125 //=======================================// 126 127 128 129 130 void GUI_Display(MenuItem_typedef *id) 131 { 132 //printf("Now we at %s\n" ,id->DisplayString); 133 LCD_Clear(WHITE); 134 LCD_ShowString(0,40,320,24,24, id->DisplayString); 135 } 136 137 void GUI_Subs(MenuItem_typedef *id) 138 { 139 (*(id->Subs))(id); 140 } 141 142 void Nop(void) {} 143 144 145 void DoSomething(MenuItem_typedef *id) 146 { 147 148 } 149 150 151 152 153 void GUI_Init(void) 154 { 155 memset(&MenuData, 0, sizeof(MenuData)); 156 157 POINT_COLOR=RED; 158 BACK_COLOR=WHITE; 159 LCD_Clear(WHITE); 160 MenuData.GUI_ID = &M0Main[0]; //开始的位置 161 //GUI_Display(MenuData.GUI_ID); 162 GUI_Subs(MenuData.GUI_ID); 163 } 164 165 166 void GUI(char button) 167 { 168 switch (button) 169 { 170 case '>': //到同级菜单的后一项 171 MenuData.ID_Offset[MenuData.mark]++; 172 if(MenuData.ID_Offset[MenuData.mark] > MenuData.GUI_ID->MenuCount-1) 173 MenuData.ID_Offset[MenuData.mark]=0; 174 //GUI_Display(MenuData.GUI_ID+MenuData.ID_Offset[MenuData.mark]); 175 GUI_Subs(MenuData.GUI_ID+MenuData.ID_Offset[MenuData.mark]); 176 177 break; 178 179 case '<': //到同级菜单的前一项 180 if(MenuData.ID_Offset[MenuData.mark] == 0) 181 MenuData.ID_Offset[MenuData.mark] = MenuData.GUI_ID->MenuCount-1; 182 else 183 MenuData.ID_Offset[MenuData.mark]--; 184 //GUI_Display(MenuData.GUI_ID+MenuData.ID_Offset[MenuData.mark]); 185 GUI_Subs(MenuData.GUI_ID+MenuData.ID_Offset[MenuData.mark]); 186 187 break; 188 189 case '+': //到下一级菜单 190 if((MenuData.GUI_ID+MenuData.ID_Offset[MenuData.mark])->Childrenms != Null) 191 { 192 MenuData.GUI_ID = (MenuData.GUI_ID+MenuData.ID_Offset[MenuData.mark])->Childrenms; 193 MenuData.mark++; 194 MenuData.ID_Offset[MenuData.mark] = 0; 195 //GUI_Display(MenuData.GUI_ID+MenuData.ID_Offset[MenuData.mark]); 196 GUI_Subs(MenuData.GUI_ID+MenuData.ID_Offset[MenuData.mark]); 197 } 198 199 break; 200 201 case '-': //到上一级菜单 202 if((MenuData.GUI_ID+MenuData.ID_Offset[MenuData.mark])->Parentms != Null) 203 { 204 MenuData.GUI_ID = (MenuData.GUI_ID+MenuData.ID_Offset[MenuData.mark])->Parentms; 205 MenuData.mark--; 206 //GUI_Display(MenuData.GUI_ID+MenuData.ID_Offset[MenuData.mark]); 207 GUI_Subs(MenuData.GUI_ID+MenuData.ID_Offset[MenuData.mark]); 208 } 209 210 break; 211 212 default: break; 213 } 214 215 }
在实际开发中遇到了一点问题,使用的是V5.26版本:
一、在控件EDIT小工具中,EDIT_EnaBleBlink()函数并没有正常开启光标闪烁。
二、在控件EDIT小工具中,EDIT_GetText()函数获取用户的输入数据,其中,有一个形参是获取多少 字节的,但是实际获取到的比它要少一位,比如填5,实际获取到的是4位字符。
STemwin似乎对版本一致性比较高,不同版本的库与工具使用事会对应不上。