Forum: Mikrocontroller und Digitale Elektronik RS485 Zeichen empfangen


von Davor S. (da__x)


Lesenswert?

Hallo!

Ich hoffe jmd. von euch kann mir helfen, hänge schon unendlich lange an 
diesem Problem.

Ich verwende die serial outpus von meinem mbed entwicklungsboard und 
einen rs485 transceiver (ADM3491EARZ).

TX und RX sind direkt mit DI und RO verbunden, DE und RE sind mit 2 
digitalen outputs verbunden.

Die Ausgänge des Transceivers (A,B,Z,Y) sind mit einem USB/RS485 kabel 
verbunden um die Kommunikation zu testen.

Ich schließe nun einerseits das mbed entwicklungsboard per usb an meinen 
notebook an um über printfs zu debuggen.

COM3 : mbed
COM4 : USB/RS485 Kabel

Folgendes passiert...ich schicke "Hello World" über die serielle 
schnitstelle und kann im hterm sehen, dass an COM4 auch "Hello World" 
ankommt.

Das ist zunächst super.

Das Problem ist aber, wenn ich mein Programm erweitere, damit ich fähig 
bin auch etwas über RS485 zu empfangen...hab ich ein Problem.

Ich verwende die bibliotheksfunktion getc() und übergebe den 
rückgabewert an einen character. Ich erwarte, dass die Abarbeitung des 
programms an dieser stelle wartet, bis ich aus hterm ein zeichen sende.
Das Programm wartet aber kein bisschen, der character wird sofort mit 
'\0' initialisiert. Egal was ich mache.

Ich achte natürlich auch darauf, dass die richtigen enable Signale 
eingestellt sind.

Hier mein C-Code:
1
#include "mbed.h"
2
 
3
 
4
Serial rs485(p9, p10);  // tx, rx
5
Serial pc(USBTX, USBRX);
6
 
7
DigitalOut re_not(p19);
8
DigitalOut de(p20);
9
 
10
DigitalOut led1(LED1); //transmit mode
11
DigitalOut led2(LED2); //receive mode
12
 
13
int main() {
14
    
15
    char rx;
16
    
17
    re_not = 1;
18
    de = 1;
19
    led1 = 1;
20
    
21
    rs485.printf("Hello World\n"); //print string to device - WORKS
22
    wait(0.25);
23
    
24
    while(1)
25
    {
26
        pc.printf("Press a button to continue\n");
27
        pc.getc();
28
        if(rs485.readable()) {
29
            re_not = 0;
30
            de     = 0;
31
            pc.printf("readable!\n");
32
            rx = rs485.getc();            
33
            pc.printf("read: %c", rx);
34
            wait(0.25);
35
        }
36
        re_not = 1;
37
        de = 1;
38
    }
39
}

von Jim M. (turboj)


Lesenswert?

Mach mal den (weak) Pullup auf dem RX Pin an (PINMODEx Register). IIRC 
klemmen die RS485 Tranceiver beim Senden den RO vollständig ab, so dass 
man den Ruhepegel (HIGH bei UART) selbst herstellen muss.

Wie ist eigentlich der RS485 Bus terminiert? Ein auf "0" terminierter 
Bus würde ähnliches Verhalten zeigen, denn nach dem Ausschalten des 
Senders wird die "0" als Start-Bit erkannt.

von RS495 (Gast)


Lesenswert?

Wenn Dein DE das data enable ist, sollte es high sein. Soweit ich weiss 
ist das nicht lo aktiv.

von Davor S. (da__x)


Lesenswert?

Jim Meba schrieb:
> Mach mal den (weak) Pullup auf dem RX Pin an (PINMODEx Register). IIRC
> klemmen die RS485 Tranceiver beim Senden den RO vollständig ab, so dass
> man den Ruhepegel (HIGH bei UART) selbst herstellen muss.
>
> Wie ist eigentlich der RS485 Bus terminiert? Ein auf "0" terminierter
> Bus würde ähnliches Verhalten zeigen, denn nach dem Ausschalten des
> Senders wird die "0" als Start-Bit erkannt.



Danke Jim!

Dein Beitrag hat mir sehr geholfen!
1
    LPC_PINCON->PINMODE0 &= ~(1 << 2);
2
    LPC_PINCON->PINMODE0 &= ~(1 << 3);

Das löst mein Problem leider nur teilweise.../

Jetzt empfange ich das richtige Zeichen....aber nur unter der Bedingung, 
dass ich rs485.readable() entferne. Also die Abfrage wird nie erfüllt.

Zur Terminierung. Derzeit habe ich gar nicht terminiert. Die Kabellängen 
sind gerade mal ein Meter. Sollte ich da schon Widerstände vorsehen? 
Falls ja, kannst du mir da auf die Sprünge helfen? 120Ohm jeweils 
zwischen A und B ; Y und Z  sowohl am Sender, als auch beim den (später 
2) Empfänger?


@RS495

Da das ein full duplex transceiver ist sollte DE eig. ohnehin egal sein 
beim empfangen. Es wird auch im Datenblatt als "dont care (X)" in der 
Wahrheitstabelle die die funktion der Enable signale beschreibt.

Danke!

von Jim M. (turboj)


Lesenswert?

> ..aber nur unter der Bedingung, dass ich rs485.readable() entferne

Bei nRE=1 kann man auch keine Zeichen einlesen. Das geht nur bei nRE = 
0. Daher sollte das readable() im Code oben immer false sein.


Eine Terminierung ist bei dieser Länge nicht unbedingt nötig.

Eine Vorspannung (B nach VCC und A nach GND, analog bei Z und Y) mit 1k 
oder 10k Widerständen sorgt für einen definiertem (Ruhe-)Buspegel, auch 
wenn kein Sender "an" ist.

von Davor S. (da__x)


Lesenswert?

Ok danke für die Info.

Ich würde nur so mal aus Interesse wissen, wieso ich die pull-up 
Widerstände aktivieren musste, damit die Kommunikation funktioniert? Wie 
kann man das verstehen?

Wieso ist das bei dem mbed board, das damit wirbt, dass es auf einer 
'high level' Ebene programmiert wird, wo man sich keine Gedanken mehr um 
die Einstellungen auf Registerebene machen sollte... ?!

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.