Code:
Const Ok = 1
Const Not_ok = 0
Const Yes = 1
Const No = 0
Const Op = 2
Const Minus = 3
$regfile = "m16def.dat"
$crystal = 16000000
Const Print_ausgabe = No 'hier Yes/No um die Prints zu aktivieren
Const Use_double = No 'hier Yes/No um mit Double/Single zu rechnen
Const Enable_power = No 'hier Yes/No um den Power-Operator zu aktivieren
'Power und Double funktioniert nicht richtig, keine Ahnung warum
#if Print_ausgabe = Yes
$baud = 38400
#endif
$hwstack = 32
$swstack = 32
$framesize = 64
Config Lcd = 20 * 4
Config Lcdpin = Pin , Db4 = Porta.3 , Db5 = Porta.2 , Db6 = Porta.1 , Db7 = Porta.0 , E = Porta.5 , Rs = Porta.4 ', Rw = Portc. 5
Dim Positionzeile As Byte
Dim Positionspalte As Byte
#if Use_double = Yes
Dim Ergebnis As Double , Operand1 As Double , Operand2 As Double 'auskommentieren um nur Single zu rechnen
#else
Dim Ergebnis As Single , Operand1 As Single , Operand2 As Single 'auskommentieren, um Double zu rechnen
#endif
Dim Prta As Byte , Prtb As Byte , Prtd As Byte , Prtc As Byte 'die Masken der Ports, 1=wird verwendet, 0=wird nicht verwendet
Dim Port_masken As Long At Prta Overlay 'Long liegt über allen 4 Masken
Dim Alte_taste As Long
Dim Tastea As Byte , Tasteb As Byte , Tasted As Byte , Tastec As Byte 'Reihenfolge nicht ändern, sonst passt das Overlay nicht mehr
Dim Taste As Long At Tastea Overlay 'Long liegt über allen 4 Tasten-Ports
Dim Taste_string As String * 32 'definiert, welche Funktion auf welchem Pin liegt
Dim Taste_array(1) As Byte At Taste_string Overlay 'darüber ein Byte Array, damit man leichter eine Schleife drüber machen kann
Dim Taste_index As Byte
Dim Operator As String * 1 'das gefundene Operator Zeichen
Dim Operator_pos As Byte 'Position des Operators in Rechnung$
Dim Rechnung$ As String * 33 'die gesamte Eingabe
Dim String_length As Byte 'die Länge von Rechnung$
Dim Operand$(2) As String * 16 'die beiden Operanden
Dim Check As Byte 'gültige Eingabe
Dim Found As Byte 'alle Flags
Operation Alias 0 'es wurde schon ein Operator eingegeben
Comma_op1 Alias 1 'Komma in Operator 1 gefunden
Comma_op2 Alias 2 'Komma in Operator 2 gefunden
Minus_op1 Alias 3 'Operand 1 ist negativ
Minus_op2 Alias 4 'Operand 2 ist negativ
Prta = &B11000000
Prtb = &B00011111
Prtc = &B11110111
Prtd = &B10111100
Porta = Prta
Portb = Prtb
Portc = Prtc
Portd = Prtd
Initlcd
Cls
Cursor Off
Locate 2 , 1
Lcd "Taschenrechner"
Positionzeile = 1
Positionspalte = 1
' 123456789 123456789 123456789 12 Position in Taste_string = Taste_index
' AAAAAAAABBBBBBBBDDDDDDDDCCCCCCCC Dies ist meine Tastenbelegung
' 01234567012345670123456701234567 geringfügig anders als die ursprüngliche
#if Enable_power = Yes
Taste_string = " */01234 789+ -56^ .=CD" 'C=Clear all, D=Delete ein Zeichen
Prtc = &B11110111 ' 11101111
#else
Taste_string = " */01234 789+ -56 .=CD" 'C=Clear all, D=Delete ein Zeichen
Prtc = &B11110111 ' 11001111
#endif
Prtd = &B10111100 ' 00111101
Prtb = &B00011111 ' 11111000
Prta = &B11000000 '00000011
'weiteres Zeichen hinzufügen:
' 123456789 123456789 123456789 12
'Taste_string = " */01234 789+ -56^ .=CD" neues Zeichen an eine Leerstelle setzen
'Prtc = &B11110111 ' 11001111 im zugehörigen Port eine 1 setzen
'Prtd = &B10111100 ' 00111101
'Prtb = &B00011111 ' 11111000
'Prta = &B11000000 '00000011
'im Select case taste_index für die Position im String ein case schreiben
Porta = Prta 'setzen der PullUps
Portb = Prtb 's.o.
Portc = Prtc 's.o.
Portd = Prtd 's.o.
String_length = 0
Do
Tastea = Pina And Prta
Tasteb = Pinb And Prtb
Tastec = Pinc And Prtc ' c d b a
Tasted = Pind And Prtd '11110100 10111110 00011111 11000000
If Taste <> Port_masken Then
If Taste <> Alte_taste Then
Alte_taste = Taste
Taste_index = 0
Check = Not_ok
If Rechnung$ = "" Then Lcd Spc(20)
Do
If Port_masken.taste_index = 1 Then
If Taste.taste_index = 0 Then
Incr Taste_index
Select Case Taste_index
Case 9 To 13 : '01234 die Zahlen
Check = Ok
Case 19 To 21 : '789
Check = Ok
Case 25 To 26 : '56
Check = Ok
#if Enable_power = Yes
Case 7 To 8 Or Taste_index = 22 Or Taste_index = 27: '*****/////+++++^^^^^
#else
Case 7 To 8 Or Taste_index = 22: '*****/////+++++
#endif
If Found.operation = No Then 'die Operatoren, außer '-' wegen Vorzeichen-Sonderbehandlung
Check = Op
Found.operation = Yes
Operator_pos = String_length + 1
Operator = Chr(taste_array(taste_index))
End If
Case 29 : '.....
If Found.operation = No Then 'wenn noch kein Operator eingegeben wurde, ist das Komma im 1. Operanden
If Found.comma_op1 = No Then
Check = Ok
Found.comma_op1 = Yes
End If
Else
If Found.comma_op2 = No Then 'ansonsten im 2. Operanden
Check = Ok
Found.comma_op2 = Yes
End If
End If
Case 24: '-----
If String_length = 0 Then 'Fortsetzung der Berechnung mit letztem Ergebnis als Operand 1
If Found.operation = No Then 'dann muss der Operator als erstes Zeichen kommen, also kein Vorzeichen
Check = Op
Found.operation = Yes
Operator_pos = String_length + 1
Operator = "-"
End If
Elseif Found.operation = Yes Then 'wenn schon ein Operator eingegeben wurde, ist das '-' ein Vorzeichen des 2. Operanden
Found.minus_op2 = Yes
Check = Minus
Else
Found.minus_op1 = Yes 'dann muss das Vorzeichen des 1. Operanden sein
Check = Minus
End If
Case 32: 'D = Delete: ein zeichen löschen
Positionspalte = Positionspalte - 1
Locate Positionzeile , Positionspalte : Lcd " "
If Right(rechnung$ , 1) = "." Then
If Found.operation = Yes Then
Found.comma_op2 = No
Else
Found.comma_op1 = No
End If
Elseif Operator_pos = String_length Then
Found.operation = No
End If
Decr String_length
Rechnung$ = Left(rechnung$ , String_length)
Check = Not_ok
Case 31: 'C = Clear: alles löschen
Cls 'alles zurücksetzen
Positionspalte = 1
Positionzeile = 1
Rechnung$ = ""
Found = 0
Operator_pos = 0
Check = Not_ok
String_length = 0
Case 30: '=====
If Operator_pos > 1 Then
Decr Operator_pos 'Operand 1 endet links vom Operator
Operand$(1) = Left(rechnung$ , Operator_pos)
Operand1 = Val(operand$(1))
Operator_pos = Operator_pos + 1 'Operand 2 beginnt rechts vom Operator
Else 'Fortsetzung einer Berechnung
Operand1 = Ergebnis
Operand$(1) = Str(operand1)
Incr Operator_pos
End If
Operator_pos = String_length - Operator_pos
Operand$(2) = Right(rechnung$ , Operator_pos)
#if Print_ausgabe = Yes
Print Operand$(1) ; Operand$(2)
#endif
Operand2 = Val(operand$(2))
Select Case Operator
Case "+" : Ergebnis = Operand1 + Operand2
Case "-" : Ergebnis = Operand1 - Operand2
Case "*" : Ergebnis = Operand1 * Operand2
Case "/" : Ergebnis = Operand1 / Operand2
#if Enable_power = Yes
Case "^" : Ergebnis = Power(operand1 , Operand2)
#endif
End Select
Locate 2 , 1 : Lcd Spc(20)
Locate 2 , 1 : Lcd Ergebnis : Locate 1 , 1
#if Print_ausgabe = Yes
Print "ergebnis=" ; Ergebnis
#endif
Ergebnis = Operand1 ^ Operand2
Locate 2 , 20 : Lcd Ergebnis : Locate 1 , 1
Print "ergebnis=" ; Ergebnis
Positionspalte = 1 'alles zurücksetzen, nur Ergebnis bleibt auf dem alten Wert
Positionzeile = 1
Rechnung$ = ""
Found = 0 'alle Flags auf 0
Operator_pos = 0
Check = Not_ok
String_length = 0
End Select
If Check <> Not_ok Then 'wenn die Eingabe erlaubt war, wird das Zeichen ausgegeben und an Rechnung$ angehangen
Locate Positionzeile , Positionspalte ' Zahl 0 schreiben
Lcd Chr(taste_array(taste_index))
Positionspalte = Positionspalte + 1
Rechnung$ = Rechnung$ + Chr(taste_array(taste_index))
Incr String_length
#if Print_ausgabe = Yes
Print "Rechnung=" ; Rechnung$
#endif
End If
Exit Do
Decr Taste_index
End If
End If
Incr Taste_index
Loop Until Taste_index = 32
Waitms 200 'zum Tasten entprellen
End If
Else
Alte_taste = Port_masken 'wenn keine taste mehr gedrückt ist (dann ist Taste = Port_Masken) wird Alte_Taste auch zurückgesetzt
End If
Loop
End
Es können beim Compilieren über die Schalter
Lesezeichen