Forum: Mikrocontroller und Digitale Elektronik AVR USART: Eine Byte-Zeit warten


von Bernhard (Gast)


Lesenswert?

Hallo!
In einer RS485-Umgebung möchte ich je nach eingestellter Baudrate vor 
dem Senden immer eine Bytezeit warten damit der Master genug Zeit hat 
seinen Empfänger zu aktivieren.

Gibt es dafür eine bessere Möglichkeit als mit _delay_us oder Timern zu 
arbeiten?

Ich hatte schon probiert ein Dummy-Byte bei abgeschaltetem RS485 
Transceiver zu senden, nur das geht hardwarebedingt nicht überall.
Beim Abschalten des internen Transmitters per TXEN funktioniert der TXC0 
nicht mehr und man kann leider auch temporär den TXD pin per DDR 
Register nicht auf Input schalten.

Irgendeine andere Idee? ;)

Grüße,

Bernhard

von Falk B. (falk)


Lesenswert?

@ Bernhard (Gast)

>Gibt es dafür eine bessere Möglichkeit als mit _delay_us

Eher nicht, das lohnt sich hier kaum.

von c-hater (Gast)


Lesenswert?

Bernhard schrieb:

> Gibt es dafür eine bessere Möglichkeit als mit _delay_us oder Timern zu
> arbeiten?

Leider nicht.

> Beim Abschalten des internen Transmitters per TXEN funktioniert der TXC0
> nicht mehr und man kann leider auch temporär den TXD pin per DDR
> Register nicht auf Input schalten.

So ist es. Der Pinfunction-Override ist leider nicht umgehbar und starr 
an TXEN gekoppelt.

Ich find's auch Scheiße. Wäre es anders, könnte man die USART, die 
heutzutage immer seltener als solche benötigt wird, oftmals als 
zusätzlichen Timer mit durchaus interessanten Fähigkeiten benutzen. Das 
gilt genauso für SPI und (teilweise) USI. Könnte alles mit nur geringem 
zusätzlichen Hardwareaufwand viel universeller nutzbar sein.

Aber es ist halt so, wie es ist, man muß sich mit den Gegebenheiten 
abfinden.

von Peter D. (peda)


Lesenswert?

Bernhard schrieb:
> Ich hatte schon probiert ein Dummy-Byte bei abgeschaltetem RS485
> Transceiver zu senden, nur das geht hardwarebedingt nicht überall.

Warum geht das nicht?
Am RS-485 Transceiver muß man doch das TXEN abschalten, wenn man 
empfangen will.

von Bernhard (Gast)


Lesenswert?

@Peter: Die TXEN-Leitung ist bei manchen Designs leider fest auf TXD 
verdrahtet um sich einen zusätzlichen IO Pin zu sparen. Was auch immer 
sich der Entwickler dabei gedacht hat :)

@c-hater: Ja, es könnte alles viel universeller sein aber mal im Ernst, 
wir sprechen hier von ATmegas... Die sind nicht für sowas gedacht.
Für mächtigere Peripherie und IO-Module geht man dann sowieso auf z.B. 
STM32

von Peter D. (peda)


Lesenswert?

Bernhard schrieb:
> Die TXEN-Leitung ist bei manchen Designs leider fest auf TXD
> verdrahtet um sich einen zusätzlichen IO Pin zu sparen.

Dann hast Du aber keinen RS-485, sondern etwas CAN ähnliches. D.h. nur 
ein Pegel wird aktiv angelegt, der andere nur durch den 
Abschlußwiderstand.

Da aber RS-485 Empfänger entgegengesetzte Pegel sehen wollen, 
funktioniert das entweder gar nicht oder unzuverlässig und auch nur bei 
kleinen Baudraten.
Dein Problem wird also nicht die fehlende Pause sein, sondern die 
Verletzung der RS-485 Spezifikation.

: Bearbeitet durch User
von Bernhard (Gast)


Lesenswert?

@Peter: Dass die Lösung ohne TXEN nicht gut ist, ist mir schon klar.
Die Pause braucht der Master um wieder auf Empfang zu schalten, dabei 
macht es keinen Unterschied ob ich ein Gerät mit fehlerhafter 
RS485-Schnittstelle am Bus habe oder nicht.
Wenn wir uns jetzt weiter an dem Gerät mit der defekten Schnittstelle 
aufhängen bringt das niemanden weiter.

Ich werde mich nun wieder der Pause widmen und diese per _delay_us 
implementieren.

Bevor ich nun einen neuen Thread starte, ist bekannt dass sich die 
beiden USARTS in größeren AVRs wie dem 1284 gegenseitig beeinflussen? 
Liegt da evtl. wie damals beim 323 ein Bug im Chip verborgen?

von Oliver (Gast)


Lesenswert?

Wenn Atmel dazu nichts in den Errata schreibt, ist das denen zumindest 
nicht bekannt.

Wie äussert sich denn die Beeinflussung?

Oliver

von Bernhard (Gast)


Lesenswert?

Der USART1 hat eine fest eingestellte Baudrate und arbeitet im 
Hintergrund problemlos.

Auf dem USART0 kommen Daten mit falscher Baudrate an und es wird das Bit 
FE0 gesetzt (und dann in der ISR gemeinsam mit UDR0 wieder ausgelesen).

Auf dem USART1 werden dann aber auch Fehler gemeldet obwohl die 
Peripherie dort mit dem USART0 gar nichts zu tun hat.
Die Registernamen FE0 im UCSR0A für USART0 und FE1 im UCSR1A für USART1 
werden korrekt abgefragt.

Das Problem ist nicht kritisch, ich wiederhole dann einfach die 
Nachricht. Es ist nur komisch und vielleicht hat ja jemand das auch 
schonmal festgestellt.

von Peter D. (peda)


Lesenswert?

Bernhard schrieb:
> Auf dem USART1 werden dann aber auch Fehler gemeldet obwohl die
> Peripherie dort mit dem USART0 gar nichts zu tun hat.

Wenn der Fehler bei beiden UARTs auftritt, kann es am Takt liegen, z.B. 
Quarz im Low-Power Mode ist recht kritisch, stabiler ist der Full-Swing 
Mode.

Bernhard schrieb:
> Das Problem ist nicht kritisch

Jedes Problem, welches Du nicht löst, wird garantiert mal kritisch.

von der alte Hanns (Gast)


Lesenswert?

Ein Probeaufbau bringt bei mir keinen Fehler der beschriebenen Art:
USART1 läuft korrekt durch trotz FE-Fehler auf USART0.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.