MAX485: empfängt eine Null, die keine ist

(Firma: FHK) #6848397
Lesenswert?

Hallo!
In meiner Hauselektronik werkelt ein Atmega 2560, indem er mittels 
mehrerer Max485 verschiedene Ein- und Ausgabegeräte ansteuert.
Es läuft alles wunderbar, auch keine Probleme mit Senden/ Empfang wie 
sie hier oftmals beschrieben sind.

Mit einer Einschränkung:
-wenn ich eine Zeichenkette händisch (d.h. langsam, z.B. per Hyperterm) 
sende, empfängt der AVR nach jedem gesendeten Zeichen ein nachgestelltes 
'/0'. Mir scheint, als nehme der MAX485 nach dem Empfang einen Zustand 
ein, den der AVR für ne empfangene '\0' wertet - aber es dürfte doch 
kein Stopp-Bit generiert werden. Kann ich das ggfs durch pull-up 
umgehen?

Beste Grüße und schonmal ein schönes Wochenende!


Ich benutze u.g. Routine.
1
ISR(USART3_RX_vect){
2
  unsigned char nextChar;
3
  nextChar = UDR3;
4
  if( uart3_str_complete == 0 ) {
5
    if( nextChar != '\n' &&  nextChar != '\r' &&  uart3_str_count < UART_MAXSTRLEN ){
6
      uart3_array[uart3_str_count] = nextChar;
7
      uart3_str_count++;}
8
    else {
9
      uart3_array[uart3_str_count] = '\0';
10
      uart3_str_count = 0;
11
      uart3_str_complete = 1;}
12
  }
13
}
(Firma: FHK) #6848415
Lesenswert?

H.Joachim S. schrieb:
> Wie machst du denn die Richtungsumschaltung wenn du vom PC/Hyperterm aus
> sendest?

Das beschriebene Fehlerverhalten tritt völlig unabhängig vom 
Sende/Empfang-Umschalten auf bzw. ich habe sie zur Fehlersuche 
abgeschaltet. Der UART3 lauscht nur und der MAX485 ist die ganze Zeit im 
Empfangs-Modus.



Aber um die Frage dennoch zu beantworten:
1
#define RS485_3_SND_EN  {PORTG |=(1 << 5); _delay_ms(3);}
2
#define RS485_3_RCV_EN  {_delay_ms(3); PORTG &=  ~(1 << 5);}
3

4
void uart3_RS485 (char* string){
5
  RS485_3_SND_EN
6
  uart3_puts(string);
7
  RS485_3_RCV_EN
8
  uart3_flush ();
9
}
10

11
void uart3_flush (void){
12
    uart3_str_count = 0;
13
    uart3_str_complete = 0;
14
}
#6848431
Lesenswert?

Wie ist der RS485 Bus vorgespannt? Da muss ja ein Pullup und ein 
Pulldown dran sein.

Eine "0" (binäre Null) unterscheidet sich nur durch das fehlende Stopp 
Bit von einem "Break". Ein auf Null vorgspannter Bus erzeigt immer ein 
Break wenn der Sender abschaltet.

Unterscheiden kann man das beim Empfänger nur dann wenn man die Status 
Bits auswertet.

Ich spanne daher den RS485 Bus gerne auf "1" vor...
Moderator (Firma: Titel) Persönliche Seite #6848433
Lesenswert?

Stephan R. schrieb:
> Der UART3 lauscht nur und der MAX485 ist die ganze Zeit im Empfangs-Modus.
Und: was macht der 485 Treiber auf der Senderseite?
Aus diesem Grund ist die einzig relevante Frage: was passiert auf dem 
Bus?

Jim M. schrieb:
> Wie ist der RS485 Bus vorgespannt? Da muss ja ein Pullup und ein
> Pulldown dran sein.
Es muss nicht unbedingt einer dran sein, aber dann muss der 
Empfänger eben mit den erratischen Pegeln klarkommen, die sich 
einstellen, wenn kein Sender aktiv ist.
(Firma: FHK) #6848444
Lesenswert?

leo schrieb:
> Ich schätze mal, dass du UTF-16 schickst.

Das Problem tritt auch auf, wenn ich mittels HTerm die Zeichen einzeln 
sende. Oder, was könnte die Verwendung von UTF-16 für mich und den AVR 
bedeuten?

EDIT: wenn ich Hyperterminal und HTerm "verbinde", so kommt im HTerm 
auch stets nur das eine jeweilige im Hyperterminal gesendete Zeichen an. 
Ohne Null.
Moderator (Firma: Titel) Persönliche Seite #6848481
Lesenswert?

Stephan R. schrieb:
> EDIT: wenn ich Hyperterminal und HTerm "verbinde", so kommt im HTerm
> auch stets nur das eine jeweilige im Hyperterminal gesendete Zeichen an.
Wie verbindest du die beiden? Über den RS485-Bus?

