Forum: Mikrocontroller und Digitale Elektronik UART-Empfangsproblem Atmega88pa


von yafr (Gast)


Angehängte Dateien:

Lesenswert?

Abend zusammen,

seit 2 Tagen grübel ich jetzt schon an meinem Empfangsproblem.

Ich möchte (zuerst einmal) ohne Interrupt zwischen PC und Atmega 
kommunizieren.

Da ich euch nicht mit dem gesamten Code (der ist im Anhang) belästigen 
möchte hier ein paar Ausschnitte:

der Init (ist soweit aus dem Datenblatt übernommen:
1
void USART_init( unsigned int ubrr)
2
{
3
/*Set baud rate */
4
UBRR0H = (unsigned char)(ubrr>>8);
5
UBRR0L = (unsigned char)ubrr;
6
/*Enable receiver and transmitter */
7
UCSR0B = (1<<RXEN0)|(1<<TXEN0);
8
/* Set frame format: 8data, 1stop bit */
9
UCSR0C = (3<<UCSZ00);
10
}
Wird im main so aufgerufen:
1
#define F_CPU 8000000UL     //Interner Quartz CLKDiv ist aus
2
#define UBRR_9600 51        // for 8Mhz with .2% error
3
4
USART_init(UBRR_9600);

Was ich zum laufen bekommen habe ist das Senden vom AVR zum PC:
1
  if (T1)  //wenn auf Taster1 gedrückt, sende an UART und zeige auf LCD
2
  {
3
  USART_tx_string("Sende:");
4
  USART_tx_string(buffer);
5
  lcd_goto(1,0);
6
  lcd_string("Set:");
7
  lcd_goto(1,4);
8
  itoa(i,buffer,10);
9
  lcd_string(buffer);
10
  i= i+1;
11
  }
Daher denke ich das der Init und die Bauddatenberechnung auch soweit ok 
ist.

Beim Empfangen habe ich mich auch wieder an das Tutorial und das 
Datenblatt gehalten:
1
/* Zeichen empfangen */
2
uint8_t uart_getc(void)
3
{
4
        while (!(UCSR0A & (1<<RXC0)));   // warten bis Zeichen verfuegbar
5
    
6
   return UDR0;                   // Zeichen aus UDR an Aufrufer zurueckgeben
7
}
So wird das im Main behandelt:
1
  if ( (UCSR0A & (1<<RXC0)) )
2
    {
3
      // Zeichen wurde empfangen, jetzt abholen
4
      uint8_t c;
5
      c = uart_getc();
6
    itoa(c,buffer2,10);
7
 lcd_goto(0,0);
8
 lcd_string(buffer2);
9
    }
Aber ich empfange einfach keine Daten. Egal was ich tu, es wird nix.

Mein Serialport am PC ist wie folgt eingestellt:
Baudrate: 9600
Stopbit: 1
Datenbits: 8
Parität: Keine
Flusssteuerung: Keine

Ich denke das stimmt so mit der Konfiguration des AVR-Uarts über ein.
Könnt ihr mir den entscheidenden Hinweis geben?

Ich habe schon das Forum durchgesucht und alle möglichen Tutorials 
durchgeschaut, aber leider nix gefunden.
Danke schon mal für die Mühe.

: Bearbeitet durch User
von yafr (Gast)


Lesenswert?

was ich zur Hardware vergessen habe zu erwähnen, ist das der USB-Port zZ 
lediglich zur Spannugsversorgung genutzt wird. der soll später für die 
Komunikation herhalten, aber Schritt für Schritt.

von yafr (Gast)


Lesenswert?

Hat wirklich keiner eine Idee?

von Ben S. (theben)


Lesenswert?

Eine Frage, du hast jetzt doch nicht etwa den PC an der USB Buchse (X1) 
angeschlossen oder?

von Henrik P. (henrik84)


Lesenswert?

Moin,

beim Max232 sind die Versorgungspins (15 und 16) nicht eingezeichnet.

Warum hast Du 5V an C3 angelegt?

Eindeutig kann ich den Fehler nicht benennen, aber ich hoffe das hilft 
bei der Suche.

Gruß Henrik

von yafr (Gast)


Lesenswert?

Ben S. schrieb:
> Eine Frage, du hast jetzt doch nicht etwa den PC an der USB Buchse
> (X1)
> angeschlossen oder?

Doch aber nur zur Spannugsversorgung.

Henrik P. schrieb:
> Moin,
>
> beim Max232 sind die Versorgungspins (15 und 16) nicht eingezeichnet.

Kontrollier ich später, aber müsste er nicht arbeiten wenn das senden 
funtioniert?

> Warum hast Du 5V an C3 angelegt?

habe mich an den Plan im Tutorial gehalten:
http://www.mikrocontroller.net/articles/AVR-Tutorial:_UART

von bell (Gast)


Lesenswert?

Hallo,

welchen Max232 verwendest du? Da gibt es eine ganze Menge verschiedener 
Typen. Je nach Datenblatt musst du da deine Kondensatoren anpassen. Wenn 
du dich an die Vorgabe im Tutorial gehalten hast (C = 1µ) kann das unter 
Umständen nicht passen.

Grüße

von Henrik P. (henrik84)


Lesenswert?

Ich würde den Kondensator an VS+ nochmal messen, ob er kurzgeschlossen 
ist, und die Kathode auf Masse legen. Ich kann echt keinen Sinn darin 
erkennen, den auf 5V zu legen und im Tutorial wird auch nicht gesagt 
warum.

Wie die Ladungspumpe im Max232 genau funktioniert weiß ich auch nicht, 
aber ich kann mir schon vorstellen dass man ihn so zerschießen könnte. 
(Wenn an VS+ kurzzeitig <5V anliegen anfangs)

Weitere Idee: Sind die Pins am AT evtl. open drain?

: Bearbeitet durch User
von yafr (Gast)


Lesenswert?

Aber müsste durch die ganzen Annahmen er doch auch nicht senden können 
oder?

von bell (Gast)


Lesenswert?

Hast du schon mal versucht dich mit "hterm" dazwischen zu hängen? Da 
siehst du was gesendet und empfangen wird. Da musst du vielleicht dein 
Programm ein bisschen anpassen, aber du siehst erstmal was passiert!

von yafr (Gast)


Lesenswert?

ja hab ich. das hyterm empfängt das was ich sende.
Nur der AVR nicht was ich vom Hyterm sende.

achso der MAX232 ist die Variante CPE von reichtelt

von Karl H. (kbuchegg)


Lesenswert?

Ist es ein MAX232 oder ein MAX232A?

Bei den Typen ohne A sind 1µF ok. Der mit einem A in der 
Typenbezeichnung will dagegen nur 100nF.


Ansonsten: Ob die Ladungspumpe arbeitet kannst du an den Pins V+ (2) 
bzw. V- (6) feststellen. Dort sollten (bezogen auf GND) ca +10V bzw. 
-10V anliegen.


einfaches 'Testgerät': verkabel dir eine LED mit einem 220Ohm 
Vorwiderstand nach GND. Im HTerm stellst du alles korrekt ein und legst 
einen Stein auf die Tastatur (dauersenden). Dann nimmst du das freie 
Ende der LED und fängst am PC an, das Signal zu verfolgen. Wenn der PC 
sendet, dann siehst du die LED fröhlich blinken. Dieses Blinken 
verfolgst du jetzt vom PC über alle Leitungen, bis du beim Mega am RxD 
Pin angelangt bist. Sehr wahrscheinlich wird es irgendwo dazwischen 
verschwinden. Dort musst du dann nachsehen, wo das Problem liegt.

: Bearbeitet durch User
von yafr (Gast)


Lesenswert?

Danke Karl Heinz, werde ich probieren. Ob ohne oder mit a prüfe ich.

Es wurde die ganze Zeit von der Hardware und dem MAx232 gesprochen, habt 
ihr über den Code geschaut? Ist das alles soweit iO?

von yafr (Gast)


Lesenswert?

das Problem war natürlich mal wieder ein Layoutfehler.
Im Eagle-Makro vom Max232 ist gnd und Vcc als lose Pins aufgeführt und 
nicht wie oben schon erwähnt im IC-Kasten.

Daher habe ich VCC nicht layoutet. Aber GND wurde komischerweise von 
Eagle automatisch geroutet. naja wie auch immer.

Jetzt empfange ich auch daten.
nur muss ich mich jetzt noch mit den Datenformaten auseinandersetzen.

Wenn ich über das Hterm eine 1 sende kommt bei AVR als wert 490 an, bei 
der 2 500 und zB bei "a" 970. aber das wird wohl der Ascii wert sein 
oder so.
Naja aber die Hardware steht schon mal.

Danke für die Hilfe. Ich ärger mich noch eine Runde grün und blau das es 
mal wieder ein Fehler war, den man eigentlich schon in der ersten Woche 
der Ausbildung lernt: 1.Schritt Fehlersuche: Versorgungsspannung prüfen!

Oh man man sieht den Wald vor lauter Bäumen nicht....ob das daran liegt 
das die Tannen zapfen?

von Karl H. (kbuchegg)


Lesenswert?

yafr schrieb:
> das Problem war natürlich mal wieder ein Layoutfehler.
> Im Eagle-Makro vom Max232 ist gnd und Vcc als lose Pins aufgeführt und
> nicht wie oben schon erwähnt im IC-Kasten.
>
> Daher habe ich VCC nicht layoutet. Aber GND wurde komischerweise von
> Eagle automatisch geroutet. naja wie auch immer.
>
> Jetzt empfange ich auch daten.
> nur muss ich mich jetzt noch mit den Datenformaten auseinandersetzen.
>
> Wenn ich über das Hterm eine 1 sende kommt bei AVR als wert 490 an

Das kann nicht sein.
Deine Baudrate stimmt nicht.
Was mich bei Verwendung des internen Taktes auch nicht besonders 
wundert.
Der hat nicht 8Mhz. Zumindest nicht genau 8Mhz. Zumindest nicht genau 
genug.

> der 2 500 und zB bei "a" 970. aber das wird wohl der Ascii wert sein
> oder so.
No.
490 ist schon mal größer als 255. Und 255 ist der maximale Wert, den 1 
Byte annehmen kann. Wenn du da also was größeres als 255 siehst, dann 
stimmt irgendwas anderes nicht.

Schieb hier mal
1
      c = uart_getc();
2
    itoa(c,buffer2,10);
3
 lcd_goto(0,0);
4
 lcd_string(buffer2);
noch mindestens 1 Leerzeichen nach. Damit dich beim überschreiben von zb 
100 durch 49, die übrig gebliebene 0 nicht narrt.
1
      c = uart_getc();
2
    itoa(c,buffer2,10);
3
 lcd_goto(0,0);
4
 lcd_string(buffer2);
5
 lcd_string("   ");

: Bearbeitet durch User
von yafr (Gast)


Lesenswert?

das ist mir auch gerade aufgefallen. das einfach das letzte Zeichen 
nicht überschrieben wird.

aber du warst schneller mit der Lösung ;-)

