Inhaltsverzeichnis
Bascom State Machine Menu
Beim der Umsetzung des AVR Butterfly IAR-C Code (bzw. der GCC-Portierung) nach Bascom [[1]] entstand folgende hoch effiziente State Machine zur Umsetzung eines Menüs für einen Datalogger.
Der Code wurde stark reduziert, so dass für das gesammte Programm der Menü-Rahmen mit allen Unterprogrammen übrig geblieben ist.
Die Menü-Struktur
Sample Code
Das Code-Beispiel wurde für den Bascom Simulator optimiert und kann dort direkt mit den Ziffern-Tasten bedient werden (NumLock!). Auf dem Simulator-LCD-Display werden die Ebenen mit angezeigt (3 -> 31 -> 32 -> 321 etc.)
Weitere Erklärungen stehen im Quelltext.
'Beispiel für ein State Machine Menü 'Das Beispiel ist für den BASCOM-Simulator angepasst worden ' getestet mit BASCOM 1.11.8.1 ' Codelänge 2362 Byte ' 'Hinweis: Im Simulator müssen die Eingaben in das "Terminal Emulator Window" erfolgen! 'Auf der Tastatur ergeben sich für die VIER Joystick-Positionen folgende Umsetzungen ' ' [Key_plus ] ' [Key_prev] [ ] [Key_next] ' [Key_minus] ' ' ' [ Taste_8 ] ' [Taste_4 ] [ ] [Taste_6 ] ' [ Taste_2 ] ' 'bzw. im ASCII-Code Const Key_null = 0 'keine Taste gedrückt Const Key_next = 54 Const Key_prev = 52 Const Key_plus = 56 Const Key_minus = 50 'los gehts: $regfile = "m32def.dat" $framesize = 32 'Stack $swstack = 32 $hwstack = 64 'Pins des LCD-Modules setzen ggf. an eigene Anschlüsse anpassen Config Lcdpin = Pin , Db4 = Portc.5 , Db5 = Portc.4 , Db6 = Portc.3 , Db7 = Portc.2 , E = Portc.6 , Rs = Portc.7 Config Lcdmode = Port Config Lcdbus = 4 '4 bit mode Config Lcd = 20 * 4 Initlcd Cls '******** state machine states ************************************************ ' Menu state machine states Const St_avrbf = 10 Const St_avrbf_rev = 11 Const St_time = 20 Const St_time_clock = 21 Const St_time_clock_func = 22 Const St_time_clock_adjust = 23 Const St_time_clock_adjust_func = 24 Const St_time_clockformat_adjust = 25 Const St_time_clockformat_adjust_func = 26 Const St_time_date = 27 Const St_time_date_func = 28 Const St_time_date_adjust = 29 Const St_time_date_adjust_func = 30 Const St_time_dateformat_adjust = 31 Const St_time_dateformat_adjust_func = 32 Const St_datalogger = 40 Const St_datalogger_logcycle = 41 Const St_datalogger_logcycle_func = 42 Const St_datalogger_erase = 43 Const St_datalogger_erase_select = 44 Const St_datalogger_erase_func = 45 Const St_datalogger_logcount = 46 Const St_datalogger_logcount_func = 47 Const St_datalogger_rs232 = 48 Const St_datalogger_rs232_select = 49 Const St_datalogger_rs232_func = 50 Const St_adc = 60 Const St_temperature = 65 Const St_temperature_func = 66 Const St_voltage = 70 Const St_voltage_func = 71 Const St_adc_raw = 75 Const St_adc_raw_func = 76 Const St_adc_batt = 80 Const St_adc_batt_func = 81 Const St_options = 90 Const St_options_display_contrast = 91 Const St_options_display_contrast_func = 92 Const St_options_power_off = 95 Const St_options_power_off_func = 97 Const St_options_auto_power_save = 100 Const St_options_auto_power_save_func = 101 Const St_options_keyclick = 105 Const St_options_keyclick_func = 106 Const St_options_boot = 110 Const St_options_boot_select = 111 Const St_options_boot_func = 112 '********* State Variables **************************************************** Dim Tab_state As Byte , Tab_input As Byte , Tab_nextstate As Byte Dim Tab_text As String * 25 Dim State As Byte , State_renew As Byte 'Initial state variables State = St_avrbf State_renew = 1 '******** Joystick/Key Settings *********************************************** Dim Key As Byte 'key in Mainloop '******** LCD ***************************************************************** Dim Lcd_textbuffer As String * 25 '******** allg Variablen ****************************************************** Dim I As Byte , J As Byte Dim I1 As Byte Dim W As Word , W1 As Word '********** MAIN-Loop ********************************************************* Do 'Tastaturabfrage Key = Inkey() 'Menüeintrag und Tastencodes finden If Key <> Key_null Then 'save power State_renew = 0 Restore State_machine Do Read Tab_state Read Tab_input Read Tab_nextstate If State = Tab_state Then If Key = Tab_input Then State = Tab_nextstate State_renew = 1 'LCD refresh Key = Key_null 'reset key status after get a new state of state machine (prevent influence on GOSUBs) End If End If Loop Until State_renew = 1 Or Tab_state = 255 End If 'Endlosschleife mit Unterprogrammen Select Case State '320 Byte für 20 Gosub Case St_time_clock_func : Gosub Showclock Case St_time_clock_adjust_func : Gosub Setclock Case St_time_clockformat_adjust_func : Gosub Setclockformat Case St_time_date_func : Gosub Showdate Case St_time_date_adjust_func : Gosub Setdate Case St_time_dateformat_adjust_func : Gosub Setdateformat Case St_datalogger_logcycle_func : Gosub Datalogger_setloginterval Case St_datalogger_erase_func : Gosub Datalogger_erase Case St_datalogger_logcount_func : Gosub Datalogger_logcount Case St_datalogger_rs232_func : Gosub Datalogger_rs232 Case St_temperature_func : Gosub Temperaturefunc Case St_voltage_func : Gosub Voltagefunc Case St_adc_raw_func : Gosub Adc_raw_func Case St_adc_batt_func : Gosub Adc_batt_func Case St_options_display_contrast_func : Gosub Setcontrast Case St_options_boot_func : Gosub Bootfunc Case St_options_power_off_func : Gosub Power_off_func Case St_options_auto_power_save_func : Gosub Autopower Case St_options_keyclick_func : Gosub Keyclick_set End Select '--------------------------------------------------------------- 'place for your own code in main loop '--------------------------------------------------------------- 'LCD refresh wenn Menü verändert If State_renew = 1 Then State_renew = 0 Restore Menu_text_data Do Read Tab_state Read Tab_text If State = Tab_state Then Lcd_textbuffer = Tab_text Loop Until Tab_state = 255 Gosub Lcd_print End If Loop End '********* LCD SUB routines *************************************************** '--------------------------------------------------------------- 'Subroutine: Lcd_print 'Call from: anywhere 'Purpose: gibt Lcd_textbuffer auf dem LCD-Display aus 'Result: LCD '--------------------------------------------------------------- Lcd_print: 'Print lcd_textbuffer Cls Lcd Lcd_textbuffer Return '********* SUB Clock routines************************************************** Showclock: 'Show the clock on the LCD Lcd_textbuffer = "HH:MM:SS" Gosub Lcd_print Return Setclock: 'Adjusts the Clock Lcd_textbuffer = "HH=11" Gosub Lcd_print Return Setclockformat: 'Adjusts the Clockformat (12H or 24H) Lcd_textbuffer = "12H / 24H" Gosub Lcd_print Return '********* SUB date routines ************************************************** Showdate: 'Show the date on the LCD Lcd_textbuffer = "DD.MM.YY" Gosub Lcd_print Return Setdate: 'Adjusts the Date Lcd_textbuffer = "Month=12" Gosub Lcd_print Return '--------------------------------------------------------------- Setdateformat: 'Adjusts the Dateformat "DDMMYY" , "MMDDYY" , "YYMMDD" Lcd_textbuffer = "DDMMYY/YYMMDD" Gosub Lcd_print Return '********* Datalogger routines ************************************************ Datalogger_setloginterval: 'set the datalog intervall HOUR:MINUTES Lcd_textbuffer = "HH:MM" Gosub Lcd_print Return Datalogger_erase: 'erase the dataflash State = St_datalogger_erase State_renew = 1 Return Datalogger_logcount: 'Show DF_LogCount Lcd_textbuffer = "1234" Gosub Lcd_print Return Datalogger_rs232: 'Print all DataLogs to RS232 State = St_datalogger_rs232 'next status of state machine State_renew = 1 Return Temperaturefunc: 'temperature measurement in °C Lcd_textbuffer = "+24C" Gosub Lcd_print Return Voltagefunc: 'voltage measurement mV Lcd_textbuffer = "0mV" Gosub Lcd_print Return Adc_raw_func: 'ADC Temperature/Voltage/Light result as RAW Lcd_textbuffer = "CH:RAW" Gosub Lcd_print Return Adc_batt_func: 'battery voltage measurement Lcd_textbuffer = "2900mV" Gosub Lcd_print Return '********* Sub MENU / OPTIONS ******************************** Setcontrast: 'Adjust the LCD contrast Lcd_textbuffer = "0...15" Gosub Lcd_print Return Bootfunc: State = St_avrbf 'next status of state machine State_renew = 1 Return Power_off_func: 'LCD OFF State = St_options_power_off Return Autopower: 'Enable/Disable auto power save Lcd_textbuffer = "ON/OFF" Gosub Lcd_print Return Keyclick_set: 'Enable/Disable keyclick Lcd_textbuffer = "ON/OFF" Gosub Lcd_print Return '*********** State Machine *************************************************** '112 Datensätze der State Machine ca. 350 Byte 'State with xxx_func forward to GOSUB xxx in main loop ' ' [Key_plus ] '[Key_prev] [Key_enter] [Key_next] ' [Key_minus] State_machine: ' CURRENT_STATE INPUT NEXT_STATE Data St_avrbf , Key_plus , St_options Data St_avrbf , Key_next , St_avrbf_rev Data St_avrbf , Key_minus , St_time Data St_avrbf_rev , Key_prev , St_avrbf 'Date+Time----------------------------------------------------------------- Data St_time , Key_plus , St_avrbf Data St_time , Key_next , St_time_clock Data St_time , Key_prev , St_avrbf Data St_time , Key_minus , St_datalogger Data St_time_clock , Key_plus , St_time_date Data St_time_clock , Key_next , St_time_clock_func Data St_time_clock , Key_prev , St_time Data St_time_clock , Key_minus , St_time_date Data St_time_clock_func , Key_prev , St_time_clock Data St_time_clock_func , Key_next , St_time_clock_adjust Data St_time_clock_func , Key_minus , St_time_date_func Data St_time_clock_adjust , Key_plus , St_time_clockformat_adjust Data St_time_clock_adjust , Key_next , St_time_clock_adjust_func Data St_time_clock_adjust , Key_prev , St_time_clock_func Data St_time_clock_adjust , Key_minus , St_time_clockformat_adjust Data St_time_clock_adjust_func , Key_prev , St_time_clock_func Data St_time_clockformat_adjust , Key_plus , St_time_clock_adjust Data St_time_clockformat_adjust , Key_next , St_time_clockformat_adjust_func Data St_time_clockformat_adjust , Key_prev , St_time_clock_func Data St_time_clockformat_adjust , Key_minus , St_time_clock_adjust Data St_time_clockformat_adjust_func , Key_prev , St_time_clock_func Data St_time_date , Key_plus , St_time_clock Data St_time_date , Key_next , St_time_date_func Data St_time_date , Key_prev , St_time Data St_time_date , Key_minus , St_time_clock Data St_time_date_func , Key_plus , St_time_clock_func Data St_time_date_func , Key_prev , St_time_date Data St_time_date_func , Key_next , St_time_date_adjust Data St_time_date_adjust , Key_plus , St_time_dateformat_adjust Data St_time_date_adjust , Key_next , St_time_date_adjust_func Data St_time_date_adjust , Key_prev , St_time_date_func Data St_time_date_adjust , Key_minus , St_time_dateformat_adjust Data St_time_date_adjust_func , Key_prev , St_time_date_func Data St_time_dateformat_adjust , Key_plus , St_time_date_adjust Data St_time_dateformat_adjust , Key_next , St_time_dateformat_adjust_func Data St_time_dateformat_adjust , Key_prev , St_time_date_func Data St_time_dateformat_adjust , Key_minus , St_time_date_adjust Data St_time_dateformat_adjust_func , Key_prev , St_time_date_func 'Data Logger--------------------------------------------------------------- Data St_datalogger , Key_plus , St_time Data St_datalogger , Key_next , St_datalogger_logcycle Data St_datalogger , Key_prev , St_avrbf Data St_datalogger , Key_minus , St_adc Data St_datalogger_logcycle , Key_plus , St_datalogger_rs232 Data St_datalogger_logcycle , Key_next , St_datalogger_logcycle_func Data St_datalogger_logcycle , Key_prev , St_datalogger Data St_datalogger_logcycle , Key_minus , St_datalogger_erase Data St_datalogger_logcycle_func , Key_prev , St_datalogger_logcycle Data St_datalogger_erase , Key_plus , St_datalogger_logcycle Data St_datalogger_erase , Key_next , St_datalogger_erase_select Data St_datalogger_erase , Key_prev , St_datalogger Data St_datalogger_erase , Key_minus , St_datalogger_logcount Data St_datalogger_erase_select , Key_next , St_datalogger_erase_func Data St_datalogger_erase_select , Key_prev , St_datalogger_erase 'SUB St_datalogger_erase_func -> new State = St_datalogger_erase Data St_datalogger_logcount , Key_plus , St_datalogger_erase Data St_datalogger_logcount , Key_next , St_datalogger_logcount_func Data St_datalogger_logcount , Key_prev , St_datalogger Data St_datalogger_logcount , Key_minus , St_datalogger_rs232 Data St_datalogger_logcount_func , Key_prev , St_datalogger_logcount Data St_datalogger_rs232 , Key_plus , St_datalogger_logcount Data St_datalogger_rs232 , Key_next , St_datalogger_rs232_select Data St_datalogger_rs232 , Key_prev , St_datalogger Data St_datalogger_rs232 , Key_minus , St_datalogger_logcycle Data St_datalogger_rs232_select , Key_next , St_datalogger_rs232_func Data St_datalogger_rs232_select , Key_prev , St_datalogger_rs232 'SUB St_datalogger_rs232_func -> new State = St_datalogger_rs232 'ADC----------------------------------------------------------------------- Data St_adc , Key_plus , St_datalogger Data St_adc , Key_next , St_temperature Data St_adc , Key_prev , St_avrbf Data St_adc , Key_minus , St_options Data St_temperature , Key_plus , St_adc_raw Data St_temperature , Key_next , St_temperature_func Data St_temperature , Key_prev , St_avrbf Data St_temperature , Key_minus , St_voltage Data St_temperature_func , Key_prev , St_temperature Data St_voltage , Key_plus , St_temperature Data St_voltage , Key_next , St_voltage_func Data St_voltage , Key_prev , St_avrbf Data St_voltage , Key_minus , St_adc_raw Data St_voltage_func , Key_prev , St_voltage Data St_adc_raw , Key_plus , St_voltage Data St_adc_raw , Key_next , St_adc_raw_func Data St_adc_raw , Key_prev , St_avrbf Data St_adc_raw , Key_minus , St_adc_batt Data St_adc_raw_func , Key_prev , St_adc_raw Data St_adc_batt , Key_plus , St_adc_raw Data St_adc_batt , Key_next , St_adc_batt_func Data St_adc_batt , Key_prev , St_avrbf Data St_adc_batt , Key_minus , St_temperature Data St_adc_batt_func , Key_prev , St_adc_batt 'Options------------------------------------------------------------------- Data St_options , Key_plus , St_adc Data St_options , Key_next , St_options_display_contrast Data St_options , Key_prev , St_avrbf Data St_options , Key_minus , St_avrbf Data St_options_display_contrast , Key_plus , St_options_keyclick Data St_options_display_contrast , Key_next , St_options_display_contrast_func Data St_options_display_contrast , Key_prev , St_options Data St_options_display_contrast , Key_minus , St_options_boot Data St_options_display_contrast_func , Key_prev , St_options_display_contrast Data St_options_boot , Key_plus , St_options_display_contrast Data St_options_boot , Key_next , St_options_boot_select Data St_options_boot , Key_prev , St_options Data St_options_boot , Key_minus , St_options_power_off Data St_options_boot_select , Key_next , St_options_boot_func Data St_options_boot_select , Key_prev , St_options_boot Data St_options_power_off , Key_plus , St_options_boot Data St_options_power_off , Key_next , St_options_power_off_func Data St_options_power_off , Key_prev , St_options Data St_options_power_off , Key_minus , St_options_auto_power_save 'SUB St_options_power_off_func -> new State = St_options_power_off Data St_options_auto_power_save , Key_plus , St_options_power_off Data St_options_auto_power_save , Key_next , St_options_auto_power_save_func Data St_options_auto_power_save , Key_prev , St_options Data St_options_auto_power_save , Key_minus , St_options_keyclick Data St_options_auto_power_save_func , Key_prev , St_options_auto_power_save Data St_options_keyclick , Key_plus , St_options_auto_power_save Data St_options_keyclick , Key_next , St_options_keyclick_func Data St_options_keyclick , Key_prev , St_options Data St_options_keyclick , Key_minus , St_options_display_contrast Data St_options_keyclick_func , Key_prev , St_options_keyclick 'Stop Condition Data 255 , 255 , 255 '************ menu text strings: max. length 24 Byte!! *********************** Menu_text_data: Data St_avrbf , "1 Butterfly Bascom" Data St_avrbf_rev , "11 Rev 1" Data St_time , "2 Time" Data St_time_clock , "21 Clock" Data St_time_clock_adjust , "211 Adjust Clock" Data St_time_clockformat_adjust , "212 Clock Format" Data St_time_date , "22 Date" Data St_time_date_adjust , "221 Adjust Date" Data St_time_dateformat_adjust , "222 Date Format" Data St_datalogger , "3 DataLogger" Data St_datalogger_logcycle , "31 Log Cycle" Data St_datalogger_erase , "32 Delete Flash" Data St_datalogger_erase_select , "321 RIGHT Delete DF" Data St_datalogger_logcount , "33 Show LogCount" Data St_datalogger_rs232 , "34 Print to RS232" Data St_datalogger_rs232_select , "341 RIGHT Print9600B" Data St_adc , "4 ADC" Data St_temperature , "41 Temperature" Data St_voltage , "42 Voltage" Data St_adc_raw , "43 ADC Port RAW" Data St_adc_batt , "44 Battery" Data St_options , "5 Options" Data St_options_display_contrast , "51 LCD contrast" Data St_options_boot , "52 Bootloader" Data St_options_boot_select , "521 RIGHT bootloader" Data St_options_power_off , "53 LCD OFF" Data St_options_auto_power_save , "54 LCD Auto Power" Data St_options_keyclick , "55 Key Click" Data 255 , "" 'Stop Condition
Siehe auch
- Sourcevergleich mit Hinweisen zu einer State Machine in BASCOM
- Bascom