Andreas B. schrieb:
> Tip: Kauf Dir einen Saleae clone für 10€ aus der Bucht und installiere
> Dir Pulseview. Das schlägt für so etwas jedes Oszilloskop.
Nochn Tipp: sieh dir trotzdem auch die wirklichen analogen Pegel auf dem 
Bus an. Denn nur das, was dort völlig analog passiert, kann eine 
nachgeschaltete Elektronik in 0 und 1 umwandeln.
(Firma: FHK) #6848543
Lesenswert?

A. S. schrieb:
> Ist sichergestellt, dass sie framing-error erkennt?

Ich befürchte, das sagt mir nicht allzu viel. Hat mich aber auf einen 
Workaround gebracht:

Eine empfangene '\0' wird stets weggeschmissen.
Scheissidee?
1
ISR(USART3_RX_vect){
2
  unsigned char nextChar;
3
  nextChar = UDR3;
4
  if( uart3_str_complete == 0 &&  nextChar != '\0') {  //Da!
5
    if( nextChar != '\n' &&  nextChar != '\r' &&  uart3_str_count < UART_MAXSTRLEN ){
6
      uart3_array[uart3_str_count] = nextChar;
7
      uart3_str_count++;
8
      uart0_putc(nextChar);
9
    }
10
    else {
11
      uart3_array[uart3_str_count] = '\0';
12
      strcpy(uart3_string, uart3_array);
13
      uart3_str_count = 0;
14
      uart3_str_complete = 1;
15
    }
16
  }
17
}

EDIT: es funktioniert.
Gast #6848648
Lesenswert?

Stephan R. schrieb:
> Mir scheint, als nehme der MAX485 nach dem Empfang einen Zustand
> ein, den der AVR für ne empfangene '\0' wertet - aber es dürfte doch
> kein Stopp-Bit generiert werden.

Für ein Stoppbit wird nichts generiert. Ein Stopp-Bit ist lediglich eine 
Pause (Mark-Pegel) von einer Bit-Dauer, bevor das nächste Start-Bit 
kommen darf.
Gast #6848664
Lesenswert?

Jim M. schrieb:
> Eine "0" (binäre Null) unterscheidet sich nur durch das fehlende Stopp
> Bit von einem "Break". Ein auf Null vorgspannter Bus erzeigt immer ein
> Break wenn der Sender abschaltet.
>
> Unterscheiden kann man das beim Empfänger nur dann wenn man die Status
> Bits auswertet.

Zusatzinfo:
Die "break condition" wird hier, mehr oder weniger ausführlich, 
diskutiert:

https://netbsd-users.netbsd.narkive.com/LbW29ucx/what-is-a-serial-break

https://en.wikipedia.org/wiki/Universal_asynchronous_receiver-transmitter#Break_condition

https://groups.google.com/g/beagleboard/c/-_MNJSArsFU
Moderator (Firma: Titel) Persönliche Seite #6848693
Lesenswert?

Stephan R. schrieb:
> Eine empfangene '\0' wird stets weggeschmissen.
So geht ein richtig guter Softwerkerworkaorund!
Der würde gut zum "Schönsaufen" passen:
>>>> Es läuft alles wunderbar, auch keine Probleme mit Senden/ Empfang

Denn schon das stimmt natürlich nicht. Du hast tatsächlich Probleme 
beim Empfangen und siehst mit diesem "Ausnahmefall" erstmal nur die 
Spitze des Eisbergs, ohne die Ursache zu kennen. Und vermutest, dass das 
immer eine 0 ist und die immer am Ende eines Telegramms kommt.
Aber wenn eines deiner Geräte beim sonst durchgängigen Senden einmal am 
Tag eine kurze Pause zwischen 2 Bytes einlegt (evtl. weil ein 
mordswichtiger Interrupt daherkommt), dann hast du eben auch mittendrin 
ab&zu mal so eine korrupte 0. Oder weil der Bus in diesem Augenblick ja 
offen herumfloatet eben irgendwas.

Ich würde aber auch drauf setzen, dass du nur solche Zeichen als 
gültig erkennst, die auch ein gültiges Stopbit haben. Denn wenn 
nicht mal das Stopbit stimmt, dann liegt es nahe, dass der Rest davor 
nicht viel besser ist...
Gast #6848711
Lesenswert?

Bus nachmessen im idle-Zustand.

Wenn kein "failsafe" vorhanden ist das für definierte Pegel sorgt kann 
(abhängig von Leitungslänge, Mondphase und aktuellem Gemütszustand von 
Lady Gaga) das Ausschalten des Senders vom Empfänger als Start-Bit 
interpretiert werden und dann wird ein Byte Mist eingelesen.
Gast #6848790
Lesenswert?

Womit bist du am Bus? FTDI+RS485 Treiber?
Hatte mal den Fall das auf so nem FTDI+Treiber Platinchen die RX/TX 
zwischen FTDI und RS485 Treiber mit Pulldowns statt Pullups bestückt 
waren... Da kam auch immer eine 0 zu viel an..
(Firma: FHK) #6848856
Lesenswert?

