До кучи.
Код
//---------------------------------------------------------------------------
//
//---------------------------------------------------------------------------
MenuState menu_state[] =
{
// State State Text Function
{ ST_MAIN, "Main ", NULL },
{ ST_MAIN_REV, " ", mf_revision },
{ ST_TIME_FUNC, "Time ", mf_showtime },
{ ST_TIME_SET_FUNC, "SetTime ", mf_settime },
{ ST_DATE_FUNC, "Date ", mf_showdate },
{ ST_SOUND, "Sound ", NULL },
{ ST_SOUND_SELECT_FUNC, NULL, mf_selectsound },
{ ST_SOUND_PLAY_FUNC, NULL, mf_playsound },
{ ST_TEMPERATURE, "Temperature ", NULL },
{ ST_TEMPERATURE_FUNC, NULL, mf_temperature },
{ ST_VOLTAGE, "Voltage ", NULL },
{ ST_VOLTAGE_FUNC, NULL, mf_voltage },
{ ST_LIGHT, "Light ", NULL },
{ ST_LIGHT_FUNC, NULL, mf_light },
{ ST_OPTIONS, "Options ", NULL },
{ ST_OPTIONS_DISPLAY, "Display ", NULL },
{ ST_OPTIONS_COMMON, "Common ", NULL },
{ ST_OPTIONS_TEST, "Test ", NULL },
// End of list
{ 0, NULL, NULL },
};
//---------------------------------------------------------------------------
//
//---------------------------------------------------------------------------
MenuNavigate menu_nextstate[] =
{
// State Input NEXT State
{ ST_MAIN, KEY_UP, ST_OPTIONS },
{ ST_MAIN, KEY_PREV, ST_MAIN_REV },
{ ST_MAIN, KEY_NEXT, ST_MAIN_REV },
{ ST_MAIN, KEY_DOWN, ST_TIME_FUNC },
{ ST_MAIN_REV, KEY_PREV, ST_MAIN },
{ ST_MAIN_REV, KEY_NEXT, ST_MAIN },
{ ST_SOUND, KEY_UP, ST_DATE_FUNC },
{ ST_SOUND, KEY_NEXT, ST_SOUND_SELECT_FUNC },
{ ST_SOUND, KEY_PREV, ST_MAIN },
{ ST_SOUND, KEY_DOWN, ST_TEMPERATURE },
{ ST_TEMPERATURE, KEY_UP, ST_SOUND },
{ ST_TEMPERATURE, KEY_NEXT, ST_TEMPERATURE_FUNC },
{ ST_TEMPERATURE, KEY_PREV, ST_MAIN },
{ ST_TEMPERATURE, KEY_DOWN, ST_VOLTAGE },
{ ST_VOLTAGE, KEY_UP, ST_TEMPERATURE },
{ ST_VOLTAGE, KEY_NEXT, ST_VOLTAGE_FUNC },
{ ST_VOLTAGE, KEY_PREV, ST_MAIN },
{ ST_VOLTAGE, KEY_DOWN, ST_LIGHT },
{ ST_LIGHT, KEY_UP, ST_VOLTAGE },
{ ST_LIGHT, KEY_NEXT, ST_LIGHT_FUNC },
{ ST_LIGHT, KEY_PREV, ST_MAIN },
{ ST_LIGHT, KEY_DOWN, ST_OPTIONS },
{ ST_OPTIONS, KEY_UP, ST_LIGHT },
{ ST_OPTIONS, KEY_NEXT, ST_OPTIONS_DISPLAY },
{ ST_OPTIONS, KEY_PREV, ST_MAIN },
{ ST_OPTIONS, KEY_DOWN, ST_MAIN },
{ ST_OPTIONS_TEST, KEY_UP, ST_OPTIONS_COMMON },
{ ST_OPTIONS_TEST, KEY_PREV, ST_OPTIONS },
{ ST_OPTIONS_TEST, KEY_BREAK, ST_MAIN },
{ ST_OPTIONS_TEST, KEY_DOWN, ST_OPTIONS_DISPLAY },
{ ST_OPTIONS_DISPLAY, KEY_UP, ST_OPTIONS_TEST },
{ ST_OPTIONS_DISPLAY, KEY_PREV, ST_OPTIONS },
{ ST_OPTIONS_DISPLAY, KEY_BREAK, ST_MAIN },
{ ST_OPTIONS_DISPLAY, KEY_DOWN, ST_OPTIONS_COMMON },
{ ST_OPTIONS_COMMON, KEY_UP, ST_OPTIONS_DISPLAY },
{ ST_OPTIONS_COMMON, KEY_PREV, ST_OPTIONS },
{ ST_OPTIONS_COMMON, KEY_BREAK, ST_MAIN },
{ ST_OPTIONS_COMMON, KEY_DOWN, ST_OPTIONS_TEST },
// End of list
{ 0, 0, 0 }
};
BYTE state; // Helds the current Menu state
BYTE enter = TRUE;
BYTE enter_func = FALSE;
//---------------------------------------------------------------------------
//
//---------------------------------------------------------------------------
void MenuProcess( void *params )
{
int rotor_cnt = 0xF7;
char tmp_str[16];
ulong rtc_time;
BYTE nextstate;
BYTE prevstate;
static char *statetext;
BYTE (*statefunc)(BYTE);
BYTE input;
char i;
params = params;
// Initial state variables
prevstate = ST_DUMMY;
state = nextstate = ST_MAIN;
statetext = "Hello!";
statefunc = NULL;
for(;; ) // Main Menu loop
{
// Plain menu text
if( statetext )
{ lcd_setpos( 1, 1 );
lcd_string( statetext );
statetext = NULL;
}
input = key_get(); // Read buttons
if( statefunc )
{ // When in this state, we must call the state function
nextstate = statefunc( input );
}
else if( input != KEY_NULL )
{ // Plain menu, clock the state machine
nextstate = statemachine( state, input );
}
if( nextstate != state )
{ state = nextstate;
for( i=0; menu_state[i].state; i++ )
{ if( menu_state[i].state == state )
{ statetext = menu_state[i].text;
statefunc = menu_state[i].func;
break;
}
}
}
if( state == ST_MAIN )
{
if( prevstate != ST_MAIN )
{ prevstate = ST_MAIN;
lcd_setpos( 2, 1 );
// 1234567890123456
lcd_string( "No Alarms " );
}
if( xQueueReceive( RTCMSG_handle, &rtc_time, 0 ) )
{
sprintf( &tmp_str[0], "%02i:%02i", (BYTE)(rtc_time>>16), (BYTE)(rtc_time>>8) );
lcd_setpos( 1, 17-8 );
lcd_string( tmp_str );
}
if( ++rotor_cnt > 0xF7+5 )
rotor_cnt = 0xF7;
lcd_setpos( 1, 16 );
lcd_char( rotor_cnt );
vTaskDelay_ms( 100 );
}
else
{ prevstate = state;
vTaskDelay_ms( 100 );
}
} //End Main loop
}
//---------------------------------------------------------------------------
//
//---------------------------------------------------------------------------
BYTE statemachine( BYTE state, BYTE stimul )
{
int i;
BYTE newstate = state; // Default stay in same state
for( i=0; menu_nextstate[i].state; i++ )
{ if( menu_nextstate[i].state == state && menu_nextstate[i].input == stimul )
{ newstate = menu_nextstate[i].state_next;
break;
}
}
return( newstate );
}