'---------------------------------------------------------------------------
' c't LAB Universal 1.3 Günter Gerold
'
' Grundgerüst für das C'T-LAB
'
' Empfangen, prüfen und weiterleiten der Befehle im Opto-Bus
' c't-Lab konformer Parser zur Befehlsverarbeitung
' Stefan Esni hat einen Fehler im Mnemonicarr beseitigt, danke!
'---------------------------------------------------------------------------
$regfile = "m32def.dat"
$crystal = 4000000
$baud = 38400
$hwstack = 32
$swstack = 10
$framesize = 40
Config Serialin = Buffered , Size = 63 , Bytematch = 13
Config Serialout = Buffered , Size = 63
Config Watchdog = 512
Config Pind.5 = Input 'Modulnummer +1
Config Pind.6 = Input 'Modulnummer +2
Config Pind.7 = Input 'Modulnummer +4
Enable Interrupts
Echo Off
Declare Sub Writeserinp
Declare Sub Checkserinp
Declare Sub Parser
Dim Serinpstr As String * 63
Dim Serinpbuffer As String * 63
Dim Serinbuffarr(5) As Byte At Serinpbuffer Overlay
Dim Mnemonicbuffer As String * 4
Dim Mnemonicbufferarray(5) As Byte At Mnemonicbuffer Overlay
Dim Cr_received As Bit
Dim Strsize As Byte
Dim Mymainchannel As Byte
Dim Mainchannel As Byte
Dim Subchannel As Word
Dim Wert As Single
Dim Frage As Bit
Dim Zeichenpos As Byte
Dim Doppelpunkt As String * 1
Doppelpunkt = ":"
Dim Istgleich As String * 1
Istgleich = "="
Dim Mnemonicarr(25) As String * 3
Mnemonicarr(1) = "TRG" ' 249 = manuelle Trigger-Ausl?sung
Mnemonicarr(2) = "STR" ' 255 = Status,
Mnemonicarr(3) = "IDN" ' 254 = Identifikation ohne Parameter
Mnemonicarr(4) = "VAL" ' 0 = Value
Mnemonicarr(5) = "OFS" ' 100 = Offsets
Mnemonicarr(6) = "SCL" ' 200 = Skalierungen
Mnemonicarr(7) = "RAW" ' 50 = Roh-AD-Werte
Mnemonicarr(8) = "PIO" ' 30 = Ports I/O
Mnemonicarr(9) = "DIR" ' 40 = Ports Datenrichtung
Mnemonicarr(10) = "DSP" ' 80 = Display-Parameter
Mnemonicarr(11) = "ALL" ' 95..99 = Alle Werte, Liste
Mnemonicarr(12) = "OPT" ' 150...159
Mnemonicarr(13) = "TRM" ' 240..243 = Trigger-Masken 0..7, 10..17, (20..27), 30..37
Mnemonicarr(14) = "TRT" ' 247 = Auto-Trigger-Timing in ms, 0=aus
Mnemonicarr(15) = "TRL" ' 248 = Trigger-Edge-Level 0=neg, 1=pos. auf PB2 (INT2)
Mnemonicarr(16) = "ICB" ' 230 = Generic I2C I/O Byte
Mnemonicarr(17) = "ICW" ' 231 = Generic I2C I/O Word/Integer
Mnemonicarr(18) = "ICS" ' 232 = Generic I2C I/O Word Swapped
Mnemonicarr(19) = "ICT" ' 233 = Generic I2C I/O Temperatur
Mnemonicarr(20) = "ICA" ' 239 = Generic I2C I/O Hardware-Adresse setzen
Mnemonicarr(21) = "REF" ' 246 = Ext. Referenz wenn 1, interne wenn 0
Mnemonicarr(22) = "WEN" ' 250 = Write Enable
Mnemonicarr(23) = "ERC" ' 251 = ErrCount seit letztem Reset
Mnemonicarr(24) = "SBD" ' 252 = SerBaud UBRR-Register mit U2X=1
Mnemonicarr(25) = "NOP"
Dim Cmd2subcharr(25) As Byte
Cmd2subcharr(1) = 249
Cmd2subcharr(2) = 255
Cmd2subcharr(3) = 254
Cmd2subcharr(4) = 0
Cmd2subcharr(5) = 100
Cmd2subcharr(6) = 200
Cmd2subcharr(7) = 50
Cmd2subcharr(8) = 30
Cmd2subcharr(9) = 40
Cmd2subcharr(10) = 80
Cmd2subcharr(11) = 95
Cmd2subcharr(12) = 150
Cmd2subcharr(13) = 240
Cmd2subcharr(14) = 247
Cmd2subcharr(15) = 248
Cmd2subcharr(16) = 230
Cmd2subcharr(17) = 231
Cmd2subcharr(18) = 232
Cmd2subcharr(19) = 233
Cmd2subcharr(20) = 239
Cmd2subcharr(21) = 246
Cmd2subcharr(22) = 250
Cmd2subcharr(23) = 251
Cmd2subcharr(24) = 252
Cmd2subcharr(25) = 0
Mymainchannel.0 = Pind.5 'Moduladdresse von den Jumpern holen
Mymainchannel.1 = Pind.6
Mymainchannel.2 = Pind.7
Do
If Cr_received = 1 Then 'wenn was im ser. Buffer ist abholen
Cr_received = 0
Input Serinpstr
'zum Abtrennen eines oder mehrerer LF am Anfang des Strings, das noch vom Vorgänger-String im Buffer steht
While Asc(serinpstr) = 10
Strsize = Len(serinpstr) - 1
Serinpstr = Right(serinpstr , Strsize)
Wend
'Hier ist der String empfangen und ein event. LF entfernt
Call Checkserinp
End If
Reset Watchdog
Loop
'---------------------------------------------------------------------------
' Writeserinp
' Leitet den empfangenen String zum nächsten Modul weiter
'---------------------------------------------------------------------------
Sub Writeserinp
Print Serinpstr ' Befehl Weiterreichen
End Sub
'---------------------------------------------------------------------------
' Serial0charmatch
' Im Eingangspuffer wurde ein "13" empfangen
'---------------------------------------------------------------------------
Serial0charmatch:
Cr_received = 1
Return
'---------------------------------------------------------------------------
' Checkserinp
' Hier der String abgeholt
' Der Mainchannel und der : wird geprüft
'---------------------------------------------------------------------------
Sub Checkserinp
If Asc(serinpstr) = 35 Then 'Strings mit # gleich weiterleiten
Call Writeserinp
Exit Sub
End If
Zeichenpos = Instr(serinpstr , ":")
If Zeichenpos > 0 Then ' Doppelpunkt Gefunden
If Instr(serinpstr , "*") > 0 And Instr(serinpstr , "*") < Zeichenpos Then
Call Writeserinp
Call Parser
Exit Sub
Else 'kein *
Serinpbuffer = Left(serinpstr , Zeichenpos)
Mainchannel = Val(serinpbuffer)
If Mainchannel = Mymainchannel Then
Call Parser
Exit Sub
Else
Call Writeserinp
Exit Sub
End If
End If
Else 'kein :
If Mainchannel = Mymainchannel Then 'Mainchannel müsste noch von vorigem Durchlauf drinstehen
Call Parser
Exit Sub
Else 'anderes Modul
Call Writeserinp
Exit Sub
End If
End If
End Sub
'---------------------------------------------------------------------------
' Parser
' Hier beginnt der Parser
'
'---------------------------------------------------------------------------
Sub Parser
Dim I As Byte
Dim A As Byte
A = 1
Serinpbuffer = ""
Mnemonicbuffer = ""
Wert = 0
Subchannel = 0 'der ":" und alles davor kommt weg
Zeichenpos = Len(serinpstr) - Instr(serinpstr , Doppelpunkt)
Serinpbuffer = Right(serinpstr , Zeichenpos)
For I = 1 To 4 'die nächsten 4 Stellen nach dem Doppelpunkt (4 wegen Leerzeichen)
If Serinbuffarr(i) >= "A" And Serinbuffarr(i) <= "Z" Or Serinbuffarr(i) >= "a" And Serinbuffarr(i) <= "z" Then
Mnemonicbufferarray(a) = Serinbuffarr(i)
Incr A
Mnemonicbufferarray(a) = 0
End If
Next
If Len(mnemonicbuffer) = 3 Then '3 Buchstaben sind angekommen
Mnemonicbuffer = Ucase(mnemonicbuffer)
For I = 0 To 25
If Mnemonicbuffer = Mnemonicarr(i) Then 'passende Zahl suchen
Subchannel = Cmd2subcharr(i)
Exit For
End If
Next
End If
A = 1
Mnemonicbuffer = ""
Zeichenpos = Instr(serinpbuffer , Istgleich)
If Zeichenpos = 0 Then Zeichenpos = Len(serinpbuffer)
For I = 1 To Zeichenpos 'Den ganzen String bis Ende oder = nach Zahlen durchsuchen
If Serinbuffarr(i) >= "0" And Serinbuffarr(i) <= "9" Then
Mnemonicbufferarray(a) = Serinbuffarr(i)
Incr A
Mnemonicbufferarray(a) = 0
End If
Next
Subchannel = Subchannel + Val(mnemonicbuffer) 'gefundene Zahl mit dem Mnemonic addieren
If Instr(serinpbuffer , Istgleich) > 0 Then '= ist vorhanden
Frage = 0
Else
Frage = 1
End If
Zeichenpos = Len(serinpbuffer) - Instr(serinpbuffer , Istgleich)
Serinpbuffer = Right(serinpbuffer , Zeichenpos) 'alles hinter = ist der Wert
Wert = Val(serinpbuffer)
Print "#Modulnummer: " ; Str(mainchannel)
Print "#Subchannel: " ; Subchannel
If Frage = 0 Then
Print "#Wert: " ; Wert
Else
Print "#"
End If
'An dieser Stelle ist alles ausgewertet
'Mainchannel ist die Kartennummer des Befehls
'Subchannel ist der Befehl incl. des Subchannels
'Wert ist der Wert der gesetzt werden soll
'Frage steht auf 1 wenn ein ? im Datensatz vorgekommen ist
End Sub