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


von elmo (Gast)


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
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <util/delay.h>
4
#define F_CPU 16000000UL
5
#define BAUD 38400UL          // Baudrate
6
 
7
// Berechnungen
8
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
9
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
10
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
11
 
12
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
13
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! 
14
#endif
15
16
uint8_t i=0;
17
18
void uart_init (void)
19
{
20
  UBRRH = UBRR_VAL >> 8;  //Baudrate setzen
21
    UBRRL = UBRR_VAL;
22
  UCSRC |= (1<<URSEL)|(1 << UCSZ1)|(1 << UCSZ0); // Asynchron 8N1
23
  UCSRB |= (1<<TXEN);                            // UART TX einschalten
24
} 
25
26
void uart_Transmit(unsigned char value)
27
{
28
 while (!(UCSRA & (1<<UDRE)));
29
    UDR = value;   
30
}
31
32
int main ()
33
{
34
DDRC=0x01; //led port als ausgang
35
uart_init();
36
37
  while(1)
38
  {  
39
    uart_Transmit('a');
40
    PORTC^=(1<<PC0); //toggle led (1 sek)
41
    for (i=0; i<100; i++)
42
    {
43
      _delay_ms(10);
44
      
45
    }
46
  }
47
48
49
return 0;
50
}

von gast (Gast)


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);

    }
"

von gast (Gast)


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);
}

von elmo (Gast)


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?!

von gast (Gast)


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

von elmo (Gast)


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?

von elmo (Gast)


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.

von David (Gast)


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...

von spess53 (Gast)


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

von elmo (Gast)


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 
;-)

von Thilo M. (Gast)


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?)

von elmo (Gast)


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...

von ich (Gast)


Lesenswert?

ich hab dein Programm mal getestet. Also bei mir funktioniert es, nur du 
musst den Spaß in der Reihenfolge einbinden.
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#define F_CPU 16000000UL
4
#define BAUD 38400UL          // Baudrate
5
6
#include <util/delay.h>

von Stefan B. (stefan) Benutzerseite


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?

von elmo (Gast)


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 :-)

von spess53 (Gast)


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

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.