Forum: Mikrocontroller und Digitale Elektronik Wer rettet meine Facharbeit - UART Problem TXC bit


von Christian (Gast)


Lesenswert?

Hallo allerseits,
am Montag ist Facharbeitabgabe. Ich habe mich mit dem Bau einer
inertialen Messeinheit auseinandergesetzt was bis vor 3 Tagen auch
alles prima funktioniert hat - Problem nun: meine Funkmodule (BIM2)
sind mir wohl kaputt gegangen oder es hat sich erneut ein
Softwarefehler eingeschlichen - nachdem diese Funkmodule noch nie so
richtig fehlerfrei bei mir funktionierten hab' ich mich für einen
Datenübertragung über Kabel per serieller Schnittstelle entschlossen -
um möglichst wenig Software ändern zu müssen möchte ich keinen
Interrupt verwenden sondern das TXC und RXC bit abfragen.
Beim senden passiert aber nix - hier mal ein Codeschnipsel(atmega128):

void init_serial (void)
{
outp((1<<TXEN),UCSR0B);                 //
outp(103, UBRR0L);           //9600bps @ 16 Mhz
outp(0, UBRR0H);

}

void write_byte (unsigned char bim_byte)
{
outp(bim_byte,UDR0);
loop_until_bit_is_set(UCSR0A,TXC);
sbi(UCSR0A,TXC);              //löscht das TXC bit (siehe Datenblatt)

}

Das TXC bit wird aber nie eins und jetzt sitzt der MC in der Schleife
fest - warum wirds aber nie eins???

Wäre prima wenn mir jemand helfen könnte!!

Vielen Dank

Christian

von Jörg Wunsch (Gast)


Lesenswert?

Du hast das bißchen schräg angefaßt.

Typischerweise interessiert man sich nach dem Absenden des Bytes gar
nicht für den UART-Zustand, sondern erst vor dem Senden des nächsten
Bytes:

int
uart_putchar(char c)
{

  if (c == '\n')
    uart_putchar('\r');
  loop_until_bit_is_set(UCSRA, UDRE);
  outb(UDR, c);
  return 0;
}

(Die \n -> \r\n Umwandlung brauchst Du sicher nicht.)

Damit kann die Applikation erstmal sofort weitermachen, erst vor der
Ausgabe des nächsten Zeichens muß sie ggf. warten.

TXC braucht man für gewöhnlich gar nicht.  UDRE genügt, da es Dir ja
reicht, daß der Sendepuffer wieder schreibbar ist, Du mußt ja nicht
extra warten, bis auch alle Daten aus dem Sende-Schieberegister raus
sind.

von Christian (Gast)


Lesenswert?

Hallo Jörg,
bist mir eine sehr große Hilfe beim Kampf gegen die Zeit gewesen :-) -
vielen Dank für die prompte Antwort!!!
Aus irgendeinem Grund ist die übertragung aber nicht zuverlässig -
ändern sich die Messwerte stark, tritt plötzlich ein fehler auf und es
wir d nur noch quatsch angezeigt - scheint sich der string irgendwie um
ein bit zu verschieben oder so etwas.... naja - hab' ja noch 2 Tage -
da kann noch so einiges passieren :-)

Viele Grüße an alle und ein schönes Wochenende!!

Christian

von Christian (Gast)


Angehängte Dateien:

Lesenswert?

Hallihallo,

hab' ein neues UART Problem, ein Mega8 Controller liest einen
elektronisches Kompass (siehe Anhang) aus - dieser sendet die Daten
seriell. Die Ausleseroutine hat auf einem anderen Controller (mega128)
prima funktioniert, aber warum wird noch folgender Initalisierung kein
RECV Interrupt mehr ausgelöst (Daten liegen an!!)??

void init_kompass(void)
{
outp((1<<RXCIE)|(1<<RXEN),UCSRB); /* enable RX interrupt */
outp(103, UBRRL);           //9600bps
outp(0, UBRRH);

sei();           /* enable interrupts */
}

so sieht die Interruptroutine aus - wird aber nie aufgerufen:

SIGNAL(SIG_UART_RECV)
{
uart_rx_pos++;
byte++;
uart_rxbuf[uart_rx_pos]=inp(UDR);
if (uart_rx_pos == 4) calc_kompasswert();
}

Ihr helft mir auch schon wenn ihr mir bestätigt, dass die Routine
theoretisch so stimmt....

Vielen Dank

Christian

von Uwe (Gast)


Lesenswert?

Hi!
>outp(103, UBRRL);           //9600bps
>outp(0, UBRRH);
Ist def. falsch!
richtig muss es lauten:

outp(0, UBRRH);
outp(103, UBRRL);           //9600bps

MFG Uwe

von OldBug (Gast)


Lesenswert?

Noch schöner:

  UBRRH = 0;
  UBRRL = 103;     /* 9600bps */

Gruß,
Patrick...

von Christian (Gast)


Lesenswert?

zunächst mal vielen Dank für den Hinweis - ich wusste nicht dass der AVR
bei der Reihenfolge so kleinlich ist....
Leider hat es aber überhaupt keine Auswirkung - die Interrupt Routine
wird immer noch nicht aufgerufen - naja einen Tag hab' ich noch zeit
:-)

Vielen Dank an alle - tolles Forum und es macht immer wieder Spaß
mitzulesen!!!

mfg

Christian

von Rahul (Gast)


Lesenswert?

Moin!
Vielleicht solltest Du erst die Baudrate einstellen, und dann die
Interrupts freigeben.
Gruß
Rahul

von bukongahelas (Gast)


Lesenswert?

hi bin uli und neu,wenig ahnung.
hab mich nach der try and error methode in avr8515 eingearbeitet.
machte auch den fehler 16 bit register in der reihenfolge
lobyte,hibyte zu laden.in der doku stehts aber richtig: hb,lb
und hat was mit einem temp-register zu tun,das aber nur intern
zu existieren scheint,egal.
kostete mich einen tag.
gruß

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.