Forum: Mikrocontroller und Digitale Elektronik schon wieder UART Problem:(


von S. L. (goldencue)


Lesenswert?

Hallo zusammen.

Ich möchte mit einem Atmega8 über die UART kommunizieren. Das Erste was 
ich mach ist eine LED zur Kontrolle und die UART init. Die LED blinkt im 
Sekundentakt, nur die UART sendet seit nunmehr TAGEN nichts raus. Ich 
bin am verzweifeln. Habe so viele Beiträge nun dazu gelesen und alles 
mögliche geändert. Aber der TX am µC bleibt kalt:(

Einstellungen:

AVRStudio -> STK500 -> Atmega8
Fuses:
SUT_CKSEL = Int.RC Osc 8MHz; Start-up time 6CK+64ms
Ansonsten keine weiteren gesetzt ( ausser SPIEN )

Programm:


#define F_CPU    8000000UL

#include <avr/io.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <string.h>
#include "mydefs.h"

#define BAUD 19200UL      // Baudrate
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)

int main(){

_delay_ms(150);    //wait for Supply stabilization

DDRB|= (1<<5);    //set Test LED Output


USART_Init(UBRR_VAL);

while (1)
{

  PORTB |= (1<<5);
  USART_Transmit( 'U' );
  _delay_ms(1000);
  PORTB &= ~(1<<5);
  USART_Transmit( '5' );
  _delay_ms(1000);
}
}

void USART_Init( unsigned int baud )
{
  /* Set baud rate */
  UBRRH = (unsigned char)(baud>>8);
  UBRRL = (unsigned char)baud;
  UCSRB |= (1<<TXEN);  // UART TX einschalten
  UCSRB = (1<<RXEN);   // UART RX einschalten

  UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);  // Asynchron 8N1

}

void USART_Transmit( unsigned char data )
{

  /* Wait for empty transmit buffer */
  while ( !( UCSRA & (1<<UDRE)) )
  ;
  /* Put data into buffer, sends the data */
  UDR = data;
}

unsigned char USART_Receive( void )
{
  /* Wait for data to be received */
  while ( !(UCSRA & (1<<RXC)) )
  ;
  /* Get and return received data from buffer */
  return UDR;
}

////////////////////////////////////////////////////////////

Ich habe bereits:

*Die TX/RX von rs232-Spare mit Logikanalyser zum Testgemessen. Alles ist 
am STK500 also io.
*Den Atmega ausgewechselt
*Eine Kontrol-LED an den Pin PD1 gehangen ( flackert bisher nie )
*Datenblatt und viele andere Beiträge gelesen

aber der TX ( also PD1 ) am AVR spricht einfach nicht, obwohl ich wie 
man sieht zum Test ständig ein U und eine 5 sende. An der Baudrate kann 
es z.Z. nicht liegen, da der µC ja trotzdem wenigstens senden müsste. In 
der Simulation von AVRStudio wird mein Testchar auch in UDR geschrieben. 
Doch da endet leider die Spur.

Vieleicht ist das Problem pillepalle. Vermutlich sogar. Ich komme nur 
nicht dahinter????

Vielen Dank wenn mir jemand zu helfen weiss.

von Karl H. (kbuchegg)


Lesenswert?

1
  UCSRB |= (1<<TXEN);  // UART TX einschalten
2
  UCSRB = (1<<RXEN);   // UART RX einschalten

Gratuliere.
Mit der 2.ten Zuweisung hast du dir soeben das TXEN Bit wieder gelöscht.

Wenn werdet ihr endlich begreifen, dass Mehrfachzuweisungen an ein und 
dasselbe Register ausser fehleranfällig nur noch fehleranfällig sind.

