www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik atmega 32: UART- Verzweiflung


Autor: elmo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Forum!

Ich habe lange probiert, aber ich komme einfach nicht weiter. Ich möchte 
mit dem UART des ATmega32 in einer Schleife ein Zeichen an den Rechner 
senden, erhalte aber statt des abgesendeten "a" ein großes "O". Ursache 
ist ja nun meistens falsche Baudrate durch falsche Taktfrequenz, aber 
folgende Punkte sind schon überprüft worden:
- Taktfrequenz 16MHz, externer Quarz - getestet mit delay.h und LED: 
stimmt
- Wert für 38400 BAUD in UBRR (aus Datenblatt) ist 25, wird auch korrekt 
berechnet
- UBRRH wird vor UBRRL beschrieben
- externe Beschaltung mit MAX232 okay, da bin ich sicher, da es sich um 
ein fertiges Eval-Board handelt und in anderen Projekten schon 
funktioniert hat.

Ich komme echt nicht mehr weiter, wäre nett, wenn von euch jemand auf 
den (minimalistischen) Quellcode schauen kann - vielleicht sehe ich den 
Wald vor lauter Bäumen nicht:

Danke,
Elmo
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define F_CPU 16000000UL
#define BAUD 38400UL          // Baudrate
 
// Berechnungen
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
 
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! 
#endif

uint8_t i=0;

void uart_init (void)
{
  UBRRH = UBRR_VAL >> 8;  //Baudrate setzen
    UBRRL = UBRR_VAL;
  UCSRC |= (1<<URSEL)|(1 << UCSZ1)|(1 << UCSZ0); // Asynchron 8N1
  UCSRB |= (1<<TXEN);                            // UART TX einschalten
} 

void uart_Transmit(unsigned char value)
{
 while (!(UCSRA & (1<<UDRE)));
    UDR = value;   
}

int main ()
{
DDRC=0x01; //led port als ausgang
uart_init();

  while(1)
  {  
    uart_Transmit('a');
    PORTC^=(1<<PC0); //toggle led (1 sek)
    for (i=0; i<100; i++)
    {
      _delay_ms(10);
      
    }
  }


return 0;
}


Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ermal muss in deiner uart_init
" UBRRH = UBRR_VAL >> 8;  //Baudrate setzen
    UBRRL = UBRR_VAL;"
ganz an den schluss und nicht an den anfang (steht so im datenblatt)

dann ist dies überflüssig geworden, da in der gcc von 2008 die schleife 
in der _delay_ms schon mit drin ist, falls die übergebene zahl zu gross 
ist
"    for (i=0; i<100; i++)
    {
      _delay_ms(10);

    }
"

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
so etwa:

#define BAUD 19200UL               //Baudrate
#define UBRR_BAUD   ((F_CPU/(16UL*BAUD))-1)

void uart_init()
{
UCSRB = (1<<RXEN)|(1<<TXEN); }
UCSRC |= ( 1 << URSEL )|(1 << UCSZ1)|(1 << UCSZ0);// A 8N1
UBRRH = (uint8_t) (UBRR_BAUD>>8);
UBRRL = (uint8_t) (UBRR_BAUD);
}

Autor: elmo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ermal muss in deiner uart_init
" UBRRH = UBRR_VAL >> 8;  //Baudrate setzen
    UBRRL = UBRR_VAL;"
ganz an den schluss und nicht an den anfang (steht so im datenblatt)