von Karl H. (kbuchegg)


Lesenswert?

yafr schrieb:
> das ist mir auch gerade aufgefallen. das einfach das letzte Zeichen
> nicht überschrieben wird.
>
> aber du warst schneller mit der Lösung ;-)

Tip.
Bei derartigen Dingen sind Dezimalzahlen keine gute Idee. In praktisch 
jeder ASCII Tabelle findest du die Codes in Hexadezimaler Form.

Man kann sich jetzt natürlich eine HEX-Ausgabe bauen. Aber für ein 
einfaches Testprogramm tut es auch sprintf. Das hat den Vorteil, dass 
man es anweisen kann, führende 0-en nicht zu unterdrücken, so dass alle 
mit 1 Byte darstellbaren Zahlen immer die gleiche Länge aufweisen
1
      c = uart_getc();
2
      sprintf( buffer2, "0x%02X (%c)", c, c );
3
      lcd_goto( 0, 0 );
4
      lcd_string( buffer2 );

und bei der Gelegenheit lassen sich dann auch gleich noch andere 
Formatierungen mit einbauen. Zum Beispiel das Zeichen in seiner lesbaren 
Form :-)

: Bearbeitet durch User
von yafr (Gast)


Lesenswert?

Karl Heinz schrieb:
> sprintf( buffer2, "0x%02X (%c)", c, c );

