RS485 Kommunikation

wer

Neues Mitglied
02. Juli 2012
485
0
0
Sprachen
  1. Assembler
Hallo,

ich hab mal wieder ein seltsames Problem!

Ich habe eine RS485-Kommunikation zwischen zwei AtMega1284p. MC1 überträgt Kommandos an MC2 und MC2 quittiert dies mit einer Nachricht, die aus den folgenden Bytes besteht: 0x40 0x01 0x02 0x00 0x00 0x00 0x6D

Hier ist der Anfang dieser Daten zu sehen:

rs485.gif

Das ist nur B+ gegen Masse. Also nicht das volle Differenzsignal! Deshalb die halbe Amplitude.

Zunächst hatte ich das Problem, daß die Datenübertragung direkt nach der zweiten Null gekappt wurde. Habe dann gesehen, daß Markus in seinem Starlight Projekt ein Wait eingebaut hat, bevor er Data Enable ausgeschalten hat. Nach dem ich dies auch so gemacht habe, liegen alle Daten auf dem Bus.

Jetzt passiert aber folgendes:
MC1 empfängt: 0x40 0x01 0x02 0x00 0x6D
Es werden also zwei Nullen verschluckt!?

Hat dazu jemand eine Idee?

Wolfgang
 
Hallo Wolfgang,

da deine Fragestellung bzw. Beschreibung sehr viel Spielraum für Fantasie läßt, kann ich nur mal raten ...
Wie sendest du die Daten ? Als String (Nullterminiert)? - würde evtl. eine Erklährung liefern - 0x00 terminiert den String, weitere 0x00 werden unterdrückt.

- gp177 -
 
Hallo Wolfgang,

da deine Fragestellung bzw. Beschreibung sehr viel Spielraum für Fantasie läßt, kann ich nur mal raten ...
Wie sendest du die Daten ? Als String (Nullterminiert)? - würde evtl. eine Erklährung liefern - 0x00 terminiert den String, weitere 0x00 werden unterdrückt.

- gp177 -

Ich sende die Daten binär:
Code:
RS485outC:     ; Byte in temp1
	push	temp1
RSCLoop:
	lds	temp1, UCSR0A
	sbrs	temp1, UDRE0
	rjmp 	RSCLoop
	pop	temp1
	sts	UDR0, temp1
	ret

und lese sie ebenso

Code:
RS485inC:
	lds	temp1, UCSR0A
	sbrs	temp1, RXC0
	rjmp	RS485inC			; warten bis Byte angekommen ist
	lds	temp1, UDR0
	ret

Wolfgang
 
Mal testweise versucht, das direkt via TTL-UART zu übertragen?
Was ist mit anderen Telegrammen? Also ohne doppelte Null bzw doppelter Null an anderer Stelle.
Der Empfang ist IRQ-basiert? Dann laß doch mal die ISR-Aufrufe zählen.
Mit dem Oszi kannst Du aber korrekte (alle) Bytes nachvollziehen?
 
Mal testweise versucht, das direkt via TTL-UART zu übertragen?
Nein! Dazu müßte ich so viel umbauen, daß es nicht mehr vergleichbar wäre.
Was ist mit anderen Telegrammen? Also ohne doppelte Null bzw doppelter Null an anderer Stelle.
Die Telegramme von MC1 zu MC2 enthalten auch manchmal doppelte Nullen und das geht. Dabei wird der selbe Code genutzt.
Der Empfang ist IRQ-basiert? Dann laß doch mal die ISR-Aufrufe zählen.
Ich polle.
Mit dem Oszi kannst Du aber korrekte (alle) Bytes nachvollziehen?
Ja, sowohl vor dem RS485 Chip, als auch auf dem RS485-Bus!
 
ich meinte, wenn MC2 ein anderes Telegramm sendet, wird das dann korrekt empfangen? Also mit Tripple-0 an anderer Stelle bzw ohne Tripple-0?

Wenn das in die eine Richtung geht, in die andere nicht, UND beide Seiten dieselben Sende-/Empfangsroutinen verwenden Und das Oszillogramm keine Auffälligkeiten zeigt, ist das meiner Meinung nach kein Hardware-Problem (Störungen etc), noch liegt der Fehler in den eigentlichen Byte-Sende-/-Empfangsroutinen.
Ich denke, daß Dein Programm (MC1) selbst irgendwo den Empfang verschludert. (Entweder nach dem Auslesen und Return (in temp), oder Du rufst die Empfangsroutine da gar nicht erst auf (nach der ersten 0))
Diesbezüglichen Code zeigst Du ja nicht.
 
Diesbezüglichen Code zeigst Du ja nicht.

Das ist die Senderoutine:
Code:
SendOK:	push	temp1		; 0|1
	DEon
	ldi	temp1, '@'
	call	RS485outC

	ldi	temp1, 0xFF	; crc initialisieren
	sts	crc8, temp1

	ldi	temp1, 1
	call	dow_crc
	call	RS485outC

	ldi	temp1, 2
	call	dow_crc
	call	RS485outC

	pop	temp1
	call	dow_crc
	call	RS485outC

	clr	temp1
	call	dow_crc
	call	RS485outC

	call	dow_crc
	call	RS485outC

	call	dow_crc
	call	RS485outC

	lds	temp1, crc8
	call	RS485outC
	
	wait	(1.0)
	DEoff
	ret

