Also ich verwende 2 Hardware Uarts. Es ist so das der µC als Buskoppler fungieren soll. d.h. er ist Master und Slave zugleich. UART1 ist die Schnittstelle zum Hauptbus und die UART0 ist die Schnittstelle zum "Kartenbus". Dort sollen bis zu 6 weitere µC angeschlossen werden die dann Zyklisch abgefragt werden. deren Daten sollen dann auf Anfrage vom Hauptbus abgeholt werden können. Ich hoffe ihr versteht was ich meine.
So wie das Program im Moment ist funktioniert es auch. Aber zu langsam. Ich Suche einen Weg wie man es schneller machen kann. Schaut es euch mal an, vielleicht habt ihr eine Idee. Aktuelle Version ist ohne Interrupts mit Zyklischer Bufferabfrage, da es mit Interrupts ja nicht funktioniert hat. Ich hoffe ihr könnt mir helfen.
Code:'-------------------------------------------------------------- ' S-Bus-Koppler ' '-------------------------------------------------------------- $regfile = "m162def.dat" ' specify the used micro $crystal = 8000000 ' used crystal frequency ' use baud rate (Rackbus) $baud = 38400 ' baud rate for second serial port (Hauptbus) $baud1 = 38400 $hwstack = 42 ' default use 32 for the hardware stack $swstack = 40 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space ' Lib für die automatische Sende- Empfangsumschaltung $lib "modbus.lbx" ' Com1 (Rackbus) Schnitstelle auf 9 Bit Modus konfigurieren Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 9 , Clockpol = 0 ' Com2 (Hauptbus) Schnitstelle auf 9 Bit Modus konfigurieren Config Com2 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 9 , Clockpol = 0 ' use OPEN/CLOSE for using the second UART Open "COM2:" For Binary As #1 Echo Off Enable Interrupts ' MPCM (MULTI PROCESSOR COMMUNICATION MODE) auf Hauptbus einschalten Ucsr1a.mpcm = 1 ' PORTS DEKLARIEREN Rs485dir Alias Portd.2 Config Rs485dir = Output Rs485dir = 0 'Auf Empfangsmodus schalten ' Pin für die Sende-Empfangsumschaltung UART Config Print = Portd.2 , Mode = Set Rs485dir1 Alias Portb.1 Config Rs485dir1 = Output Rs485dir1 = 0 'Auf Empfangsmodus schalten ' Pin für die Sende-Empfangsumschaltung UART1 Config Print1 = Portb.1 , Mode = Set Declare Function Checksumme_berechnen(byref Datenbereich As Byte) As Byte ' Empfangspuffer UART Config Serialin = Buffered , Size = 150 ' Sendepuffer UART Config Serialout = Buffered , Size = 150 ' Empfangspuffer UART1 Config Serialin1 = Buffered , Size = 150 ' Sendepuffer UART1 Config Serialout1 = Buffered , Size = 150 ' TIMER ' Watchdog Timer / LED Config Timer1 = Timer , Prescale = 256 ' Timer konfigurieren On Timer1 Timerroutine1 ' Timerinterrupt Subroutine zuweisen Enable Timer1 ' Timer aktivieren Stop Timer1 ' Timer stoppen Timer1 = 34286 ' Timer auf neuen Startwert einstellen (1s) ' Timeout Timer Config Timer3 = Timer , Prescale = 256 ' Timer konfigurieren On Timer3 Timerroutine3 ' Timerinterrupt Subroutine zuweisen Enable Timer3 ' Timer aktivieren Stop Timer3 ' VARIABLENDEKLARATION Dim Koppleradresse As Byte Dim Empfangeneadresse As Byte Dim Kopplerstatusbyte As Byte Dim Kopplersteuerbyte As Byte Dim Kartenadresse As Byte Kartenadresse = 255 ' Startwert Dim Anzahl_karten As Byte Dim Aktuelle_karte As Byte Aktuelle_karte = 1 Dim Folge_karte As Byte ' Teilnehmer Speicherbereiche Dim An_k1 As Word Dim Von_k1 As Word Dim An_k2 As Word Dim Von_k2 As Word Dim An_k3 As Word Dim Von_k3 As Word Dim An_k4 As Word Dim Von_k4 As Word Dim An_k5 As Word Dim Von_k5 As Word Dim An_k6 As Word Dim Von_k6 As Word Dim An_k7 As Word Dim Von_k7 As Word Dim Sendeword As Word Dim Empfangsword As Word Dim Empfangene_kartenadresse As Byte Dim Schritt1 As Bit Schritt1 = 1 Dim Schritt1a As Bit Dim Schritt2 As Bit Dim Schritt2a As Bit Dim Schritt3 As Bit Dim Sendeschritt1 As Bit Dim Sendeschritt2 As Bit Dim Err_falscher_teilnehmer As Bit Dim Err_fehlende_antwort As Bit Dim Err_falsche_protokolllaenge As Bit Dim Rack_bus_error As Bit Dim Karten_error As Bit Dim Watch_dog As Bit Dim Watchdogtimer As Bit ' Variablen zur Datenabwicklung UART / R-Bus Dim Rs485_count1 As Word ' Variablen zur Datenabwicklung UART1 / S-Hauptbus Dim Rs485_1_count1 As Word Dim S_bus_empfangsarray(15) As Byte Dim S_bus_sendearray(15) As Byte Dim S_bus_empfangschecksum As Byte Dim S_bus_sendechecksum As Byte Dim Datenmodus As Bit ' KOPPLERADRESSE ERRECHNEN If Code1 = 0 Then Koppleradresse = Koppleradresse + 1 End If If Code2 = 0 Then Koppleradresse = Koppleradresse + 2 End If If Code3 = 0 Then Koppleradresse = Koppleradresse + 4 End If If Code4 = 0 Then Koppleradresse = Koppleradresse + 8 End If If Code5 = 0 Then Koppleradresse = Koppleradresse + 16 End If If Code6 = 0 Then Koppleradresse = Koppleradresse + 32 End If If Code7 = 0 Then Koppleradresse = Koppleradresse + 64 End If If Code8 = 0 Then Koppleradresse = Koppleradresse + 128 End If ' Kopleradresse auf 255 begrenzen If Koppleradresse >= 255 Then Koppleradresse = 255 End If ' Koppleradresse für das Sendearray festlegen S_bus_sendearray(1) = Koppleradresse ' ANZAHL DER ANGESCHLOSSENEN KARTEN ERMITTELN Ermittlung: ' Restdaten im Eingangspuffer löschen Clear Serialin ' Gesendete Daten als Adresse deklarieren (TXB8 High = Adresse ; TXB8 Low = Daten) Ucsr0b.txb8 = 1 ' Anfrage an Kartenr. X senden Printbin Kartenadresse ; ' Die Karte hat 10ms Zeit zu antworten Waitms 10 ' Überprüfen ob ein Zeichen im Empfangspuffer wartet. ' Wenn ja, das Zeichen abrufen und... If _rs_bufcountr0 > 0 Then If _rs_bufcountr0 = 1 Then ' Teilnehmer hat seine Adresse korrekt zurück gesendet Inputbin Empfangene_kartenadresse ' Nur Karten die Ihre Adresse korrekt übermitteln werden Registriert If Empfangene_kartenadresse = Kartenadresse Then ' ...Eine Karte hinzu addieren Incr Anzahl_karten ' ...Kartenadresse um eins verringern Decr Kartenadresse ' Nach einer weiteren Karte suchen Goto Ermittlung End If End If ' wenn keine Rückmeldung, dann keine Karte gefunden... Else ' Restdaten im Eingangspuffer löschen Clear Serialin ' ... und Schleife wird verlassen End If ' HAUPTSCHLEIFE Do ' RINGABFRAGE DER KARTEN If Schritt1 = 1 And Anzahl_karten > 0 And Anlaufphase = 0 Then Clear Serialin ' Watchdogtimer starten Start Timer1 ' Sendedaten und Kartenadresse zuordnen If Aktuelle_karte = 1 Then Kartenadresse = 255 Sendeword = An_k1 End If If Aktuelle_karte = 2 Then Kartenadresse = 254 Sendeword = An_k2 End If If Aktuelle_karte = 3 Then Kartenadresse = 253 Sendeword = An_k3 End If If Aktuelle_karte = 4 Then Kartenadresse = 252 Sendeword = An_k4 End If If Aktuelle_karte = 5 Then Kartenadresse = 251 Sendeword = An_k5 End If If Aktuelle_karte = 6 Then Kartenadresse = 250 Sendeword = An_k6 End If ' Sendedaten als Adresse deklarieren (TXB8 High = Adresse ; TXB8 Low = Daten) Ucsr0b.txb8 = 1 Schritt1a = 1 Schritt1 = 0 End If ' Warten bis das TXB8 bit gesetzt ist If Schritt1a = 1 And Ucsr0b.txb8 = 1 Then ' Daten an Karte senden Printbin Kartenadresse ; ' Schritt2 für das Empfangen freigeben Schritt1a = 0 Schritt2 = 1 End If ' Auf Rückmeldung der Karte warten If Schritt2 = 1 Then ' Ein Byte wurde empfangen If _rs_bufcountr0 > 0 Then Err_fehlende_antwort = 0 ' Quelladresse auslesen und mit gesendeter vergleichen Inputbin Empfangene_kartenadresse ' Die richtige Karte hat geantwortet If Empfangene_kartenadresse = Kartenadresse Then ' Sende Daten als Daten deklarieren (TXB8 High = Adresse ; TXB8 Low = Daten) Ucsr0b.txb8 = 0 Schritt2a = 1 Schritt2 = 0 Else Schritt2 = 0 Err_falscher_teilnehmer = 1 End If Else Err_fehlende_antwort = 1 End If End If ' Warten bis das TXB8 bit zurückgesetzt ist If Schritt2a = 1 And Ucsr0b.txb8 = 0 Then ' Daten an Karte senden Printbin Sendeword ; Schritt2a = 0 Schritt3 = 1 End If ' Auf Daten von der Karte warten If Schritt3 = 1 Then ' Wenn erstes Byte der Daten empfangen dann... If _rs_bufcountr0 > 0 Then Err_fehlende_antwort = 0 Err_falsche_protokolllaenge = 1 ' Sind beide Bytes im Puffer eingegangen, dann... If _rs_bufcountr0 = 2 Then ' Empfangszähler erhöhen Incr Rs485_count1 ' 5 Zyklen lang warten ob weitere Bytes eingehen... If Rs485_count1 > 5 Then Rs485_count1 = 0 ' Stimmt die Anzahl an Daten noch überein, dann... If _rs_bufcountr0 = 2 Then Err_falsche_protokolllaenge = 0 ' Empfangswort auslesen Inputbin Empfangsword ' Empfangene Daten auf Speicherbereiche verteilen. If Aktuelle_karte = 1 Then Von_k1 = Empfangsword End If If Aktuelle_karte = 2 Then Von_k2 = Empfangsword End If If Aktuelle_karte = 3 Then Von_k3 = Empfangsword End If If Aktuelle_karte = 4 Then Von_k4 = Empfangsword End If If Aktuelle_karte = 5 Then Von_k5 = Empfangsword End If If Aktuelle_karte = 6 Then Von_k6 = Empfangsword End If ' Aktuellen Teilnehmer um eins erhöhen Incr Aktuelle_karte ' Alle Teilnehmer durchgelaufen, wieder von vorne beginnen If Aktuelle_karte > Anzahl_karten Then Aktuelle_karte = 1 End If ' WatschdogTimer zurücksetzen bzw. auf neuen Startwert einstellen (1s) Timer1 = 34286 ' Schritt3 beenden Schritt3 = 0 ' Schritt1 starten Schritt1 = 1 End If End If End If Else Err_fehlende_antwort = 1 End If End If ' BUSKOPPLER WIRD ANGESPROCHEN ' Wenn erstes Byte eines Protokolls empfangen dann... If _rs_bufcountr1 > 0 Then ' Der Koppler befindet sich im Adressmodus If Datenmodus = 0 Then ' Adresse auslesen Inputbin #1 , S_bus_empfangsarray(1) , 1 ' Adresse mit eingestellter Koppleradresse vergleichen und prüfen ob Daten für mich. If S_bus_empfangsarray(1) = Koppleradresse Then ' Weiter mit Sendeschritt1 Sendeschritt1 = 1 End If End If ' Der Koppler befindet sich im Datenmodus If Datenmodus = 1 Then ' Sind die geforderten 14 Byte eingetroffen If _rs_bufcountr1 = 14 Then Incr Rs485_1_count1 ' 10 Zyklen lang warten ob weitere Bytes eingehen. If Rs485_1_count1 > 10 Then Rs485_1_count1 = 0 ' Ist die Anzahl an Bytes noch korrekt, dann... If _rs_bufcountr1 = 14 Then ' Lese 14 Bytes aus dem Empfangspuffer und schreibe in Array ab Position 2 Inputbin #1 , S_bus_empfangsarray(2) , 14 ' Checksumme der empfangenen Bytes berechnen S_bus_empfangschecksum = Checksumme_berechnen(s_bus_empfangsarray(1)) ' Empfangene Checksumme mit errechneter vergleichen If S_bus_empfangschecksum = S_bus_empfangsarray(15) Then ' Empfangene Bytes mappen. Kopplersteuerbyte = S_bus_empfangsarray(2) An_k1 = Makeint(s_bus_empfangsarray(3) , S_bus_empfangsarray(4)) An_k2 = Makeint(s_bus_empfangsarray(5) , S_bus_empfangsarray(6)) An_k3 = Makeint(s_bus_empfangsarray(7) , S_bus_empfangsarray(8)) An_k4 = Makeint(s_bus_empfangsarray(9) , S_bus_empfangsarray(10)) An_k5 = Makeint(s_bus_empfangsarray(11) , S_bus_empfangsarray(12)) An_k6 = Makeint(s_bus_empfangsarray(13) , S_bus_empfangsarray(14)) ' Sende Daten Mappen S_bus_sendearray(2) = Kopplerstatusbyte S_bus_sendearray(3) = Low(von_k1) S_bus_sendearray(4) = High(von_k1) S_bus_sendearray(5) = Low(von_k2) S_bus_sendearray(6) = High(von_k2) S_bus_sendearray(7) = Low(von_k3) S_bus_sendearray(8) = High(von_k3) S_bus_sendearray(9) = Low(von_k4) S_bus_sendearray(10) = High(von_k4) S_bus_sendearray(11) = Low(von_k5) S_bus_sendearray(12) = High(von_k5) S_bus_sendearray(13) = Low(von_k6) S_bus_sendearray(14) = High(von_k6) ' Checksumme der Sendebytes berechnen S_bus_sendechecksum = Checksumme_berechnen(s_bus_sendearray(1)) ' Checksumme an das Sendearray übergeben S_bus_sendearray(15) = S_bus_sendechecksum ' Weiter mit Sendeschritt2 Sendeschritt2 = 1 End If End If End If End If End If End If ' Prüfen ob der Koppler im Empfangsmodus ist If Sendeschritt1 = 1 And Rs485dir1 = 0 Then Waitus 500 ' Timeouttimer starten Start Timer3 ' wenn ja, dann Koppleradresse als Antwort senden Printbin #1 , Koppleradresse ; ' in den Datenmodus schalten Datenmodus = 1 ' MPCM abschalten um Daten empfangen zu können Ucsr1a.mpcm = 0 ' Sendeschritt1 beenden Sendeschritt1 = 0 End If ' Prüfen ob der Koppler im Empfangsmodus ist If Sendeschritt2 = 1 And Rs485dir1 = 0 Then Waitus 500 ' Sende 14 Bytes aus dem Bytearray ab Position 2 Printbin #1 , S_bus_sendearray(2) , 14 ; ' in den Datenmodus abschalten Datenmodus = 0 ' MPCM einschalten um Adressen empfangen zu können Ucsr1a.mpcm = 1 ' Sendeschritt2 beenden Sendeschritt2 = 0 ' TimeoutTimer zurücksetzen (Startwert für eine Sekunde) Timer3 = 34286 End If 'RACK-BUS FEHLER AUSWERTEN UND AUSGEBEN If Watch_dog = 1 Then ' Kopplerstatus n.i.O. Kopplerstatusbyte.7 = 0 ' Ringabfrage der Karten stoppen Schritt1 = 0 Schritt2 = 0 Schritt3 = 0 ' Teilnehmer hat nicht geantwortet If Err_fehlende_antwort = 1 And Fehler_erkannt = 0 Then Fehler_erkannt = 1 ' Fehlercode 8: Teilnehmer antwortet nicht Call Koppler_fehlercode(8) End If ' Falsche Protokolllänge empfangen If Err_falsche_protokolllaenge = 1 And Fehler_erkannt = 0 Then Fehler_erkannt = 1 ' Fehlercode 5: Falsche Protokolllänge empfangen Call Koppler_fehlercode(5) End If ' Unerwarteter Teilnehmer hat geantwortet If Err_falscher_teilnehmer = 1 And Fehler_erkannt = 0 Then Fehler_erkannt = 1 ' Fehlercode 7: Unerwarteter Teilnehmer hat geantwortet Call Koppler_fehlercode(7) End If ' FEHLER GENAUER DEFINIEREN If Karten_error = 0 And Rack_bus_error = 0 Then ' Eine Karte hat nicht innerhalb der vorgegebenen Zeit geantwortet ' Überprüfen ob die nächste Karte Antworten würde. Folge_karte = Aktuelle_karte + 1 If Folge_karte > Anzahl_karten Then Folge_karte = 1 End If ' Kartenadresse der nachfolgenden Karte ermitteln If Folge_karte = 1 Then Kartenadresse = 255 End If If Folge_karte = 2 Then Kartenadresse = 254 End If If Folge_karte = 3 Then Kartenadresse = 253 End If If Folge_karte = 4 Then Kartenadresse = 252 End If If Folge_karte = 5 Then Kartenadresse = 251 End If If Folge_karte = 6 Then Kartenadresse = 250 End If ' Restdaten im Eingangspuffer löschen Clear Serialin ' Gesendete Daten als Adresse deklarieren (TXB8 High = Adresse ; TXB8 Low = Daten) Ucsr0b.txb8 = 1 ' Anfrage an Kartenr. X senden Printbin Kartenadresse ; 'Leerbyte ; Leerbyte; ' Die Karte hat 10ms Zeit zu antworten Waitms 10 ' Ein Zeichen empfangen und... If _rs_bufcountr0 > 0 Then '... es bleibt bei einem Kartenfehler. Karten_error = 1 ' An das Statusbyte übergeben um welche Karte es sich handelt. Kopplerstatusbyte.2 = Aktuelle_karte.2 Kopplerstatusbyte.1 = Aktuelle_karte.1 Kopplerstatusbyte.0 = Aktuelle_karte.0 Else ' Keine Antwort ... '... es handelt sich um einen Rack-Busfehler Rack_bus_error = 1 ' Fehlercode 9: R-Bus gestört, kein Teilnehmer antwortet mehr Call Koppler_fehlercode(9) End If End If ' KARTENFEHLER AN ERROR LED AUSGEBEN If Karten_error = 1 Then Call Blink_code_karten_error End If ' RACKBUSFEHLER AN ERROR LED AUSGEBEN If Rack_bus_error = 1 Then Call Blink_code_rbus_error End If End If Loop







Zitieren

Lesezeichen