Archiv verlassen und diese Seite im Standarddesign anzeigen : RS485 Datenübertragung
elkokiller
09.12.2006, 22:45
Hallo,
habe mal wieder eine Frage an die RS485 Experten.
Ich habe mir einen kleinen Bus aufgebaut und steuere damit 4 Module (je 5 Relais) an.
Parallel dazu habe ich die Möglichkeit, an jedem Modul per Taster die Relais zu schalten.
Jetzt habe ich festgestellt, dass ich über Rs485 ein Relai z.B. im Modul 1 ansteuern und umschalten kann.
Wenn allerdings im Modul 2 eine örtliche Bedienung stattfindet, reagiert Modul 1 bei einer RS485 ansteuerung nicht mehr.
Ich muss zunächst wieder Modul 1 örtlich bedienen um die RS485 bedienung zu ermöglichen.
Woran kann das liegen?
Meine Busabfrage mache ich über einen Interrupt und folgenden Code
'---------- Einlesen ----------
Onrxd:
Disable Interrupts
Incr N
B(n) = Udr
If N > 9 Then
Preamble = B(1) : Sync = B(2) : Hdb2 = B(3)
Hdb1 = B(4) : Dab1 = B(5)
Sab1 = B(6)
Db1 = B(7)
Db2 = B(8)
Crc2 = B(9)
Crc1 = B(10)
N = 0
Gosub Pruefung
Else
End If
Return
[/code]
Dein Code ist so Aussagekräftig wie die Variablennamen x1,x2,x3,x4,x5,x6,x7,x8
Gento
tja, du disablest die interrupts und wo enablest du die wieder?
Nach dem Disable geht der URXD nämlich nicht mehr
elkokiller
10.12.2006, 15:30
Hallo,
ich habe jetzt versucht, die Interrupts zu enablen.
Leider nicht mit dem gewünschten Erfolg.
Jetzt habe ich meinen gesamten Code angehängt, da sich zwischenzeitlich einige bei mir gemeldet haben, die gerne etwas mehr über die RS485 Steuerung erfahren möchten.
Da das Programm weitestgehend ohne Probleme läuft, kann sich hier jeder etwas abkugen.
Verbesserungsvorschläge nehme ich gerne entgegen!
Vielleicht findet ja auch jemand den oben beschriebenen Fehler im Programm?!
Tobias
'***** RS-485 *************************
' RS485 Ansteuerung von 5 Relais mit Zeitschaltfunktion und manueller vor Ort Bedienung mit Tastern
' Erstellt von Tobias Riesbeck, Dezember 2006
'**************************************
$regfile = "m8def.dat"
$crystal = 7372800
$baud = 4800
'------------------------------------
Config Pind.4 = Input '1 Dil Schalter für Adresse
Config Pind.3 = Input '2 Dieser muss beim programmieren
Config Pinb.4 = Input '3 auf allen Positionen auf 0 stehen
Config Pinb.3 = Input '4
Config Pinc.0 = Input ' Schaltport
Config Pinc.1 = Input
Config Pinc.2 = Input
Config Pinc.3 = Input
Config Pinc.4 = Input
Config Pinc.5 = Input ' N.N.
Config Portb.0 = Output ' Schaltport's
Config Portb.1 = Output
Config Portb.2 = Output
Config Portd.7 = Output
Config Portd.6 = Output
Config Portb.5 = Output ' Kontrollport
Dim T1 As Long
Dim T2 As Long
Dim T3 As Long
Dim T4 As Long
Dim T5 As Long
Dim Zeit1 As Long
Dim Zeit2 As Long
Dim Zeit3 As Long
Dim Zeit4 As Long
Dim Zeit5 As Long
Dim Sz As Long 'Sendezeit
Zeit1 = 20000000 'Flur EG
Zeit2 = 20000000 'Schlafzimmer
Zeit3 = 20000000 'Keller
Zeit4 = 10000000 'Gang
Zeit5 = 20000000 'Flur OG
Dim Myadress As Byte 'Variable Myadress wird für Adresse über Dip Schalter festgelegt
'"Hex(myadress)" gibt die Adresse in Hex-Format aus
Myadress.0 = Pind.4
Myadress.1 = Pind.3
Myadress.2 = Pinb.4
Myadress.3 = Pinb.3
Dim Db1_ As Byte ' db1 zur Aufnahme des Modulzustandes in Hex
T1 = 0
T2 = 0
T3 = 0
T4 = 0
T5 = 0
Sz = 0
Config Portd.2 = Output ' RS485
Config Debounce = 50
Dim I As Byte
Dim Key As Byte
Dim S As String * 10
Dim B(10) As Byte 'At S Overlay
Dim N As Byte
' Adresse festlegen -------------------------------------------------
Dim Preamble_ As Byte 'Preamble-Byte
Dim Sync_ As Byte 'Syncronisation-Byte
Dim Hdb2_ As Byte 'Kopf-Byte 1
Dim Hdb1_ As Byte 'Kopf-Byte 2
Dim Dab1_ As Byte
Dim Crc2_ As Byte 'CRC2
Preamble_ = &H55 'H55
Sync_ = &H54 'H54
Hdb2_ = &H51 'H51
Hdb1_ = &H42 'H42
Dab1_ = &H00
' Protokoll ---------------------------------------------------------
Dim Preamble As Byte 'Preamble-Byte
Dim Sync As Byte 'Syncronisation-Byte
Dim Hdb2 As Byte 'Kopf-Byte 1
Dim Hdb1 As Byte 'Kopf-Byte 2
Dim Dab1 As Byte 'Empfänger-Byte 1
Dim Sab1 As Byte 'Sender-Byte 1 Adresse
Dim Db1 As Byte 'Daten-Byte 1 (in diesem Modul als Hex)
Dim Db2 As Byte 'Date-Byte 2 fals erforderlich
Dim Crc2 As Byte 'CRC2
Dim Crc1 As Byte 'CRC1
Dim Aktion As Byte 'CRC1 als Sender
Const Keys = 5
On Urxc Onrxd
Enable Urxc
Enable Interrupts
Portd.2 = 0 ' R/W für RS485
'---------- Programm ----------
Gosub Zustand
Prog_start:
N = 0
Do
If Sz > 0 Then Sz = Sz + 1
If Sz > 10000 Then Gosub Zustand
'Zeitschalter (Zähler)
If T1 > 0 Then T1 = T1 + 1
If T1 > Zeit1 Then
Portd.6 = 0
T1 = 0
Aktion = &H00
Sz = 1
Else
End If
If T2 > 0 Then T2 = T2 + 1
If T2 > Zeit2 Then
Portb.0 = 0
T2 = 0
Aktion = &H00
Sz = 1
Else
End If
If T3 > 0 Then T3 = T3 + 1
If T3 > Zeit3 Then
Portb.2 = 0
T3 = 0
Aktion = &H00
Sz = 1
Else
End If
If T4 > 0 Then T4 = T4 + 1
If T4 > Zeit4 Then
Portd.7 = 0
T4 = 0
Aktion = &H00
Sz = 1
Else
End If
If T5 > 0 Then T5 = T5 + 1
If T5 > Zeit5 Then
Portb.1 = 0
T5 = 0
Aktion = &H00
Sz = 1
Else
End If
For I = 1 To Keys
Key = I
Select Case Key
Case 1 : Debounce Pinc.0 , 0 , Key_o1 , Sub 'Port 1.
Case 2 : Debounce Pinc.1 , 0 , Key_o2 , Sub 'Port 2
Case 3 : Debounce Pinc.2 , 0 , Key_o3 , Sub 'Port 3
Case 4 : Debounce Pinc.3 , 0 , Key_o4 , Sub 'Port 4
Case 5 : Debounce Pinc.4 , 0 , Key_o5 , Sub 'Port 5
End Select
Next
Loop
End
Key_o1:
Toggle Portb.0 'Buchse 1
Aktion = &HFF
Sz = 1
If T2 = 0 Then
T2 = 1
Else
T2 = 0
End If
Return
Key_o3:
Toggle Portb.2 'Buchse 3
Aktion = &HFF
Sz = 1
If T3 = 0 Then
T3 = 1
Else
T3 = 0
End If
Return
Key_o5:
Toggle Portd.6 'Buchse 4
Aktion = &HFF
Sz = 1
If T1 = 0 Then
T1 = 1
Else
T1 = 0
End If
Return
Key_o4:
Toggle Portd.7 'Buchse 5
Aktion = &HFF
Sz = 1
If T4 = 0 Then
T4 = 1
Else
T4 = 0
End If
Return
Key_o2:
Toggle Portb.1 'Buchse 2
Aktion = &HFF
Sz = 1
If T5 = 0 Then
T5 = 1
Else
T5 = 0
End If
Return
'---------- Einlesen ----------
Onrxd:
Disable Interrupts
Incr N
B(n) = Udr
If N > 9 Then
Preamble = B(1) : Sync = B(2) : Hdb2 = B(3)
Hdb1 = B(4) : Dab1 = B(5)
Sab1 = B(6)
Db1 = B(7)
Db2 = B(8)
Crc2 = B(9)
Crc1 = B(10)
N = 0
Enable Urxc
Enable Interrupts
Gosub Pruefung
Else
End If
Return
'---------- Prüfung ----------
Pruefung: 'SNAP Prüfung der eingehenden Byte
If Sync <> Sync_ Then : Goto Prog_start
Elseif Hdb2 <> Hdb2_ Then : Goto Prog_start
Elseif Hdb1 <> Hdb1_ Then : Goto Prog_start
Elseif Dab1 <> Myadress Then : Goto Prog_start
End If
Gosub Steuerung
Return
'---------- Fernsteuerung Steuerung ----------
Steuerung:
Sz = 1
If Db1 = &H01 Then : Gosub Key_o1 : End If
If Db1 = &H02 Then : Gosub Key_o2 : End If
If Db1 = &H03 Then : Gosub Key_o3 : End If
If Db1 = &H04 Then : Gosub Key_o4 : End If
If Db1 = &H05 Then : Gosub Key_o5 : End If
If Db1 = &H06 Then : Sz = 1 : End If
Db1 = 0
Return
'---------- Übertragung des Zustandes --------
Zustand:
Db1_.0 = Portb.0 'Auswertung der Portzustände
Db1_.1 = Portb.1
Db1_.2 = Portb.2
Db1_.3 = Portd.7
Db1_.4 = Portd.6
Portb.5 = 1 ' Übertragungs LED an
Disable Urxc
Disable Interrupts
Portd.2 = 1 : Waitms 20 'RS485 PIN auf Senden
Print Chr(preamble_) ; Chr(sync_) ;
Print Chr(hdb2_) ; Chr(hdb1_) ;
Print Chr(dab1_) ; Chr(myadress);
Print Chr(db1_) ; Chr(db2);
Print Chr(crc2) ; Chr(aktion) ;
Waitms 100
Do
Loop Until Ucsra.txc = 1
Reset Ucsra.txc
Waitms 10 : Portd.2 = 0 'RS485 PIN auf Enpfang
Enable Urxc
Enable Interrupts
Aktion = ""
Sz = 0
Portb.5 = 0 ' Übertragungs LED aus
N = 0
Return
End
bertl100
10.12.2006, 22:38
Also ich machs mit gepufferten USART ala config serialin
funktioniert prima.
hab noch kosmetische Vorschläge.
die print cht(xy) gefallen mir nicht so recht, find printbin oder
die interruptbasierende Ringpuffervariante mit schreiben
ind UDR-Register schöner, aber das ist Geschmackssache.
Brintbin wär etwas übersichtlicher denk ich.
hinter dem letzten Print die 100ms brauchste eigentlich
nicht, du hast ja den loop dahinter.
ich verwende in Programmen gern die Alias Funktion,
da kann man schön bei jeder Aktion sehen was da
bewirkt werden soll, das macht die Programme schöner
lesbar fürs Debuggen im nachhinein.
Du belegst für mindestens 120ms nach dem senden des letzten
Steuerzeichens den Bus, das könnte etwas zu lang sein,
weil für n µC ist das ne Ewigkeit. versuch mal kürzere Zeiten,
bzw. mach die 100ms mal raus.
In der Mainloop versteh ich den Sinn der For - Next Schleife nicht
für die Debounce-Pinabfrage
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.