Die Unterprogramme dow_crc und RS485outC erhalten temp1.
DEon und DEoff sind macros, die das Schreiben auf den Bus enablen bzw disablen.
wait ist ein Macro, das einen Delay einfügt.
Ich gehe davon aus, daß hier alles stimmt, da wie gesagt, die so gesendeten Daten auch wirklich auf dem Bus liegen.

Und hier die Empfangsroutine:
Code:
Wait4Answer:
	clr	temp1
	sts	OK, temp1
W4A1:	sta	(0.5)
	call	RS485inCT
	brvc	W4A2
	ldi	temp1, 2
	jmp	Serout_error

W4A2:	cpi	temp1, '@'
	brne	W4A1

	ldi	temp1, 0xFF	; CRC initialisieren
	sts	crc8, temp1

	call	RS485inC	; Ziel
	call	dow_crc
	sts	ziel, temp1	

	mov	tempL, temp1
	ldi	temp1, 4
	call	SeroutB
	call	SeroutCRLF

	call	RS485inC	; Quelle
	call	dow_crc
	sts	quelle, temp1	

	mov	tempL, temp1
	ldi	temp1, 4
	call	SeroutB
	call	SeroutCRLF

	call	RS485inC	; Code
	call	dow_crc
	sts	code, temp1	

	mov	tempL, temp1
	ldi	temp1, 4
	call	SeroutB
	call	SeroutCRLF

	call	RS485inC	; Data1
	call	dow_crc
	sts	data1, temp1	

	mov	tempL, temp1
	ldi	temp1, 4
	call	SeroutB
	call	SeroutCRLF

; hier kommt nix mehr
	call	RS485inC	; Data2
	call	dow_crc
	sts	data2, temp1	

	mov	tempL, temp1
	ldi	temp1, 4
	call	SeroutB
	call	SeroutCRLF

	call	RS485inC	; Data3
	call	dow_crc
	sts	data3, temp1	

	mov	tempL, temp1
	ldi	temp1, 4
	call	SeroutB
	call	SeroutCRLF

	call	RS485inC	; CRC
	call	dow_crc

	mov	tempL, temp1
	ldi	temp1, 4
	call	SeroutB
	call	SeroutCRLF

	lds	temp1, crc8
	cpi	temp1, 0
	breq	noCrcError
	ldi	temp1, 255
	jmp	Serout_error

noCrcError:
	ldi	temp1, 1
	sts	OK, temp1
	ret
RS485inCT liest ein Zeichen mit Timeout. Das Macro sta setzt den Timeoutwert.
SeroutCRLF und SeroutB sind Unterprogramme, die einen Zeilenvorschub bzw. ein Byte (4-stellig) über die RS232 an einen PC schicken.

Wolfgang
 
Entschuldigung, meine Beobachtung war nicht exakt!

Ich schicke: 0x40, 0x01, 0x02, 0x01, 0x00, 0x00, 0x00, 0x6D ( und nicht: 0x40, 0x01, 0x02, 0x00, 0x00, 0x00, 0x6D wie ich anfangs schrieb!)
Ich empfange: 0x40, 0x01, 0x02, 0x00, 0x6D (also auch die 1 fehlt)

Schicke ich hingegen: 0x40, 0x01, 0x02, 0x01, 0x00, 0x0F, 0x00, 0x6D
so empfange ich: 0x40, 0x01, 0x02, 0x00, 0x75

Die CRCs stimmen jeweils mit den gesendeten Daten überein!

Sende ich: 0x40, 0x01, 0x02, 0x06, 0x05, 0x04, 0x03, 0x07
Bekomme ich: 0x40, 0x01, 0x02, 0x03, 0x07

D.h. mir fehlen jeweils die Bytes 4 bis 6.

Wolfgang
 
Ich schicke hier mal noch das, was ich auf dem Ausgang des Senders (MC2) sehe:

Clipboard01.gif

Ab der zweiten Zeile beginnt alles mit dem letzten Stop-Bit.
Die Binärzahlen enthalten die Start- und die Stop-Bits.

Auf dem BUS sieht das fast genau so aus. Nur ist der Ruhepegel dort low. Der Sender zieht das kurz auf High und legt dann los.

Wolfgang
 
Sicher, daß das Timeout bei der Empfangsroutine paßt? Haste Dir da was eingebaut das anzeigt, wann der mal zugeschlagen hat?

Da Du ja einen LA/Oszi hast, lasse Doch den Empfänger via Bein-toggeln mal kundtun wann erstens ein Byte empfangen wurde (also direkt vor dem ret der Routine), und zweitens (ein anderes Bein) wann ein Timeout erfolgte - und ziechne das zusammen mit dem Bus/Txd auf (das ganze Telegramm).
 
Ich habs!

Das Gequassel mit dem PC dauert zu lange. Hab das jetzt so geändert, daß die Daten nach Empfang des ganzen Datagramms als Block an den PC geschickt werden. Jetzt klapperts.

Danke für die Unterstützung!

Wolfgang
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)