430也要GUI之一: 多级文本菜单开源
提起GUI,可能有不少朋友选择去移植UCGUI之类的东西,不过在我看来,自己写一个GUI也是一个不错的选择,功能实用就好,只要能很好的完成人机交互的任务就可以了。
多级文本菜单是经常用到的一种功能选择方式,这里给出一个完整的实现源码,显示设备是240×320的彩色TFT液晶,改成其它分辨率的应该也很容易,输入是键盘。这个菜单程序理论上支持无限级菜单,使用的时候写一个菜单资源文件就可以了;支持用户权限控制,也就是说,可以设置不同级别的登录密码,所能看到的菜单项可以按登录级别区分;可以支持动态生成的菜单,比如说查询记录项之类。
GUI要有良好的用户感受,基础条件是要有足够的执行速度和内存容量。不幸的是,这2点对于大多数430单片机来说都是弱项。对于149级别的MCU,用这个程序的话,建议还是用到128×128以下的单色液晶上比较好,如果用到彩色液晶上,那么滚屏显示菜单项绝对会是噩梦级的感受。如果是5x级别的,情况就好的多,240×320的彩色液晶上完全可以跑的很流畅。
多级文本菜单.jpg (30.02 KB, 下载次数: 0)
下载附件 保存到相册
多级文本菜单
2015-4-6 16:07 上传
MAIN.C
- //===========================================================================//
- // //
- // 文件: MAIN.C //
- // 说明: BW-DK5438开发板多级文本菜单应用程序 //
- // 编译: IAR Embedded Workbench IDE for MSP430 v4.21 //
- // 版本: v1.1 //
- // 编写: JASON.ZHANG //
- // 版权: 北京拓普博维电子技术有限公司 //
- // //
- //===========================================================================//
- #include "main.h"
- #pragma vector=TIMERB1_VECTOR
- __interrupt void TIMERB1_ISR(void)
- {
- VmainMon() ;
- Event |= SHOULD_FLICKER ;
- TBCTL &= ~TBIFG ;
- }
- #pragma vector=RTC_VECTOR
- __interrupt void RTC_ISR(void)
- {
- RTCCTL01 &=~(RTCRDYIFG + RTCTEVIFG) ;
- Event |= SHOULD_DISPLAY_TIME ;
- }
- void main(void)
- {
- WDTCTL = WDTPW+WDTHOLD ;
- Init_Func() ;
- Init() ;
- MAIN_POWER_ON ;
- for(;;)
- {
- LCD_Init() ;
- Clear_LCD(Color_BK) ;
- _EINT() ;
- RunMenu() ;
- }
- }
- //=====================================================================//
- // //
- //函数:void RunMenu(void) //
- //描述:执行菜单调度 //
- // //
- //=====================================================================//
- void RunMenu(void)
- {
- unsigned char key = 0xFF , menu_index , SubMenuIndex ;
- unsigned char First_Item , Active_Item , Active_Item_Index ;
- unsigned char CallBackIndex ;
- Clear_LCD(STATUS_BK_COLOR) ;
- Color_BK = STATUS_BK_COLOR ;
- PutStringCN24(10,294,"确认") ; // 底栏
- PutStringCN24(185,294,"取消") ;
- LoadMenu(MENU_MAIN,PERMISSION) ;
- Initial_Menu() ;
- DisplayTime() ;
- for(;;)
- {
- key = GetKeyPress() ;
- switch(key)
- {
- case Up: case Down: case Left: case Right:
- MenuMessage(key) ;
- break ;
- case 8:
- MenuMessage(Up) ;
- break ;
- case 0:
- MenuMessage(Down) ;
- break ;
- case Esc:
- {
- menu_index = GetMenuIndex() ;
- if(Menus[menu_index].MasterMenu!=EMPTY)
- {
- LoadMenu(Menus[menu_index].MasterMenu,PERMISSION) ;
- Initial_Menu() ;
- }
- break ;
- }
- case OK: case Enter:
- {
- First_Item = GetFirstItem() ;
- Active_Item = GetActiveItem() ;
- Active_Item_Index = GetActiveItemIndex() ;
- if(MENU_ITEM[Active_Item_Index].CallBackFuncIndex!=EMPTY) // 有操作函数
- {
- CallBackIndex= MENU_ITEM[Active_Item_Index].CallBackFuncIndex ;
- SubMenuIndex = MENU_ITEM[Active_Item_Index].SubMenuIndex ;
- if(SubMenuIndex!=EMPTY) // 有操作函数且有动态子菜单
- {
- SubMenuIndex = MENU_ITEM[Active_Item_Index].SubMenuIndex ;
- if(Item_OP[CallBackIndex](0,Active_Item_Index )==0x00) // 生成子菜单成功
- Initial_Menu() ; // 初始化动态子菜单
- else
- Redraw_Menu(First_Item,Active_Item) ; // 未生成子菜单,重画原菜单
- }
- else
- {
- Item_OP[CallBackIndex](0,Active_Item_Index ) ; // 无动态子菜单
- Redraw_Menu(First_Item,Active_Item) ; // 重画菜单
- }
- }
- else
- if(MENU_ITEM[Active_Item_Index].SubMenuIndex!=EMPTY)
- {
- LoadMenu(MENU_ITEM[Active_Item_Index].SubMenuIndex,PERMISSION) ;
- Initial_Menu() ;
- }
- break ;
- }
- case Power:
- return ;
- default:
- break ;
- }
- }
- }
- //=====================================================================//
- // //
- //函数:Show_Help(NC1,NC2) //
- //描述:显示帮助信息 //
- // //
- //=====================================================================//
- unsigned char Show_Help(unsigned int NC1,unsigned char NC2)
- {
- unsigned char key ;
- DrawRectFill(0,60,240,230,WINDOW_BK_COLOR) ;
- DrawRectFill(0,30 ,240,30 ,WINDOW_COLOR) ;
- Color = TITLE_COLOR ;
- Color_BK = TITLE_BK_COLOR ;
- PutStringCN24(70,33,"帮助信息") ;
- DrawRectFill(0,290,240,30,STATUS_BK_COLOR) ;
- Color = STATUS_COLOR ;
- Color_BK = STATUS_BK_COLOR ;
- PutStringCN24(185,294,"返回") ;
- Color = WINDOW_COLOR ;
- Color_BK = WINDOW_BK_COLOR ;
- DrawRectFill(0,60,240,230,WINDOW_BK_COLOR) ;
- PutString24M(10,70 ,"↑键:[8]") ;
- PutString24M(10,100,"↓键:[0]") ;
- PutString24M(10,130,"菜单选择:[Enter]") ;
- PutString24M(10,160,"菜单返回:[Cancel]") ;
- PutString24M(10,190,"上 一 页:[←]") ;
- PutString24M(10,220,"下 一 页:[→]") ;
- PutString24M(10,250,"输入法切换:
- ") ;
- for(;;)
- {
- key = ReadKey() ;
- if(key==Esc) break ;
- }
- DrawRectFill(0,290,240,30,STATUS_BK_COLOR) ;
- Color_BK = STATUS_BK_COLOR ;
- Color = STATUS_COLOR ;
- PutStringCN24(10,294,"确认") ; // 底栏
- Color = WINDOW_COLOR ;
- Color_BK = WINDOW_BK_COLOR ;
- return 0x00 ;
- }
- //=====================================================================//
- // //
- //函数:Set_Time(NC1,NC2) //
- //说明:演示函数,显示时间设置成功 //
- // //
- //=====================================================================//
- unsigned char Set_Time(unsigned int NC1,unsigned char NC2)
- {
- DrawRectFill(0,60,240,230,WINDOW_BK_COLOR) ;
- DrawRectFill(0,30 ,240,30 ,WINDOW_COLOR) ;
- Color = TITLE_COLOR ;
- Color_BK = TITLE_BK_COLOR ;
- PutStringCN24(70,33,"设置时间") ;
- DrawRectFill(0,290,240,30,STATUS_BK_COLOR) ;
- Color = STATUS_COLOR ;
- Color_BK = STATUS_BK_COLOR ;
- PutStringCN24(185,294,"返回") ;
- Color = WINDOW_COLOR ;
- Color_BK = WINDOW_BK_COLOR ;
- DrawRectFill(0,60,240,230,WINDOW_BK_COLOR) ;
- MessageBox("信息提示","时间已设置成功") ;
- return 0x00 ;
- }
- //=====================================================================//
- // //
- //函数:Set_Backlight(NC1,NC2) //
- //说明:演示函数,显示背光已设置 //
- // //
- //=====================================================================//
- unsigned char Set_Backlight(unsigned int NC1,unsigned char NC2)
- {
- DrawRectFill(0,60,240,230,WINDOW_BK_COLOR) ;
- DrawRectFill(0,30 ,240,30 ,WINDOW_COLOR) ;
- Color = TITLE_COLOR ;
- Color_BK = TITLE_BK_COLOR ;
- PutStringCN24(70,33,"设置背光") ;
- DrawRectFill(0,290,240,30,STATUS_BK_COLOR) ;
- Color = STATUS_COLOR ;
- Color_BK = STATUS_BK_COLOR ;
- PutStringCN24(185,294,"返回") ;
- Color = WINDOW_COLOR ;
- Color_BK = WINDOW_BK_COLOR ;
- DrawRectFill(0,60,240,230,WINDOW_BK_COLOR) ;
- MessageBox("信息提示","背光已设置成功") ;
- return 0x00 ;
- }
- //=====================================================================//
- // //
- //函数:View_Board_Info(NC1,NC2) //
- //描述:显示帮助信息 //
- // //
- //=====================================================================//
- unsigned char View_Board_Info(unsigned int NC1,unsigned char NC2)
- {
- DrawRectFill(0,60,240,230,WINDOW_BK_COLOR) ;
- DrawRectFill(0,30 ,240,30 ,WINDOW_COLOR) ;
- Color = TITLE_COLOR ;
- Color_BK = TITLE_BK_COLOR ;
- PutStringCN24(70,33,"开发板信息") ;
- DrawRectFill(0,290,240,30,STATUS_BK_COLOR) ;
- Color = STATUS_COLOR ;
- Color_BK = STATUS_BK_COLOR ;
- PutStringCN24(185,294,"返回") ;
- Color = WINDOW_COLOR ;
- Color_BK = WINDOW_BK_COLOR ;
- DrawRectFill(0,60,240,230,WINDOW_BK_COLOR) ;
- MessageBox("信息提示","BW_DK5438") ;
- return 0x00 ;
- }
- //=====================================================================//
- //函数:void VmainMon(void) —主电池电压检测 //
- //=====================================================================//
- void VmainMon(void)
- {
- static unsigned char i = 0 ;
- static float Vmain = 0 ;
- ADC12CTL0 |= ADC12SC ;
- while (!(ADC12IFG & BIT0)) ;
- Vmain += ADC12MEM0*7.5/4095-0.4 ;
- if(++i==10)
- {
- Vmain /= 10 ;
- VmainAvr = Vmain ;
- Vmain = 0 ;
- i = 0 ;
- }
- }
- //=====================================================================//
- //函数:void VmainMon(void) —显示主电源电量 //
- //=====================================================================//
- void DrawBattery(float voltage)
- {
- DrawRectFill(213,8,24,12,STATUS_BK_COLOR) ;
- DrawRect(213,11,3,6,Green) ;
- DrawRect(215,8,20,12,Green) ;
- if(voltage>3.2)
- DrawRectFill(217,10,4,9,Green) ;
- if(voltage>3.0)
- DrawRectFill(223,10,4,9,Green) ;
- if(voltage>2.8)
- DrawRectFill(229,10,4,9,Green) ;
- }
- //=====================================================================//
- //函数:void ReadKey(void) —读取按键 //
- //=====================================================================//
- unsigned char ReadKey(void)
- {
- unsigned char column,row,key ;
- unsigned char Key ;
- ROW_IN_COL_OUT ;
- row = KEY_PORT_IN&(KPR0+KPR1+KPR2+KPR3) ;
- if(row!=(KPR0+KPR1+KPR2+KPR3))
- {
- CLO_IN_ROW_OUT ;
- column = KEY_PORT_IN&(KPC0+KPC1+KPC2+KPC3) ;
- ROW_IN_COL_OUT ;
- Key = row + column ;
- _NOP();
- switch(Key)
- {
- case 0x7E:
- key = Enter ;
- break ;
- case 0x7D:
- key = Cancel ;
- break ;
- case 0x02FE:
- key = Up ;
- break ;
- case 0x02FD:
- key = Down ;
- break ;
- case 0xEE:
- key = Left ;
- break ;
- case 0xBE:
- key = Right ;
- break ;
- case 0x7B:
- key = F1 ;
- key = Delete ;
- break ;
- case 0x77:
- key = F3 ;
- key = Backspace ;
- break ;
- case 0xE7:
- key = 1 ;
- break ;
- case 0xD7:
- key = 2 ;
- break ;
- case 0xB7:
- key = 3 ;
- break ;
- case 0xEB:
- key = 4 ;
- break ;
- case 0xDB:
- key = 5 ;
- break ;
- case 0xBB:
- key = 6 ;
- break ;
- case 0xED:
- key = 7 ;
- break ;
- case 0xDD:
- key = 8 ;
- break ;
- case 0xBD:
- key = 9 ;
- break ;
- case 0xDE:
- key = 0 ;
- break ;
- default:
- key = 0xFF ;
- }
- }
- else
- key = 0xFF ;
- KEY_PORT_DIR = 0xFF ;
- KEY_PORT_OUT = 0x00 ;
- return key ;
- }
- unsigned char GetKeyPress(void)
- {
- unsigned char Key ;
- static unsigned long power_time = 0 ;
- for(;;)
- {
- Key = ReadKey() ;
- if(Key==Power)
- {
- if(++power_time>300000)
- return Key ;
- else
- continue ;
- }
- else
- power_time = 0x00 ;
- if(Key==0xFF)
- {
- __delay_cycles(560000) ;
- Key = ReadKey() ;
- if(Key==0xFF) break ;
- }
- }
- Interval = 0 ;
- for(;;)
- {
- if(Event&SHOULD_FLICKER)
- {
- Event &=~SHOULD_FLICKER ;
- DrawBattery(VmainAvr) ;
- }
- if(Event&SHOULD_DISPLAY_TIME)
- {
- Event &=~SHOULD_DISPLAY_TIME ;
- DisplayTime() ;
- }
- Key = ReadKey() ;
- if(Interval++>MAX_INTERVAL)
- Interval =MAX_INTERVAL ;
- if(Key!=0xFF)
- {
- __delay_cycles(560000) ;
- if(Key==ReadKey())
- {
- return Key ;
- }
- }
- }
- }
- void DisplayTime(void)
- {
- unsigned char Hour,Minute ;
- unsigned int color_temp,bkcolor_temp ;
- char string[6] ;
- Minute = RTCMIN ;
- Hour = RTCHOUR ;
- DrawRectFill(160,0,50,29,STATUS_BK_COLOR) ;
- sprintf(string,"%02d:%02d",Hour,Minute) ;
- color_temp = Color ;
- bkcolor_temp = Color_BK ;
- Color = STATUS_COLOR ;
- Color_BK = STATUS_BK_COLOR ;
- PutStringEN16(160,8,(unsigned char *)string) ;
- Color = color_temp ;
- Color_BK = bkcolor_temp ;
- }
- //=====================================================================//
- //函数:void Init_Func(void) //
- //描述:初始化函数列表 //
- //=====================================================================//
- void Init_Func(void)
- {
- Item_OP[FUNC_SHOW_HELP] = Show_Help ; // 帮助信息
- Item_OP[FUNC_BOARD_INFO] = View_Board_Info ; // 开发板信息
- Item_OP[FUNC_SET_TIME] = Set_Time ; // 设置时间
- Item_OP[FUNC_SET_BACKLIGHT] = Set_Backlight ; // 设置背光
- }
- //=====================================================================//
- //函数:void MessageBox(char *title,char *string) //
- //功能:显示消息框 //
- //参数: title —消息框标题 //
- // string —消息框内容 //
- //=====================================================================//
- void MessageBox(char *title,char *string)
- {
- unsigned char key ;
- _DINT() ;
- Color = TITLE_COLOR ;
- Color_BK = TITLE_BK_COLOR ;
- DrawRectFill(20,115,200,30,TITLE_BK_COLOR) ;
- PutStringCN24(120-strlen(title)*6,118,
- (unsigned char *)title ) ;
- DrawRectFill(20,145,200,80,WINDOW_BK_COLOR) ;
- DrawRectFill(20,145,200,80,0xFFFF) ;
- DrawRect(20,145,200,80,WINDOW_COLOR) ;
- Color = WINDOW_COLOR ;
- Color_BK = 0xFFFF ;
- PutString24M(120-strlen(string)*6,173,
- (unsigned char *)string ) ;
- Color_BK = WINDOW_BK_COLOR ;
- _EINT() ;
- for(;;)
- {
- key = GetKeyPress() ;
- if(key==Enter||key==Esc||key==OK)
- break ;
- }
- }
复制代码
main.h
- #include "msp430x54x.h"
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include "Menu.h"
- #include "MenuRes.h"
- //#include "Edit.h"
- #include "TFTDRV430.H"
- #include "PIN_DEF.H"
- #include "RTC.H"
- #define MAX_INTERVAL 150000
- #define PERMISSION 0x03 // 菜单权限
- #define RETURN_MASTER 0x33 // 函数执行完回到主菜单
- #define GOTO_SUB 0x44 // 函数执行完执行子菜单
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////
- //#define Power BIT0
- #define VALID 0x11
- #define INVALID 0x22
- //------------------------------- 事件类型定义----------------------------------//
- #define SHOULD_DISPLAY_TIME BIT0 // 应更新时间显示
- #define SHOULD_FLICKER BIT1 // 应闪烁光标
- #define RX_FRAME_RECEIVED BIT2 // 收到有效数据帧
- #define TX_FRAME_WAITING BIT3 // 串口数据等待发送
- #define LOWPOWER_DETECTED BIT5 // 电池容量低
- #define SHOULD_UPDATE_WDT BIT6 // 更新看门狗定时器
- #define RX_PC_RECEIVED BIT7 // 上位机接收到数据
- #define CARD_DETECTED BIT8 // 检测到射频卡
- #define PRE_EDIT 0xFE // 切换至上一Edit控件
- #define NEXT_EDIT 0xFD // 切换至下一Edit控件
- #define INP_DIG BIT0 // 输入模式 —数字
- #define INP_EN BIT1 // 输入模式 —英文字母
- #define INP_CN BIT2 // 输入模式 —汉字
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////
- unsigned int OP_MODE ; // 操作模式-系统员级/管理员级/操作员级
- MENU Menu ;
- unsigned int Event ;
- unsigned char INP_MODE = INP_CN ; // 输入模式
- unsigned char INP_MODE_LMT = INP_CN+INP_EN+INP_DIG ; // 输入模式限制
- unsigned long int Interval = 0xFFFFFFFF ; // 输入键间隔
- float VmainAvr = 0 ;
- unsigned int Color,Color_BK ;
- unsigned char (*Item_OP[ALL_ITEMS])(unsigned int,unsigned char) ;
- unsigned char View_Board_Info(unsigned int NC1,unsigned char NC2) ;
- unsigned char Set_Time(unsigned int NC1,unsigned char NC2) ;
- unsigned char Set_Backlight(unsigned int NC1,unsigned char NC2) ;
- void Init_Func(void) ;
- void Wait_Key(unsigned char key_waited) ;
- void Display_Time(void) ;
- void VmainMon(void) ;
- extern void Init_MCLK(void) ;
- extern void Init_KeyPad(void) ;
- extern void Init_RTC(void) ;
- extern void Init_timer(void) ;
- extern void Init_Port(void) ;
- extern void Init_ADC(void) ;
- extern void BackLight(void) ;
- extern void Init_UART(void) ;
- extern void Init_UART_115200(void) ;
- extern void Init(void) ;
- extern void str_cpy(char* Destination,char* Source,unsigned char Num) ;
- //////////////////////////////////////////////////////////////////////////////////////////////////////
- extern void Init_SPI(void) ;
- void RunMenu(void) ;
- unsigned char ReadKey(void) ;
- unsigned char Input_CN(char first_key,char* buffer) ;
- unsigned char GetKeyPress(void) ;
- void DrawBattery(float voltage) ;
- void DisplayTime(void) ;
- unsigned char Read_Edit_Val(unsigned char Edit_Index,char* string,
- unsigned char Renew_Edit_Index ) ;
- unsigned char Valve_Mantain_Open(unsigned int NC1,unsigned char NC2) ;
- void MessageBox(char *title,char *string)
|