Aus RN-Wissen.de
Wechseln zu: Navigation, Suche
Rasenmaehroboter fuer schwierige und grosse Gaerten im Test

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

Butterflymenu.png

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


LiFePO4 Speicher Test