Code:
'Beispiel für ein State Machine Menü
'Das Beispiel ist für den BASCOM-Simulator angepasst worden
' getestet mit Bascom 1.11.9.1
' Codelänge 3288 Byte
$regfile = "m32def.dat"
$framesize = 32 'Stack
$swstack = 32
$hwstack = 64
'
'Hinweis: Im Simulator müssen die Eingaben in dem blauen "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:
Dim Keycode_string As String * 4
'Key_plus|Key_minus|Key_prev|Key_next
Keycode_string = "{056}{050}{052}{054}"
Dim Keycode(4) As Byte At Keycode_string Overlay
Const Key_null = 0 'keine Taste gedrückt
'Pins des LCD-Modules setzen ggf. an eigene Anschlüsse anpassen
Config Lcd = 16 * 1
Initlcd
Cls
'******** 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
'********* State Variables ****************************************************
Dim State As Byte , State_renew As Byte
Dim Gosub_adr As Word
'Initial state variables
State_renew = 1
State = 10 'Startbildschirm
Key = Key_null
'********** MAIN-Loop *********************************************************
Do
'Menüeintrag und Tastencodes finden und ggf. State wechseln
If Key <> Key_null Then 'save power
State_renew = 0
Gosub State_detect 'hier nur Tastendruck auswerten
For I = 1 To 4
'Read J
LPM R24,Z+
sts {J},R24
If Key = Keycode(i) Then
If J > 0 Then
State_renew = 1
Key = Key_null 'reset key status after get a new state of state machine (prevent influence on GOSUBs)
State = J
End If
End If
Next I
End If
'Unterprogramm des aktuellen State auslesen und ggf. anspringen
Gosub State_detect
If Gosub_adr > 0 Then
Gosub_adr = Gosub_adr / 2 'see Bascom-Doc Mixing ASM and BASIC
LDS R31, {Gosub_Adr+1} 'High
LDS R30, {Gosub_Adr} 'Low
'Call zum Sub
ICALL
End If
'---------------------------------------------------------------
'place for your own code in main loop
'---------------------------------------------------------------
'LCD refresh wenn Menü verändert
If State_renew = 1 Then
State_renew = 0
Gosub Lcd_print
End If
'Tastaturabfrage mit Halt nur für Simulator, ansonsten Sleep+Timer_ISR verwenden!!
Key = Waitkey()
Loop
End
'********* State routines ***************************************************
'---------------------------------------------------------------
'Subroutine: State_detect
'Call from: main loop
'Purpose: Status der State Machine feststellen
'Result: Pointer auf "DATA KeyCodes" und zugehörige Gosub
'---------------------------------------------------------------
State_detect:
Gosub_adr = 0
Select Case State
Case 10:
Lcd_textbuffer = "1 Butterfly Bascom"
!Call Restore_label
Data 0 , 20 , 0 , 11 'Key_plus|Key_minus|Key_prev|Key_next
Case 11:
Lcd_textbuffer = "11 Rev 2"
!Call Restore_label
Data 0 , 0 , 10 , 0 'Key_plus|Key_minus|Key_prev|Key_next
Case 20:
Lcd_textbuffer = "2 Time"
!Call Restore_label
Data 10 , 30 , 0 , 21
Case 21:
Lcd_textbuffer = "21 Clock"
!Call Restore_label
Data 0 , 22 , 20 , 23
Case 22:
Lcd_textbuffer = "22 Date"
!Call Restore_label
Data 21 , 0 , 20 , 24
Case 23: 'Show HH:MM:SS
Gosub_adr = Loadlabel(showclock)
!Call Restore_label
Data 0 , 24 , 21 , 25
Case 24: 'Show DD:MM:YY
Gosub_adr = Loadlabel(showdate)
!Call Restore_label
Data 23 , 0 , 22 , 26
Case 25:
Lcd_textbuffer = "211 Adjust Clock"
!Call Restore_label
Data 27 , 0 , 23 , 65
Case 26:
Lcd_textbuffer = "221 Adjust Date"
!Call Restore_label
Data 0 , 28 , 24 , 66
Case 27:
Lcd_textbuffer = "212 Clock Format"
!Call Restore_label
Data 0 , 25 , 23 , 67
Case 28:
Lcd_textbuffer = "222 Date Format"
!Call Restore_label
Data 26 , 0 , 23 , 68
Case 30:
Lcd_textbuffer = "3 DataLogger"
!Call Restore_label
Data 20 , 40 , 0 , 31
Case 31:
Lcd_textbuffer = "31 Log Cycle"
!Call Restore_label
Data 0 , 32 , 30 , 35
Case 32:
Lcd_textbuffer = "32 Delete Flash"
!Call Restore_label
Data 31 , 33 , 30 , 36
Case 33:
Lcd_textbuffer = "33 Show LogCount"
!Call Restore_label
Data 32 , 34 , 30 , 37
Case 34:
Lcd_textbuffer = "34 Print to RS232"
!Call Restore_label
Data 33 , 0 , 30 , 38
Case 35: 'HH:MM
Gosub_adr = Loadlabel(datalogger_setloginterval)
!Call Restore_label
Data 0 , 0 , 31 , 0
Case 36:
Lcd_textbuffer = "321 RIGHT Delete DF"
!Call Restore_label
Data 0 , 0 , 32 , 76
Case 37: '1234
Gosub_adr = Loadlabel(datalogger_logcount)
!Call Restore_label
Data 0 , 0 , 33 , 0
Case 38:
Lcd_textbuffer = "341 RIGHT Print9600B"
!Call Restore_label
Data 0 , 0 , 34 , 78
Case 40:
Lcd_textbuffer = "4 ADC"
!Call Restore_label
Data 30 , 50 , 0 , 41
Case 41:
Lcd_textbuffer = "41 Temperature"
!Call Restore_label
Data 0 , 42 , 40 , 45
Case 42:
Lcd_textbuffer = "42 Voltage"
!Call Restore_label
Data 41 , 43 , 40 , 46
Case 43:
Lcd_textbuffer = "43 ADC Port RAW"
!Call Restore_label
Data 42 , 44 , 40 , 47
Case 44:
Lcd_textbuffer = "44 Battery"
!Call Restore_label
Data 43 , 0 , 40 , 48
Case 45: '+24°C
Gosub_adr = Loadlabel(temperaturefunc)
!Call Restore_label
Data 0 , 0 , 41 , 0
Case 46: '0 mV
Gosub_adr = Loadlabel(voltagefunc)
!Call Restore_label
Data 0 , 0 , 42 , 0
Case 47: 'CH:RAW
Gosub_adr = Loadlabel(adc_raw_func)
!Call Restore_label
Data 0 , 0 , 43 , 0
Case 48: '2900mV
Gosub_adr = Loadlabel(adc_batt_func)
!Call Restore_label
Data 0 , 0 , 44 , 0
Case 50:
Lcd_textbuffer = "5 Options"
!Call Restore_label
Data 40 , 0 , 0 , 51
Case 51:
Lcd_textbuffer = "51 LCD contrast"
!Call Restore_label
Data 0 , 52 , 50 , 56
Case 52:
Lcd_textbuffer = "52 Bootloader"
!Call Restore_label
Data 51 , 53 , 50 , 57
Case 53:
Lcd_textbuffer = "53 LCD OFF"
!Call Restore_label
Data 52 , 54 , 50 , 83
Case 54:
Lcd_textbuffer = "54 LCD Auto Power"
!Call Restore_label
Data 53 , 55 , 50 , 58
Case 55:
Lcd_textbuffer = "55 Key Click"
!Call Restore_label
Data 54 , 0 , 50 , 59
Case 56: '0...15
Gosub_adr = Loadlabel(setcontrast)
!Call Restore_label
Data 0 , 0 , 51 , 0
Case 57:
Lcd_textbuffer = "521 RIGHT bootloader"
!Call Restore_label
Data 0 , 0 , 52 , 87
Case 58: 'OFF/5..90min
Gosub_adr = Loadlabel(autopower)
!Call Restore_label
Data 0 , 0 , 54 , 0
Case 59: 'ON/OFF
Gosub_adr = Loadlabel(keyclick_set)
!Call Restore_label
Data 0 , 0 , 55 , 0
'Untermenüs zu State 25 bis 28
Case 65: 'sub for "211 Adjust Clock"
Gosub_adr = Loadlabel(setclock)
!Call Restore_label
Data 67 , 0 , 23 , 0
Case 66: 'sub for "221 Adjust Date"
Gosub_adr = Loadlabel(setdate)
!Call Restore_label
Data 0 , 68 , 24 , 0
Case 67: 'sub for "212 Clock Format"
Gosub_adr = Loadlabel(setclockformat)
!Call Restore_label
Data 0 , 65 , 23 , 0
Case 68: 'sub for "222 Date Format"
Gosub_adr = Loadlabel(setdateformat)
!Call Restore_label
Data 66 , 0 , 24 , 0
'Untermenüs zu State 36 und 38
Case 76: 'sub for "321 RIGHT Delete DF"
Gosub_adr = Loadlabel(datalogger_erase)
!Call Restore_label
Data 0 , 0 , 36 , 0
Case 78: 'sub for "341 RIGHT Print9600B"
Gosub_adr = Loadlabel(datalogger_rs232)
!Call Restore_label
Data 0 , 0 , 38 , 0
'Untermenü zu State 53 und 57
Case 83: 'sub for "53 LCD OFF"
Gosub_adr = Loadlabel(power_off_func)
!Call Restore_label
Data 0 , 0 , 53 , 0
Case 87: 'sub for "521 RIGHT bootloader"
Gosub_adr = Loadlabel(bootfunc)
!Call Restore_label
Data 0 , 0 , 57 , 0
'Error Handling
Case Else
State = 10
!Call Restore_label
Data 0 , 0 , 0 , 0
End Select
Return
'---------------------------------------------------------------
'Subroutine: Restore_label
'Call from: State_detect
'Purpose: Ersatz für RESTORE Label, erspart das Setzen der Labels für DATA
'Result: Pointer ZH:ZL steht auf der Rücksprungadresse => DATA aa,bb,cc,dd
'---------------------------------------------------------------
Restore_label:
Pop ZH 'R31
POP ZL 'R30
LSL ZL 'Multipliziere Adr mit 2
ROL ZH
'this is a return from Sub State_detect to main loop
Return
'********* 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
State_renew = 0
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 = 32 '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 = 34 'St_datalogger_rs232 as 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 = 10 'St_avrbf as next status of state machine
State_renew = 1
Return
Power_off_func:
'LCD OFF
State = 53 'Return State is 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
Lesezeichen