'--------------------------------------------------------------------------- ' 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