das habe ich probiert, brachte keine Änderung :-(
Das mit der Schleife wusste ich nicht, habe aber auch noch ne relativ 
alte gcc-Version - werde mir die neue mal ziehen, der UART sollte aber 
auch mit dem alten funktionieren...

noch ne Idee?!

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
evtl. liegt es ja nur an der interpretation des zeichens am pc, mit was 
empfängst du, hyperterminal?
probier mal ein anderes zeichen ,z.b ein 'b' und schau ob der 
zeichenabstand beim empfangen der gleiche ist
a-->O
b-->P
etc.
dann sollte es eher an der interpretation der ascii zeichen liegen

Autor: elmo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zusatzinfo:

Ich weiß nicht, ob das was zu sagen hat, aber der UART sendet nur was, 
wenn der ISP-Stecker ABGEZOGEN (also nicht aufgesteckt, wie bei 
fehlender Masse) ist. Die Takt-Kontroll-LED blinkt so, oder so. Kann es 
irgendwie damit zusammenhängen?

Autor: elmo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hmm, wenn ich statt des "a" ein "b" sende, erhalte ich das Zeichen "'" 
(ascii 39) und nicht "O" (ascii 79). Verwende das Terminalprogramm von 
Br@y++ - hab's aber auch schon mit Hyperterm getestet, da ist es 
dasselbe.

Autor: David (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>>Ich weiß nicht, ob das was zu sagen hat, aber der UART sendet nur was,
>>denn der ISP-Stecker ABGEZOGEN (also nicht aufgesteckt, wie bei
>>fehlender Masse) ist. Die Takt-Kontroll-LED blinkt so, oder so. Kann es
>>irgendwie damit zusammenhängen?

also dass kann nicht sein, dass ein eingesteckter isp stecker einen 
einfluss hat. habe so etwas (verwende mkll) noch nie festgestellt, 
funktionierte soweit immer tiptop.
ergo -> hardware checken...

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Ich weiß nicht, ob das was zu sagen hat, aber der UART sendet nur was,

Sieht nach fehlender Masseverbundung zu PC aus.

MfG Spess

Autor: elmo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nein, eine FEHLENDE Masseverbindung kann's ja nicht sein, wenn das 
Senden nur funktioniert, wenn KEIN ISP angesteckt ist...
Hardware checken habe ich im Rahmen meiner Möglichkeiten gemacht, MAX232 
auch ausgetauscht - selbes Resultat wie bisher :-(
Wie gesagt, bei anderen Projekten hat das Board auch schon funktioniert, 
ist das RN-Control von Roboternetz.
Meine bisherigen µC-Erfahrungen reichen auch relativ weit über UART 
hinaus, deswegen könnte ich durchdrehen, dass ich schon daran scheitere 
;-)

Autor: Thilo M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>>Ich weiß nicht, ob das was zu sagen hat, aber der UART sendet nur was,
>>denn der ISP-Stecker ABGEZOGEN (also nicht aufgesteckt, wie bei

Beim MK-II ist es so, dass bei eingestecktem ISP-Stecker und 
ausgestecktem USB-Stecker der RESET-Pin auf low ist und das System 
steht.

Hast du evtl. Fuses falsch gesetzt (CKDIV8 oder so?)

Autor: elmo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
CKDIV8 gibts glaube ich gar nicht beim mega32, oder? Jedenfalls habe ich 
in PonyProg nicht die Möglichkeit die Fuse zu setzen...ansonsten sind 
CKSEL und CKOPT alle auf 1; SUT1=1, SUT0=0...das stimmt doch so für 
externen 16MHz-Quarz, oder? µC läuft auf jeden Fall mit dem externen 
Quarz, da er stehen bleit, wenn ich den Quarz rausziehe...

Autor: ich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich hab dein Programm mal getestet. Also bei mir funktioniert es, nur du 
musst den Spaß in der Reihenfolge einbinden.
#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 16000000UL
#define BAUD 38400UL          // Baudrate

#include <util/delay.h>

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stimmt, was "ich" schreibt! F_CPU muss vor dem include von delay.h 
bekannt sein.

Ansonsten: Hast du schon die Verbindungen im Loopback getestet?

Also beim (weniger wichtigen) PC Test RS232 Kabel am Evalboard abziehen, 
Pins 2 und 3 verbinden und dann PC was senden lassen. Es sollte als Echo 
auf den PC zurückkommen. Damit ist die PC-Schnittstelle OK und das Kabel 
physikalisch OK.

Beim µC Test RS232 Kabel am Evalboard abziehen und an der Buchse vom 
Evalboard Pins 2 und 3 verbinden. Programm schreiben, welches Zeichen 
sendet und empfängt. Gesendetes und Empfangenes vergleichen und LED 
schalten, wenn ungleich. Damit ist der MAX232, die Verbindungen und der 
UART Port am AVR physikalisch OK.

Welches Evalboard benutzt du, damit ich mir mal den Schaltplan ansehen 
kann. Deine Beobachtung mit dem ISP-Stecker macht mich neugierig. Und: 
Welchen ISP-Programmieradapter benutzt du?

Autor: elmo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke Stefan!

Während du das geschrieben hast, hatte ich die selbe Idee, nochmal die 
Verbindung zu checken (Loopback)...nachdem dies nicht funktionierte hab 
ich mir das Kabel nochmalgenauer angesehen und - ich traue mich das gar 
nichtg zusagen, mach's aber trotzdem, weil mir so viele geholfen haben - 
festgestellt, dass zwar RX richtig angeschlossen war, aber TX und GND 
vertauscht waren ... mich wundert nur, warum ich dann trotzdem etwas 
empfangen habe (wenn auch nur Müll).

Jedenfalls vielen Dank an alle, jetzt klappt's :-)

PS: Ihr könnt jetzt anfangen, euch über diesen Idiotenfehler lustig zu 
machen :-)

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>PS: Ihr könnt jetzt anfangen, euch über diesen Idiotenfehler lustig zu
>machen :-)

Wenn du wüsstest, was Fachleute schon für Fehler gemacht haben.

MfG Spess

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.