Forum: Mikrocontroller und Digitale Elektronik Probleme beim Umschalten zwischen Send und Receive bei RS485-Kommunikation


von Thorben B. (Gast)


Angehängte Dateien:

Lesenswert?

Moin moin,

ich versuche gerade über RS485 eine Kommunikation zwischen einem FT232R 
und einem ATMEGA8 aufzubauen. Der FT232R agiert als Master. Als Treiber 
verwende ich auf beiden Seiten den SN75176. Übertragungsgeschwindigkeit: 
250kBaud. Abschlusswiderstände genau wie hier beschrieben: 
http://www.mikrocontroller.net/articles/RS-485

Wenn ich vom Mikrocontroller einen String sende, kommt beim Empfänger 
manchmal das letzte Zeichen gar nicht an oder ein völlig falsches 
Zeichen wird angezeigt.
Meine Sende-Funktion sieht so aus:
1
void Sende_String(char *s)
2
{
3
    _delay_us(1);// kurz warten bis der FT232R wieder auf Empfang ist
4
    PORTD |= (1<<PD2);// RS485-Tranciever vom µC auf Senden schalten
5
        
6
    while (*s)
7
    {
8
        while (!(UCSRA & (1<<UDRE)));  
9
        UDR = *s;
10
11
        s++;
12
    }
13
14
    while (!(UCSRA & (1<<TXC)));// Warte bis TXComplete
15
    _delay_us(1);
16
    PORTD &= ~(1<<PD2); // RS485-Tranciever vom µC wieder auf Empfang schalten
17
}
Ich habe schon jeweils eine kurze Wartezeit eingefügt, bevor der Treiber 
über den Pin PD2 auf Senden bzw. zurück auf Empfangen gestellt wird. 
Ohne Wartezeit kommt das letzte Zeichen immer falsch an. Wähle ich die 
Wartezeit am Ende der Funktion zu groß, kommt das letzte Zeichen auch 
immer falsch an und wird manchmal auch noch zwei- dreimal wiederholt. 
Die while-Schleife mit TXC hat komischerweise keine Auswirkung auf das 
Ergebnis.

Ich hoffe ich habe alle wichtigen Details genannt damit mir jemand sagen 
kann was ich falsch mache und wie ich auch das letzte Zeichen korrekt 
übertragen kann. Vielen Dank schon mal an alle hilfreichen Antworten.

Gruß
Thorben

von Stefan F. (sfrings)


Lesenswert?

eine Mikrosekunde ist noch recht wenig, ich würde es mit 10 oder gar 100 
versuchen.

von Thorben B. (Gast)


Lesenswert?

Ich habe auch schon mit längeren Wartezeiten experimentiert. Leider auch 
ohne Erfolg =/

von Falk B. (falk)


Lesenswert?

@  Thorben B. (kingt)

>      SN75176.png

Vorsicht! Wenn du RE beim Senden auf HIGH legst, geht der R AUsgang auf 
Tristate! Da braucht man einen Pull-Up gegen VCC!

>Wenn ich vom Mikrocontroller einen String sende, kommt beim Empfänger

PC mit FT232, ja?

>manchmal das letzte Zeichen gar nicht an oder ein völlig falsches
>Zeichen wird angezeigt.
>Meine Sende-Funktion sieht so aus:

>void Sende_String(char *s)
>{
>    _delay_us(1);// kurz warten bis der FT232R wieder auf Empfang ist

Kann man sich schenken, der FT232 geht wenige Mikrosekunden, nachdem er 
das letzte Bit gesendet hat, auf Empfang.

>    PORTD |= (1<<PD2);// RS485-Tranciever vom µC auf Senden schalten

>    while (*s)
>    {
>        while (!(UCSRA & (1<<UDRE)));
>        UDR = *s;

>        s++;
>    }

OK.

>    while (!(UCSRA & (1<<TXC)));// Warte bis TXComplete

Ha, Fehler. TXC muss erstmal gelöscht werden, und zwar am Anfang deiner 
Routine.


"Bit 6 – TXC: USART Transmit Complete
This flag bit is set when the entire frame in the Transmit Shift 
Register has been shifted
out and there are no new data currently present in the transmit buffer 
(UDR). The TXC
Flag bit is automatically cleared when a transmit complete interrupt is 
executed, or it can
be cleared by writing a one to its bit location. The TXC Flag can 
generate a Transmit
Complete interrupt (see description of the TXCIE bit)."

Versuchs mal so
1
void Sende_String(char *s)
2
{
3
    PORTD |= (1<<PD2);    // RS485-Tranciever vom µC auf Senden schalten
4
    UCSRA |= (1<<TXC);    // TXC löschen
5
6
    while (*s)
7
    {
8
        while (!(UCSRA & (1<<UDRE)));  
9
        UDR = *s;
10
11
        s++;
12
    }
13
14
    while (!(UCSRA & (1<<TXC)));// Warte bis TXComplete
15
    PORTD &= ~(1<<PD2); // RS485-Tranciever vom µC wieder auf Empfang schalten
16
}

>Ohne Wartezeit kommt das letzte Zeichen immer falsch an.

Logisch, TXC ist schon gesetzt, von der letzten Übertragung.

> Wähle ich die
>Wartezeit am Ende der Funktion zu groß, kommt das letzte Zeichen auch
>immer falsch an und wird manchmal auch noch zwei- dreimal wiederholt.

Kann nicht sein.

>Die while-Schleife mit TXC hat komischerweise keine Auswirkung auf das
>Ergebnis.

Logisch, siehe oben.

MfG
Falk

von Thorben B. (Gast)


Lesenswert?

Vielen Dank für deine ausführliche Hilfe!

Falk Brunner schrieb:
> Vorsicht! Wenn du RE beim Senden auf HIGH legst, geht der R AUsgang auf
> Tristate! Da braucht man einen Pull-Up gegen VCC!

Wozu brauche ich den Pull-Up? Ist es beim Senden nicht egal was am 
RXD-Pin des µC anliegt?

> PC mit FT232, ja?

Ja! Sorry, ich hätte nicht gedacht, dass auf der USB-Seite noch was 
anderes sinnvolles angeschlossen werden könnte.

Merkwürdigerweise hatte ich beim ersten Test deiner Lösung keine 
Übertragungsfehler mehr, aber nachdem ich ein wenig rumprobiert hatte 
und alles wieder auf deine Lösung zurückgesetzt hatte tauchen wieder die 
selben Fehler auf =(

Gruß
Thorben

von Falk B. (falk)


Lesenswert?

@  Thorben B. (kingt)

>Wozu brauche ich den Pull-Up?

Damit dein RXD auf HIGH (=Stopbit) bleibt.

> Ist es beim Senden nicht egal was am
> RXD-Pin des µC anliegt?

Willst du eine solide Schaltung oder einen Zufallsgenerator?

>Merkwürdigerweise hatte ich beim ersten Test deiner Lösung keine
>Übertragungsfehler mehr, aber nachdem ich ein wenig rumprobiert hatte
>und alles wieder auf deine Lösung zurückgesetzt hatte tauchen wieder die
>selben Fehler auf =(

Da hast du wahrscheinlich Quelltexte oder Hexfiles vertauscht. Oder noch 
andere Fehler in deinem Programm.

von Thorben B. (Gast)


Lesenswert?

Vielen Dank nochmal für deine weitere Hilfe.

Könnte es dann auch am fehlenden Pull-Up-Widerstand liegen, dass 
teilweise nur Blödsinn übertragen wird? (Ich meine auch beim Senden, wo 
ich ja bisher dachte, dass es egal ist was an RXD anliegt)

von Falk B. (falk)


Lesenswert?

@  Thorben B. (kingt)

>Könnte es dann auch am fehlenden Pull-Up-Widerstand liegen, dass
>teilweise nur Blödsinn übertragen wird?

Kann sein, denn ohne Pull-Up kann dein uC Unsinn empfangen während des 
Sendens und dadurch dein Programm aus dem Tritt bringen.

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.