von egal (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> UCSRB |= (1<<TXEN);  // UART TX einschalten
>   UCSRB = (1<<RXEN);   // UART RX einschalten
>
>
> Gratuliere.
> Mit der 2.ten Zuweisung hast du dir soeben das TXEN Bit wieder gelöscht.
Ist mir auch sofort ins Auge gesprungen. Obwohl ich mich dabei frage, 
wieso er dies getan hat? Wurde der Code nur kopiert? Hat der TO nicht 
verstanden, wozu "|=" gut ist? Komischer Fehler...

von Karl H. (kbuchegg)


Lesenswert?

egal schrieb:
> Karl Heinz Buchegger schrieb:
>> UCSRB |= (1<<TXEN);  // UART TX einschalten
>>   UCSRB = (1<<RXEN);   // UART RX einschalten
>>
>>
>> Gratuliere.
>> Mit der 2.ten Zuweisung hast du dir soeben das TXEN Bit wieder gelöscht.
> Ist mir auch sofort ins Auge gesprungen. Obwohl ich mich dabei frage,
> wieso er dies getan hat? Wurde der Code nur kopiert? Hat der TO nicht
> verstanden, wozu "|=" gut ist? Komischer Fehler...

Spekulation:
In der Vorlage, aus der er das kopiert hat, stand

  UCSRB |= (1<<TXEN) | (1<<RXEN);

das hat er auf 2 Zeilen aufgeteilt und dabei den Fehler gemacht.


Vielleicht stand in der Vorlage auch

 UCSRB = (1<<RXEN);   // UART RX einschalten
 UCSRB |= (1<<TXEN);  // UART TX einschalten

und aus irgendwelchen Gründen wollte er die Reihenfolge umdrehen.

von S. L. (goldencue)


Lesenswert?

egal schrieb:
> Ist mir auch sofort ins Auge gesprungen. Obwohl ich mich dabei frage,
> wieso er dies getan hat? Wurde der Code nur kopiert? Hat der TO nicht
> verstanden, wozu "|=" gut ist? Komischer Fehler...

Ich habe es auch wie im Datenblatt versucht. Also:

UCSRB = (1<<RXEN)|(1<<TXEN);

aber das ist es leider nicht. Ihr habt beide Recht und ich habe die 
Zeile wie im Datenblatt geändert.

Wozu | da ist weiss ich ;)

von Karl H. (kbuchegg)


Lesenswert?

Matthias T. schrieb:

> aber das ist es leider nicht.

Es kann natürlich sein, dass noch mehr im Busch ist. Aber das ist jetzt 
erst mal der erste Fehler, der ganz sicher verhindert hat, dass die UART 
etwas raussendet.

von S. L. (goldencue)


Lesenswert?

Ja das ist klar. Ich habe es geändert.

Da ich die Schaltung minimal gehalten hab, kann ich mir leider keinen 
weiteren Fehler mehr vorstellen :(

von Karl H. (kbuchegg)


Lesenswert?

Matthias T. schrieb:
> Ja das ist klar. Ich habe es geändert.

Na dann häng mal eine LED an den Tx Pin vom Mega8. Schmeiss die Pausen 
aus dem Programm raus und lass es laufen. An der LED am Tx Pin müsste 
man ein Flackern erkennen können. Eventuell kannst du ja auch mal auf 
300 Baud zurückschalten, da musst du den Pin ganz sicher flackern sehen.

Flackert es, dann ist schon mal sicher gestellt, dass aus dem UART was 
rauskommt. Noch ist nicht gesagt, dass es richtig ist, aber es wird 
zumindest schon mal gesendet.

Danach hältst du die LED an den Eingang vom MAX232, dort muss es 
ebenfalls flackern, wenn der richtig mit dem µC verdrahtet ist.
Danach an den zugehörigen Ausgang vom MAX232, ebenfalls flackern.
Dann gehts weiter zum RS232 Stecker/Buchse, wo es am richtigen Pin 
ebenfalls Flackern muss.

So eine LED kann ein ganz schön gutes Hilfsmittel sein :-)


Alles natürlich vorausgesetzt, dass du nicht den Tx Pin mit einer 
externen Beschaltung lahm gelegt hast. Im Zweifel den µC so in den 
Sockel stecken, dass der Pin 'im Freien ist'. Dann muss er ganz sicher 
Flackern.

von S. L. (goldencue)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Na dann häng mal eine LED an den Tx Pin vom Mega8. Schmeiss die Pausen
> aus dem Programm raus und lass es laufen. An der LED am Tx Pin müsste
> man ein Flackern erkennen können. Eventuell kannst du ja auch mal auf
> 300 Baud zurückschalten, da musst du den Pin ganz sicher flackern sehen.

Eine ControlLED ist bereits mit 330Ohm gegen Masse. Am PD1 (TX) liegen 
permanent 4,9V an. Also LED leuchtet - blinkt aber nie.

Des Weiteren habe ich nen Logikanalyser permanent am TX des µC und auch 
der sagt nix. Ich kann bei Datenverkehr sonst gut so die Bits verfolgen.

300Baud und Pausen raus mache ich.

von Karl H. (kbuchegg)


Lesenswert?

