Forum: Mikrocontroller und Digitale Elektronik Xmega128A1 UART mit Halbduplex


von Der M. (naeschd)


Lesenswert?

Hallo zusammen,

ich versuche gerade mit einer Xmega UART eine Halbduplexverbindung mit 
einem externen Sensor aufzubauen.

Die Einstellungen habe ich soweit vorgenommen. Die Einstellungen wie 
Baudrate, Stopbits, usw. sind korrekt. Da bin ich mir sicher. Jedoch bin 
ich mir nicht sicher wie ich die UART für den Halbduplex konfigurieren 
muss.
Bei den Megas muss man ja hier das TXC-Bit anscheinend manuell löschen 
(Siehe 
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Der_UART#Die_UART-Register)
Könnt ihr mir helfen wie ich die XMEGA-UART konfigurieren muss bzw. 
welches Bit ich manuell setzen/löschen muss, sodass ich nach dem Senden 
der Anfrage an den Sensor den Datenempfang aktivieren kann?

Ich habe schon folgendes versucht, jedoch ohne Erfolg:
1
send_string(":1F03000A000194",2,true);    //senden des Strings
2
(USART_data_smbasic.usart)->STATUS |= USART_TXCIF_bm; //Umschalten auf UART-Empfang

Habt ihr Beispiele, Vorschläge, etc? Wäre für eure Hilfe sehr dankbar
Matze

von Gerhard G. (xmega)


Lesenswert?

Hallo,

Der Matze schrieb:
> Wäre für eure Hilfe sehr dankbar



z.B.USARTE0
USARTE0.CTRLB = USART_TXEN_bm;// senden
USARTE0.CTRLB = USART_RXEN_bm;// empfangen


oder etwas aufwendiger aber sicher...

This program was produced by the
CodeWizardAVR V2.05.3a Evaluation



// Receiver: Off
// Transmitter: On
USARTE0.CTRLB=(USARTE0.CTRLB&(~(USART_RXEN_bm|USART_TXEN_bm)))| 
USART_TXEN_bm;
}

// Receiver: On
// Transmitter: Off
USARTE0.CTRLB=(USARTE0.CTRLB & (~(USART_RXEN_bm | USART_TXEN_bm)))|
USART_RXEN_bm;
}

Gruß Xmega

von Gerhard G. (xmega)


Lesenswert?

Hallo,

habe die dazugehörigen Sende- und Empfangsroutinen vergessen.



char getchar(void)
{
char data;
unsigned char status;

while (1)
      {
      while (((status=USARTE0.STATUS) & USART_RXCIF_bm) == 0);
      data=USARTE0.DATA;
      return data;
      }
}

void putchar(char c)
{
while ((USARTE0.STATUS & USART_DREIF_bm) == 0);
USARTE0.DATA=c;
}

von Der M. (naeschd)


Lesenswert?

Vielen Dank für den Tip.
Ich habe nun folgenden Code ausprobiert:
1
USART_SMBASIC.CTRLB=(USART_SMBASIC.CTRLB&(~(USART_RXEN_bm|USART_TXEN_bm)))|USART_TXEN_bm; //Auf Senden schalten
2
send_string(":1F03000A000194",2,true); //String senden    
3
while(!((USART_SMBASIC.STATUS) & (USART_TXCIF_bm))){} //Auf Abschluss des Sendevorgangs warten
4
(USART_SMBASIC.STATUS) &= (~(USART_TXCIF_bm)); //Transmit Complete Interrupt Flag manuell zurücksetzen
5
USART_SMBASIC.CTRLB=(USART_SMBASIC.CTRLB&(~(USART_RXEN_bm|USART_TXEN_bm)))|USART_RXEN_bm; //Auf Empfangen schalten

Auffälligkeiten während des debuggen:
Zeile1: Im CTRLB wird erfolgreich TXEN gesetzt und RXEN deaktiviert -> 
OK
Zeile2: String wird gesendet -> OK
Zeile3: Es wird tatsächlich gewartet bis Senden abgeschlossen ist -> OK
Zeile4: Das TXCIF-Bit wird nicht auf 0 gesetzt. Warum nicht kann ich mir 
nicht erklären -> NICHT OK!
Zeile5: Im CTRLB wird erfolgreich RXEN gesetzt und TXEN deaktiviert -> 
OK

Vom Sensor erhalte ich leider immernoch keine Antwort. Das größte 
Problem, welches ich gerade habe, ist warum ich das Statusregister der 
USART nicht beschreiben kann (siehe Zeile4). Ich habe auch schon sowas 
versucht:
1
USART_SMBASIC.STATUS = 0x20;  // Register manuell auf 0b00100000 setzen

Leider funktiert nicht einmal das. Während des Debugen wird dieser Wert 
nicht übernommen... Weiß der Fuchs warum nicht!

Habt ihr noch weitere Tipps für mich, wie ich das Statusregister 
beschreiben kann, ob ich oben im Code noch einen Fehler habe, etc...

Wäre superdankbar!
Schönen Abend noch. Es grüßt
Der Matze

P.S.: Bei Bedarf darf das gerne ins GCC-Forum verschoben werden. Ist mir 
gerade erst aufgefallen.

von Gerhard G. (xmega)


Lesenswert?

Hallo,


Der Matze schrieb:
> Weiß der Fuchs warum nicht!

Senden wird so gemacht!

if(!(USARTF0.STATUS&USART_DREIF_bm))
while(!(USARTF0.STATUS & USART_TXCIF_bm)); // wait for TX complete
USARTF0.STATUS |= USART_TXCIF_bm;  // clear TX interrupt flag

Gruß xmega

von Der M. (naeschd)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe es jetzt folgendermaßen gemacht:
1
USART_SMBASIC.CTRLB=(USART_SMBASIC.CTRLB&(~(USART_RXEN_bm|USART_TXEN_bm)))|USART_TXEN_bm; //enable TX
2
while(!((USART_SMBASIC.STATUS) & (USART_DREIF_bm))){} //wait until transmit buffer is ready to receive data
3
send_string(":1F03000A000194",2,true); //send Data
4
while(!((USART_SMBASIC.STATUS) & (USART_TXCIF_bm))){} //wait for TX complete
5
USART_SMBASIC.STATUS |= (USART_TXCIF_bm); //clear TX interrupt flag
6
USART_SMBASIC.CTRLB=(USART_SMBASIC.CTRLB&(~(USART_RXEN_bm|USART_TXEN_bm)))|USART_RXEN_bm; //enable RX

Das sollte meiner Meinung nach funktionieren. Das TXCIF-Bit wird jetzt 
auch gecleart. Muss ja gesetzt werden um es zu löschen... 
Ans-Hirn-klatsch

Leider spricht der Sensor immernoch nicht mit mir. Ich weiß, dass der 
Anfragestring garantiert richtig ist. Im Anhang hab ich noch ein Bild, 
wie ich den Sensor HW-technsich an den XMEGA angeschlossen habe. Fällt 
euch (dir) da noch etwas auf? Den LVL-Shifter benutze ich auch. In 
diesem Fall nur einen Spannungsteiler mit 1,8kR und 3,3kR. Auf Grund der 
geringen Baudrate sollte das aber kein problem sein. Der Sensor läuft 
auf 5V.

Vielleicht fällt euch (dir) ja noch was ein. Ich bin mit meinem Latein 
so langsam am Ende :-(
Gute Nacht und Grüße vom
Matze

von Gerhard G. (xmega)


Lesenswert?

Hallo,

deine Abfragen sollten automatisch in den Send- und Get-Abfragen stehen.
Sonst nirgends! Das setzen von RX und TX ist ok.
Bitte die Abfolge beachten. Sollte das Ganze funktionieren, kann man den 
Code durchaus verkürzen!!

USART_SMBASIC.CTRLB=(USART_SMBASIC.CTRLB&(~(USART_RXEN_bm|USART_TXEN_bm) 
))|USART_TXEN_bm;  //enable TX


void ausgabe_char(char c)
{
if(!(USARTF0.STATUS&USART_DREIF_bm))
while(!(USARTF0.STATUS & USART_TXCIF_bm)); // wait for TX complete
USARTF0.STATUS |= USART_TXCIF_bm;  // clear TX interrupt flag
USARTF0.DATA=c;
}

void uart_send_string (char *pcString)
{
  while (*pcString) { ausgabe_char (*pcString++); };
}

USART_SMBASIC.CTRLB=(USART_SMBASIC.CTRLB&(~(USART_RXEN_bm|USART_TXEN_bm) 
))|USART_RXEN_bm;  //enable RX

// mit  get_byte() Daten abholen

uint8_t get_byte(void)    get als Interrupt oder polling
{
      XXXX
}

uart_send_string(":1F03000A000194"); //String senden

ergebnis = get_byte();

Gruß xmega

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.