Georg schrieb:
> mein Eindruck ist dass der TO
> garnicht weiss wovon die Rede ist

Möglicherweise liegst Du gar nicht so verkehrt, ich dachte stets, ein 
Stoppbit wäre mit einer Pegeländerung verbunden.
Nur, woring liegt der Unterschied zwischen einem Stopbit und einem 
"gesendeten" /0, wenn bei beidem keine Pegeländerungen stattfinden.

Da ich beruflich umorientiert "wurde" und auch mein Labor eingemottet 
ist, wird es ein wenig dauern, bis ich die Signale anschauen und melden 
kann.
Gast #6848861
Lesenswert?

Stephan R. schrieb:
> woring liegt der Unterschied zwischen einem Stopbit und einem
> "gesendeten" /0, wenn bei beidem keine Pegeländerungen stattfinden.

'\0' ist ein Zeichen oder Byte
Und ein Bit ist eben ein Bit, wovon sich häufig 8 zu einem Byte 
gruppieren, und ca 10 Bit in einem UART Frame versammelt sind.
Gast #6848882
Lesenswert?

Georg schrieb:
> mein Eindruck ist dass der TO garnicht weiss wovon die Rede ist, er
> bringt wohl Stopbit und /0 durcheinander.

Ich glaube, ihm ist einfach nicht klar, dass auch bei fehlendem Stopbit 
ein Byte empfangen wird und man deshalb "von Hand" auf Framing Errors 
prüfen muss.

Das Problem selbst dürfte einfach an fehlenden oder vertauschten 
Bias-Widerständen liegen.

Beim Abschalten des Treibers gibt es eine fallende Flanke, und dass die 
nur beim langsamen manuellen Senden stört, liesse sich damit erklären, 
dass der Code nach dem Empfang eines kompletten Pakets nachfolgenden 
Müll ignoriert.

Stephan R. schrieb:
> woring liegt der Unterschied zwischen einem Stopbit und einem
> "gesendeten" /0, wenn bei beidem keine Pegeländerungen stattfinden.

0x00 (korrekt):

1 (Ruhelage) - 0 (Startbit) - 8x 0 (Datenbits) - 1 (Stopbit, entspricht 
dem Ruhepegel)

0x00 (mit Framing Error):

1 (Ruhelage) - 0 (Startbit) - 8x 0 (Datenbits) - Rest egal, kann auch 
dauerhaft auf 0 bleiben.

Resultat: Eine fallende Flanke mit mindestens 9 Bitzeiten (streng 
genommen etwas weniger) Low-Pegel kommt als 0x00 mit Framing Error an.
Gast #6848902
Lesenswert?

Stephan R. schrieb:
> Da ich beruflich umorientiert "wurde" und auch mein Labor eingemottet
> ist, wird es ein wenig dauern, bis ich die Signale anschauen und melden
> kann.

Dann solltest Du Dir umso mehr den Wiki-Artikel zur seriellen 
Übertragung anschauen.

Da es häufig zur Konfusion führt, zumindest bei RS232, wo es nur ein 
Pegel gibt (und kein differentielles Signal):

 * Der Ruhepegel der eigentlichen Schnittstelle ist 1 (high)
 * Da meist ein Inverter auf beiden Seiten verbaut ist, ist der 
Ruhepegel auf der Leitung (wo man meistens misst) 0 (oder low, z.B. 
-5V). Am Uart-Chip hingegen 1.
 * Ein Frame fängt mit dem Startbit an (Wechsel von Ruhepegel auf 0, für 
eine Bitzeit) und hört mit mindestens einem Bit Ruhepegel auf (Stoppbit)

Eine Übertragung beginnt mit dem Wechsel von high nach low. Das 
triggert ein neues Zeichen. Meist wird das Startbit selber gar nicht 
ausgewertet. D.H. auch ein kurzer Spike oder ein permanenter Wechsel vom 
Ruhepegel 1 nach 0 startet ein neues Zeichen. Und das ist nach 10 oder 
11 Bitzeiten auch fertig. Wenn Du die Fehlerbits nicht auswertet, wird 
halt beim Spike ein 0xff (alles 1), ansonsten eine 0 (alles 0) 
empfangen. Bei beliebigen Störungen auch beliebige Daten.

(Wenn Du eine 0 empfängst, lässt es darauf schließen, dass der Sender 
"abschaltet" und sich daraufhin am Empfänger "der NICHT-Ruhepegel" 
einstellt. Das ist ein perfektes 0x00 mit Framing-Error (=Stoppbit nicht 
erkannt).
Gast #6849017
Lesenswert?

Hmmm schrieb:
> Resultat: Eine fallende Flanke mit mindestens 9 Bitzeiten (streng
> genommen etwas weniger) Low-Pegel kommt als 0x00 mit Framing Error an.

Korrekt muss es heissen "ggf. mit Framing Error" - wenn nach den 9 
Bitzeiten Low-Pegel wieder ein High-Pegel kommt, gibt es keinen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren