Forum: Mikrocontroller und Digitale Elektronik Uart Transmission klappt nicht


von Sam (Gast)


Lesenswert?

Hallo an alle,

Ich habe ein Problem mit der Uart Übertragung:
1
UxTXREG='a';
2
while(UxSTAbits.TRMT==0)
3
; // warten bis Transmit Shift register und Transmit buffer register leer ist.

Leider wird das TRMT bit NIE gesetzt.

Was funktioniert:
1
UxTXREG='a';
2
__delay_ms(4);
Das ist aber nicht schön. Auf jeden Fall funktioniert die Übertragung, 
nur nicht korrekt.

Woran liegt es, dass das TRMT nicht gesetzt wird? Handelt sich um ein 
PIC24.
Es wird nur übertragen, es kommt nichts zurück.

http://ww1.microchip.com/downloads/en/DeviceDoc/70582C.pdf

Seite 6 ist TRMT beschrieben.

Danke

lG

von DanVet (Gast)


Lesenswert?

Wird denn etwas übertragen?
Kompletten Code zeigen!

von H.Joachim S. (crazyhorse)


Lesenswert?

Ohne was zum PIC sagen zu können: du solltest es andersherum machen. 
Erst prüfen, ob das Register frei ist (und dann ggf. so lange zu warten 
bis es frei ist) und nicht danach stur abwarten bis es raus ist. Die 
Zeit, während gesendet wird kann man sinnvoller nutzen.

von tastendrücker (Gast)


Lesenswert?

Sam schrieb:
> Was funktioniert:UxTXREG='a';
> __delay_ms(4);
> Das ist aber nicht schön. Auf jeden Fall funktioniert die Übertragung,
> nur nicht korrekt.

1. Was heißt "nur nicht korrekt"?

2. Im deinem realen Code steht auch U1STAbits.TRMT statt UxSTAbits.TRMT?


Tastendrücker

von Sam (Gast)


Lesenswert?

Hab mich eben falsch ausgedrückt. Wie gesagt, die Übertragung 
funktioniert so ohne Probleme:
1
U1TXREG='a';
2
__delay_ms(4);
3
4
U1TXREG='b';
5
__delay_ms(4);


So funktioniert es NICHT:
1
U1TXREG='a';
2
3
while(U1STAbits.TRMT==0)
4
; // warte bis vorherige Übertragung fertig ist.
5
U1TXREG='b';

Da wird das zweite Zeichen falsch ausgegeben.

Funktioniert auch nicht:
1
U1TXREG='a';
2
3
while(U1STAbits.UTXBF==1)
4
;//warte solange Transmit Buffer noch voll ist.
Da wird das zweite Zeichen falsch ausgegeben.

Wo liegt mein Denkfehler ?

von tastendrücker (Gast)


Lesenswert?

Anders herum:

1. Warten bis TX-Buffer leer ist
2. Daten in Buffer schreiben


while(U1STAbits.UTXBF==1)
U1TXREG='a';


Du must nach dem Schreiben nicht warten, bis das Byte gesendet wurde.

von Sam (Gast)


Lesenswert?

Nope..funktioniert auch nicht.
Habs so gemacht wie du es gesagt hast:
1
while(U1STAbits.UTXBF==1)
2
    ;
3
U1TXREG='a';
4
    
5
while(U1STAbits.UTXBF==1)
6
    ;
7
U1TXREG='b';

Zweites Zeichen wird FALSCH ausgegeben.

von tastendrücker (Gast)


Lesenswert?

Wie überprüfst du denn, was ausgegeben wird. Protokoll korrekt 
eingestellt?

von Sam (Gast)


Lesenswert?

Die Uart übergibt Daten einem einfachen LCD 16x2 Display der eben mit 
Uart funktioniert.
Da die Daten mit dem delay() richtig angezeigt werden nehme ich an dass 
alles richtig eingestellt ist.

von Andreas S. (Firma: Schweigstill IT) (schweigstill) Benutzerseite


Lesenswert?

Auch die Anzahl der Stoppbits?

von DanVet (Gast)


Lesenswert?

Sam schrieb:
> Die Uart übergibt Daten einem einfachen LCD 16x2 Display der eben
> mit
> Uart funktioniert.
> Da die Daten mit dem delay() richtig angezeigt werden nehme ich an dass
> alles richtig eingestellt ist.

kompletten Code zeigen!

von tastendrücker (Gast)


Lesenswert?

Sam schrieb:
> Da die Daten mit dem delay() richtig angezeigt werden nehme ich an dass
> alles richtig eingestellt ist.

Nicht unbedingt. Wenn die Baudrate nicht korrekt ist, könnte das erste 
Zeichen korrekt empfangen warden, beim zweiten aber das Timing schon 
auseinandergelaufen sein.

Mit einem Delay hast du quasi nur "erste" Zeichen.

Wie ist der PIC den getaktet? Intern/extern? Baudrate?

von Sam (Gast)


Lesenswert?

Habe das Programm hier
1
while(U1STAbits.UTXBF==1)
2
    ;
3
U1TXREG='a';
4
    
5
while(U1STAbits.UTXBF==1)
6
    ;
7
U1TXREG='b';

mal am Oszilloskop nachgeschaut. Kommt alles richtig an.

LCD benötigt laut Datenblatt: 9600 Baudrate, 1 Stop bit, 1 Startbit, no 
parity, 8 bit Datenbreite

Uart Konfig:
1
// 9600baud; 8 bits; 1 stop; no parity. //
2
    U1MODEbits.UARTEN=0; // disable Uart 1
3
    U1MODEbits.USIDL=0; // stop operation when Idle mode
4
    U1MODEbits.UEN=0b00; // only UxTX& UxRX used. UxCTS, UxRTS are I/O.
5
    U1MODEbits.WAKE=0; // Wake disabled
6
    U1MODEbits.ABAUD=0; // BaudRate Measurement disabled
7
    U1MODEbits.URXINV=0; // Idle State = 1
8
    U1MODEbits.BRGH=0; // 16 clocks per bit period ; Standard Speed mode
9
    U1MODEbits.PDSEL=0b00; // 8 bit Data, no Parity
10
    U1MODEbits.STSEL=0; // 1 Stop Bit
11
    U1BRG=259;
12
    U1MODEbits.UARTEN=1; // enable Uart 1
13
    U1STAbits.UTXEN=1; // Enable Transmit
14
    
15
    __delay_us(105);  // 1/9600

Der Pic ist extern getaktet und mittels PLL auf 80Mhz hochgeregelt. 
Zyklustakt ist 40Mhz.
Für die Baudrate habe ich die Formel aus dem Uart Datenblatt entnommen:
(40Mhz/9600/16) -1 = 259,41=259

von tastendrücker (Gast)


Lesenswert?

Versuch mal 2 Stop-Bits zu senden, auch wenn der Empfänger nur eines 
benötigt.

von DanVet (Gast)


Lesenswert?

Sam schrieb:
> Habe das Programm hierwhile(U1STAbits.UTXBF==1)
>     ;
> U1TXREG='a';
>
> while(U1STAbits.UTXBF==1)
>     ;
> U1TXREG='b';
>
> mal am Oszilloskop nachgeschaut. Kommt alles richtig an.

Dann ist ja alles gut.
Wie schnell kann denn das Display die ankommenden Bytes verarbeiten?
Vielelicht brauchts da eine kurze Pause?

von Sam (Gast)


Lesenswert?

tastendrücker schrieb:
> Versuch mal 2 Stop-Bits zu senden, auch wenn der Empfänger nur
> eines
> benötigt.

Du bekommst ein Bier von mir. Alter schwede, es funktioniert jetzt 
endlich ohne die delays.
Herzlichen Dank Tastendrücker, du hast wortwörtlich auf die richtige 
Taste gedrückt! Jetzt ist das ganze auch viel schöner und sauberer ohne 
delays.

Somit ist das hier jetzt geklärt.
Danke nochmal an alle!

Sonnige grüße!

von DanVet (Gast)


Lesenswert?

DanVet schrieb:
> Wie schnell kann denn das Display die ankommenden Bytes verarbeiten?
> Vielelicht brauchts da eine kurze Pause?

Sam schrieb:
>> Versuch mal 2 Stop-Bits zu senden, auch wenn der Empfänger nur
>> eines
>> benötigt.
>
> Du bekommst ein Bier von mir. Alter schwede, es funktioniert jetzt
> endlich ohne die delays.

Oder ein zweites StopBit :-)

von tastendrücker (Gast)


Lesenswert?

Entweder das Display benötigt tatsächlich eine Pause, wie DanVet schrieb 
(Busy-Flag?), oder der Baudraten-Fehler ist wirklich zu groß.

Jetzt müsstest du nur noch mal mehrere Zeichen versuchen.

von Sam (Gast)


Lesenswert?

Ich habe vorhin einen ganzen String gesendet, wurde alles korrekt 
angezeigt!

Zum Baudrate Fehler..hatte von 258 bis 261 probiert, immer noch Anzeige 
Fehler.

Busy Flag vom LCD kann ich nicht nachprüfen, da ich nur TX habe. Was 
könnte sonst noch ein Ursache sein, dass zwei Stopbits gebraucht werden?

lG

von tastendrücker (Gast)


Lesenswert?

Naja, das zweite Stopbit beim Senden sorgt ja nur dafür, dass dem 
Empfänger nach dem Empfang eines Datenwortes die "Zeitdauer" eines Bits 
zur Verarbeitung gegeben wird. Da ist sogesehen quasi ein Mikro-Delay.

Eventuell gibt das Datenblatt des Displays noch Aufschluss.

td

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.