ich bin einfach nur Baff,
da sieht man man was es heißt Ahnung zu haben oder sich 
druchzuwurschteln und zu versuchen sich es als Autodidakt beizubringen.

Danke für die große Hilfestellung. Ohne diese wäre ich wahrscheinlich 
noch dem Wahnsinn verfallen.

von Karl H. (kbuchegg)


Lesenswert?

yafr schrieb:
> Karl Heinz schrieb:
>> sprintf( buffer2, "0x%02X (%c)", c, c );
>
> ich bin einfach nur Baff,
> da sieht man man was es heißt Ahnung zu haben

Nein.
Da sieht man mal, was man alles wissen könnte, wen man sich ein C Buch 
zulegen und auch lesen würde.
Der Umgang mit der printf Familie und was man mit dem Formatstring alles 
anstellen kann, ist noch eine der allereinfachsten Übungen.

: Bearbeitet durch User
von yafr (Gast)


Lesenswert?

Hast du eine Empfehlung für ein gutes Buch?

von Karl H. (kbuchegg)


Lesenswert?

Der Klassiker "Kernighan&Ritchie, Programmieren in C" wird immer gerne 
genommen. Aber es gibt auch jede Menge anderer Bücher da draussen. Ich 
würde in eine Buchhandlung gehen und dort mal ein paar durchschmökern, 
womit du zurecht kommst.

http://openbook.galileo-press.de/c_von_a_bis_z/

Auf dem PC eine der freien Entwicklungsumgebungen installieren und dort 
mal die ersten Kapitel durchackern.

von yafr (Gast)


Lesenswert?

Ich habe mal einen Kumpel gefragt der auch viel Programmiert, aber Java.
Der hat noch ein "C"-Buch, und zwar das hier:

Praktisches Programmieren in C Broschiert
von Andreas Ganzer

Hatte nicht rein geschaut, meinte nur das sie C mal in der Schule kurz 
hatten und der Leherer für ne Schutzgebühr an eine Auflage ran kam, da 
hat er eins genommen.

Ist das zu gebrauchen?

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.