Matthias T. schrieb:
> Karl Heinz Buchegger schrieb:
>> Na dann häng mal eine LED an den Tx Pin vom Mega8. Schmeiss die Pausen
>> aus dem Programm raus und lass es laufen. An der LED am Tx Pin müsste
>> man ein Flackern erkennen können. Eventuell kannst du ja auch mal auf
>> 300 Baud zurückschalten, da musst du den Pin ganz sicher flackern sehen.
>
> Eine ControlLED ist bereits mit 330Ohm gegen Masse. Am PD1 (TX) liegen
> permanent 4,9V an. Also LED leuchtet - blinkt aber nie.

Alles natürlich vorausgesetzt, dass du nicht den Tx Pin mit einer
externen Beschaltung lahm gelegt hast. Im Zweifel den µC so in den
Sockel stecken, dass der Pin 'im Freien ist'. Dann muss er ganz sicher
Flackern.

von Martin (Gast)


Lesenswert?

hast du den tx pin auch auf ausgang gesetzt?

von S. L. (goldencue)


Lesenswert?

Martin schrieb:
> hast du den tx pin auch auf ausgang gesetzt?

Explizit? Ich hatte es mal mit:

DDRD |= (1<<1);

versucht. Aber es ergab keinen Erfolg. Sollte ich das drinnen lassen?

von Karl H. (kbuchegg)


Lesenswert?

Matthias T. schrieb:
> Martin schrieb:
>> hast du den tx pin auch auf ausgang gesetzt?
>
> Explizit? Ich hatte es mal mit:
>
> DDRD |= (1<<1);
>
> versucht. Aber es ergab keinen Erfolg. Sollte ich das drinnen lassen?

Brauchst du nicht.
Die UART setzt sich ihre Pins selber auf Ein-/Ausgang.

von S. L. (goldencue)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Alles natürlich vorausgesetzt, dass du nicht den Tx Pin mit einer
> externen Beschaltung lahm gelegt hast. Im Zweifel den µC so in den
> Sockel stecken, dass der Pin 'im Freien ist'. Dann muss er ganz sicher
> Flackern.

Baud auf 300, keine externen Komponenten dran, kein Signal direkt am Pin 
-> LED leuchtet still

von S. L. (goldencue)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Brauchst du nicht.
> Die UART setzt sich ihre Pins selber auf Ein-/Ausgang.

genau das hatte ich mir bei:

UCSRB |= (1<<TXEN) | (1<<RXEN);

schon gedacht.

von Volkmar D. (volkmar)


Lesenswert?

Du hast doch eine LED an PB5, blinkt die?

von Karl H. (kbuchegg)


Lesenswert?

Falschen Pin erwischt (ist wohl jedem schon mal passiert)?
Falschen Prozessor im Studio eingestellt?

Programmtechnisch seh ich da jetzt nichts mehr

von S. L. (goldencue)


Lesenswert?

ENDLICH! der Fehler ist gefunden.

Die Stiftleiste mit TX/RX am STK500 ist garnicht direkt mit dem µC 
verbunden. Wenn ichs mir recht überlege - eigendlich klar.

Ich muss das Signal direkt am PD1 abgreifen.


Vielen vielen Dank für eure Mühe und Hilfe!!!

von S. L. (goldencue)


Lesenswert?

mein Logikanalyser sagt mir bei 19200Baud von steigender Flanke zu 
steigender Flanke eine Frequenz von 9,76KHz. Ist das im richtigen 
Bereich? Jedenfalls grob?

von Krapao (Gast)


Lesenswert?

Sehr grob. Wenn du laufend 0b01010101 (= 0x55 = 'U') bei 8N1 aus gibst, 
kannst du die Bitrate so messen. Genau sollte 9,6 kHz rauskommen.

von Volkmar D. (volkmar)


Lesenswert?

Matthias T. schrieb:
> Frequenz von 9,76KHz

Krapao schrieb:
> Genau sollte 9,6 kHz rauskommen

Macht einen Fehler von 1,67% => Akzeptabel.

von S. L. (goldencue)


Lesenswert?

naja - die Kommunikation klappt gut. Mittlerweile hängt ein BTM-222 ( 
Bluetooth ) dran und ich sende/empfange schon fleißig von PDA zu AVR und 
zurück. Sollten Störungen auftreten, werd ich die Baud etwas anpassen.

Vielen Dank euch allen!

von Steven Z. (steven84)


Lesenswert?

Hallo da ich blutiger C-Anfänger bin  habe ich mal mehrer Fragen zum 
Syntax.

1. wofür steht hinter der baudrate das UL und ist das üblich?
#define BAUD 19200UL      // Baudrate

2. Dann wird hier der Wert für die Bautraten errechnet und and UBRR_VAL 
übergeben

#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)

aber hier scheiterts schon wieder! Wird die Variable an USART_Init 
übergeben?

USART_Init(UBRR_VAL);

und wie kommt die Variable nun in die Register UBRRH und UBRRL??

void USART_Init( unsigned int baud )
{
  /* Set baud rate */
  UBRRH = (unsigned char)(baud>>8);
  UBRRL = (unsigned char)baud;
  UCSRB |= (1<<TXEN);  // UART TX einschalten
  UCSRB = (1<<RXEN);   // UART RX einschalten

  UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);  // Asynchron 8N1

}

Danke schon mal.

VG

Steven

von troll (Gast)


Lesenswert?


von Karl H. (kbuchegg)


Lesenswert?

Und was noch fehlt:

C Buch kaufen, lesen und durcharbeiten!

von Tobi L. (Gast)


Lesenswert?

Matthias T. schrieb:
> UBRRH = (unsigned char)(baud>>8);
>   UBRRL = (unsigned char)baud;

schreib bei den Zeilen mal hardcoded den wert rein! und nutze nicht den 
precompiler ich hatte da auch ganz lustiger effekte als ich mir den 
assembler code angeschaut habe. Die darauf schliessen lassen dass der 
precompiler an der stelle lauter lustige dinge macht nur nicht das was 
du denkst....Im Datenblatt findest du die UBRR für die gängisten 
frequenzen udn die gängisten UART Geschw. schreib den mal hardcoded rein

von Klaus W. (mfgkw)


Lesenswert?

Tobi L. schrieb:
> schreib bei den Zeilen mal hardcoded den wert rein! und nutze nicht den

Damit das Programm unlesbar wird?
Das wäre der Ratschlag des Tages :-)

> precompiler ich hatte da auch ganz lustiger effekte als ich mir den
> assembler code angeschaut habe. Die darauf schliessen lassen dass der
> precompiler an der stelle lauter lustige dinge macht nur nicht das was
> du denkst....

Höchstens, wenn du baud als signed-Wert hättest (was hier nicht der Fall 
ist; das obige Beispiel passt).
Dann macht der Compiler (nicht der PP) etwas, was DU vielleicht nicht 
denkst.

Was sollte der Präprozessor da verhunzen?

von Karl H. (kbuchegg)


Lesenswert?

Tobi L. schrieb:
> Matthias T. schrieb:
>> UBRRH = (unsigned char)(baud>>8);
>>   UBRRL = (unsigned char)baud;
>
> schreib bei den Zeilen mal hardcoded den wert rein! und nutze nicht den
> precompiler ich hatte da auch ganz lustiger effekte als ich mir den
> assembler code angeschaut habe. Die darauf schliessen lassen dass der
> precompiler an der stelle lauter lustige dinge macht

Das einzige was man daraus schliessen kann ist, das du einen Fehler 
gemacht hast. Wahrscheinlich irgendwas mit Datentypen und Overflows.

Ausserdem ist das nicht das Problem des TO.

von Klaus W. (mfgkw)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Ausserdem ist das nicht das Problem des TO.

naja, es war ja auch ein Ratschlag an ihn, soweit ich das verstanden 
habe.
Wenn auch ein m.E. schlechter.

von Cyblord -. (cyblord)


Lesenswert?

Woher kommen denn eigentlich diese ganzen UART Probleme in letzter Zeit? 
Und dann noch mit nem Mega8? Das ist derart Simpel durch den HW-Uart. 
Ich versteh das Problem nicht. Eventuell liegts ja daran dass natürlich 
trotzdem, auch für den ersten Versuch, auf ne fertige lib 
zurückgegriffen werden muss. 4 Bits in irgendwelchen Registern korrekt 
setzen ist anscheinend zuviel. Datenblatt wird dann gar nicht mehr 
gelesen. Eine Stunde mit dem Datenblatt und der UART sollte auch beim 
größten Noob laufen.

gruß cyblord

von Klaus W. (mfgkw)


Lesenswert?

cyblord ---- schrieb:

1.
> Eine Stunde mit dem Datenblatt ...

2.
> ... größten Noob ...

1. und 2. schließen sich in aller Regel offenbar aus.

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.