1. Task Entry
static void task_ui(void){ // Display this page // Use Page function to find the page and call the disp function of that page. PageV( "idle" )->disp( NULL ); while(1) { // Use Page function to find the page and call the run function of that page. Page( "idle" )->run( NULL,PNULL ); vTaskDelay(100); }}
2. Create a UI Task
static TaskHandle_t task_ui_Handle = NULL;/* Create listener handle */void do_create_ui_task(void){ BaseType_t xReturn = pdPASS;/* Define a return value for creation information, default is pdPASS */ /* Create AppTaskCreate task */ xReturn = thread_create(task_ui, "task_ui", 1024, NULL, 2, &task_ui_Handle); if(pdPASS == xReturn) { printf("do_create_ui_task success! \r\n"); } else { printf("Error:do_create_ui_task! \r\n"); } printf("do_create_ui_task \t:mem_get_free -> %d B \r\n",mem_get_free());}
Note: The above task is called in the task scheduler.3. Organize Page Structure and Attributes
typedef struct PageAction { char* name; // Page name void (*run)(uint8_t dat,uint8_t *ch); // Page call (including display call) void (*disp)(uint8_t mouse); // Display call (provided to other files to display the page) uint8_t (*get_input_event)(void); // Get input event uint8_t mouse; // General cursor descriptor}page_t;
4. Construct and Fill a Page
Below is a background setting screen for a gaming machine device(the idle page:(The screen isLCD12864)
/*-------------------------------------------------------------------------------*/// Display English interfacestatic void disp_english(uint8_t mouse ){ lcd->line1(" welcome "); lcd->line2(" "); lcd->line3("MENU -> setting"); lcd->line4("Back -> clear error");}// Display Chinese interfacestatic void disp_chinese(uint8_t mouse ){ lcd->line1(" 欢迎使用 "); lcd->line2(" "); lcd->line3("菜单 -> 设置"); lcd->line4("返回 -> 清错");}// Display functionstatic void disp(uint8_t mouse){ uint8_t language = gamedat[_P1_]->language; if( language == Chinese ) disp_chinese( mouse ); else disp_english( mouse );}/*-------------------------------------------------------------------------*/// Get input eventstatic uint8_t get_input_event(void){ return get_keyboard_event();}/*-------------------------------------------------------------------------*/// Page call (including display call)static void run(u8 dat,u8 *ch){ extern void clr_err_tsmt_logic( uint8_t id ); extern void clr_err_score_to_gift( uint8_t road ); uint8_t ipEvent = get_input_event(); if( ipEvent == _key_none ) return ; // If there is no key event, exit this function audio_1->req_play_file( _em_key ); // Request to play key sound // Wait for key event, if it is the menu key, perform page depth adjustment if( _key_menu == ipEvent ) { // Notify all players to stop the game suspend_game_logic(); // Enter deep page (select player id) (Note, the page is blocking) PageV( "selt_item")->run( NULL,PNULL ); // Reset system __set_FAULTMASK(1); NVIC_SystemReset(); } else if( _key_back == ipEvent ) { // Notify all players to clear errors for(uint8_t id=0;id<MAX_Road;id++) { clr_err_score_to_gift( id ); // Clear error - component - "Score Exchange Gift" clr_err_tsmt_logic( id ); // Clear error - component - Ball Launcher } PRT_LOG("req clr_err \r\n"); }}/*--------------------------------------------------------------------------*/// The above functions are organized into a structurestatic page_t page = { .name = "idle", .run = run, .disp = disp, .get_input_event = get_input_event, .mouse = 0,};page_t* idle_page = &page;
Other pages are also designed in this way, such as the above required jump to the“selt_item” page, its code is as follows:
/*-------------------------------------------------------------------------*/// Display Chinese interfacestatic void disp_chinese(uint8_t mouse){ static uint8_t color = 0; uint8_t i = 0; uint8_t id = 0 ; lcd->line1(" 选择项目 "); lcd->line2(" "); switch( mouse ) { case 0:lcd->line3(" <- P1 -> ");break; case 1:lcd->line3(" <- P2 -> ");break; case 2:lcd->line3(" <- P3 -> ");break; case 3:lcd->line3(" <-查看数据-> ");break; default:break; } lcd->line4(" ");}// Display English interfacestatic void disp_english(uint8_t mouse){ static uint8_t color = 0; uint8_t i = 0; uint8_t id = 0 ; lcd->line1("Select entry: "); lcd->line2(" "); switch( mouse ) { case 0:lcd->line3(" <- P1 -> ");break; case 1:lcd->line3(" <- P2 -> ");break; case 2:lcd->line3(" <- P3 -> ");break; case 3:lcd->line3(" <-cat data -> ");break; default:break; } lcd->line4(" ");}// Display interfacestatic void disp(uint8_t mouse){ if( gamedat[_P1_]->language == Chinese ) disp_chinese( mouse ); else disp_english( mouse );}/*------------------------------------------------------------------------*/// Get input eventstatic uint8_t get_input_event(void){ return get_keyboard_event();}/*------------------------------------------------------------------------*/// Timed refresh displaystatic time_t otick = 0;static time_t ntick = 0;static void screen_tick( time_t tick ){ ntick = timtick->get(); if( tick >( ntick - otick ) ) return; otick = ntick; disp( page->mouse );}/*--------------------------------------------------------------------------*/// Page call (including display call)static void run(u8 dat,u8 *ch){ u8 ipEvent = 0; this_page = &selt_item_page; this_page->mouse = 0; // suspend_seg_coroutine(); // Suspend digital tube lcd->clr_screen(); PRT_LOG("_p_selt_id->run() \r\n "); while(1) { // Timed refresh page display screen_tick( 200 ); ipEvent = get_input_event(); if( ipEvent == _key_none ) continue; audio_1->req_play_file( _em_key ); // Request to play key sound switch( ipEvent ) { case _key_up: // Increase parameter value case _key_dn: // Decrease parameter value mouse_move( this_page,ipEvent ); break; case _key_menu:// Enter deep interface do_key_menu( this_page,ipEvent ); break; case _key_back:// goto __exit_page; default: break;}// Store datagdat_opt->data_store.write_player_data( _P1_,gamedat[_P1_] );gdat_opt->data_store.write_player_data( _P2_,gamedat[_P2_] );
The remaining pages will not be displayed.
5. Implement Page Manager
Organize these pages with an array:
// Declare external file pagesextern page_t* idle_page;extern page_t* selt_item_page;static page_t* page_list[]={ idle_page, selt_item_page, //...};
Implement a function to find the corresponding page from this array by name:
// Get the number of elements in the array#define ITEM_NUM(items) sizeof(items) / sizeof(items[0])page_t* Page( char* name ){
page_t* page =NULL; for( int i=0;i<(ITEM_NUM(page_list);i++ ) { if( 0 == strncmp( name,page_list[i]->name ,strlen( page_list[i]->name ) ) ) {// Found, the string matches, found the corresponding page page = page_list[i]; return page; } } // If no corresponding page is found, return NULL return NULL;}