Forum: Mikrocontroller und Digitale Elektronik AVR ATmega88 UART Problem


von Modellflieger (Gast)


Lesenswert?

Hallo zusammen,

bin noch Anfänger im C Programmieren und habe ein Problem mit dem UART 
vom ATmega 88. Es tut sich weder was, wenn der UART über nen MAX232 was 
an den PC senden soll, noch wenn der UART irgendwelche Zeichen vom PC 
empfangen soll.

Baudrate: 9600
Datenbits: 8
Parität: keine
Stopbit: 1


USART.C
1
 
2
//usart.c
3
4
void usart_init(void)
5
{
6
    UCSR0A |= 0x00;
7
    UCSR0B |= 0x18;
8
    UCSR0C |= 0x06;
9
    UBRR0H |= 0x00;
10
    UBRR0L |= 0x67;
11
}
12
13
unsigned char usart_getchar(void)
14
{
15
while(!(UCSR0A & (1<<RXC0)))
16
    {
17
        ;
18
    }    
19
    
20
return UDR0;
21
} 
22
23
void usart_putchar(unsigned char c)
24
{
25
while(!(UCSR0A & (1<<UDRE0)))
26
    {
27
        ;
28
    }
29
30
UDR0 = c;
31
}

MAIN.C
1
//main.c
2
3
void main(void)
4
{
5
    unsigned char zeichen;
6
    
7
    app_init();
8
    
9
    lcd_init();
10
                    
11
    delay_ms(50);
12
    
13
    lcd_clear();
14
    
15
    lcd_home;
16
17
    lcd_string("USART-Zeichen:");
18
    
19
    usart_init();
20
      
21
    delay_ms(50);
22
    
23
    usart_putchar('T');
24
    usart_putchar('E');
25
    usart_putchar('S');
26
    usart_putchar('T'); 
27
     
28
    while (1)
29
    {
30
        zeichen = usart_getchar();
31
    
32
        set_cursor(5,2);
33
    
34
        lcd_data(zeichen);
35
             
36
    }
37
}

Habe schon alles mögliche ausprobiert und finde trozdem keine Lösung.
Sind die Register alle richtig gesetzt?

Mit dem Oscar habe ich auch schon gemessen, ob überhaupt was am RX vom 
µC ankommt. Alles in Ordnung. MAX232 funktioniert.
Aber es geht kein Signal vom TX pin des µC raus.

Was mache ich nur wieder falsch?

Danke im Voraus

von Karl H. (kbuchegg)


Lesenswert?

void usart_init(void)
{
    UCSR0A |= 0x00;
    UCSR0B |= 0x18;
    UCSR0C |= 0x06;
    UBRR0H |= 0x00;
    UBRR0L |= 0x67;
}

Ach nö.
Drösel das bitte in Bits auf und benutze die dafür vorgesehenen 
Bitnamen. So macht das keinen Spass.

von Modellflieger (Gast)


Lesenswert?

1
void usart_init(void)
2
{
3
// im UCSR0A wird nichts gesetzt
4
5
UCSR0B = (1<<RXEN0) | (1<<TXEN0)
6
UCSR0C = (1<<UCSZ01) | (1<<UCSZ00)
7
8
//für 16 MHz und 9600 8N1 muss im UBBR 103 stehen
9
UBBR0H = 0x00
10
UBBR0L = 0x67
11
}

von Smdfreak (Gast)


Lesenswert?

Wofür so lange delays?!

von Hc Z. (mizch)


Lesenswert?

Schritt für Schritt, nicht gleich alles auf einmal testen wollen:

Kürze RxD und TxD am Prozessorsockel und schau, ob ein Terminalprogramm 
die eigenen Zeichen zurückbekommt.

Mach' einen while(1) oder for(;;) um die 4 uart_putchar()s von "TEST" 
herum.  So kannst Du den Sender für sich prüfen.  Erfolgt eine 
Dauersendung am TxD-Pin?  Am Ausgang des MAX232?  Wird der Text im 
Terminalprogramm dargestellt?  Wenn nicht, weißt Du, wo Du suchen musst 
oder kannst hier Deine Anfrage genauer eingrenzen.

Sobald das geht, sende empfangene Zeichen über den UART zurück.  Dass 
dessen Senderoutine geht, weißt Du ja jetzt.

Und zum krönenden Abschluss gibst Du das Zeug auf'm Display aus.

von Modellflieger (Gast)


Lesenswert?

Hallo,

hab es gerade probiert, aber es hat sich nichts geändert:

Wenn ich RXD und TXD überbrücke, bekommt man im Terminal alles korrekt 
zurück.

Aber auch in der Endlosschleife kommt garnichts aus dem µC raus.Habs mit 
nem Oskar und Logikprüfer geprüft.

Hab den MAX232 nochmal überprüft: alles einwandfrei.

Ich finde einfach keinen Fehler.

Danke für die Antwort.

von ccc (Gast)


Lesenswert?

dann liegt der fehler wohl in der software!

von Modellflieger (Gast)


Lesenswert?

Hilfreicher Beitrag!

Hat echt niemand eine Idee??

von Falk B. (falk)


Lesenswert?

@  Modellflieger (Gast)

>Hat echt niemand eine Idee??

Nach dem fünfmillionsten Thread "Hilfe, mein UART spinnt" hat kaum einer 
der "alten Hasen" noch Bock, den gleichen Kram immer wieder 
durchzukauen.

Wenn du dich an das Tutorial und die Checkliste WIRKLICH hälst, wird 
dein UART laufen. Da er es nicht tut, hast du was nicht beachtet, was 
dort aber steht!!!

MFG
Falk

von Stefan E. (sternst)


Lesenswert?

> Aber es geht kein Signal vom TX pin des µC raus.

Dir ist aber schon klar, dass mit dem Code oben nur ganz kurz mal direkt 
nach dem Reset am Tx-Pin was zu sehen ist, oder?

Am besten sendest du jetzt mal in einer Endlosschleife ein 'U'. Das 
ergibt eine kontinuierliche 0/1-Abfolge. Schau nochmal mit dem 
Oszilloskop nach, und kontrolliere dabei auch gleich die Bitlänge.

von Modellflieger (Gast)


Lesenswert?

Hallo,

danke für die Antwort.
Aber nach dem Rat von Hazeh Zimmerer läuft "TEST" nun immer in einer 
Schleife.
Aktueller Code ist also dieser:

MAIN.C
1
void main(void)
2
{
3
    unsigned char zeichen;
4
    
5
    app_init();
6
    
7
    lcd_init();
8
                    
9
    delay_ms(50);
10
    
11
    lcd_clear();
12
    
13
    lcd_home;
14
15
    lcd_string("USART-Zeichen:");
16
    
17
    usart_init();
18
      
19
    delay_ms(50);
20
    
21
    for(;;)
22
    {
23
    usart_putchar('T');
24
    usart_putchar('E');
25
    usart_putchar('S');
26
    usart_putchar('T'); 
27
    } 
28
29
}


Und dabei ist sowohl mit dem Oskar als auch mit einem Logikprüfer nichts 
am Pin des µC zu sehen.
Könnte natürlich auch kontinuierlich ein "U" senden, aber ich denke dass 
es die Sache nicht verbessern wird.

von Modellflieger (Gast)


Lesenswert?

Habe es gerade nochmal mit nur einem Zeichen ausprobiert.
Code ist aktuell also folgender:

MAIN.C
1
void main(void)
2
{
3
    unsigned char zeichen;
4
    
5
    app_init();
6
    
7
    lcd_init();
8
                    
9
    delay_ms(50);
10
    
11
    lcd_clear();
12
    
13
    lcd_home;
14
15
    lcd_string("USART-Zeichen:");
16
    
17
    usart_init();
18
      
19
    delay_ms(50);
20
    
21
    for(;;)
22
    {
23
    usart_putchar('U');
24
 
25
    } 
26
27
}

von Modellflieger (Gast)


Lesenswert?

Funktioniert aber trozdem garnichts wie schon vorher.

von Smdfreak (Gast)


Lesenswert?

Müsste eigentlich schon funktionieren. Wüsste auch nicht wo der Fehler 
liegt. Im Datenblatt stehen das ja auch so.

von smdfreak (Gast)


Lesenswert?

void usart_init(void)
{
// im UCSR0A wird nichts gesetzt

UCSR0B = (1<<RXEN0) | (1<<TXEN0)
UCSR0C = (1<<UCSZ01) | (1<<UCSZ00)

//für 16 MHz und 9600 8N1 muss im UBBR 103 stehen
UBBR0H = 0x00
UBBR0L = 0x67
}


Das ist übrigens falsch. Richtig wäre:
1
void usart_init(void)
2
{
3
// im UCSR0A wird nichts gesetzt
4
5
UCSR0B = (1<<RXEN0) | (1<<TXEN0)
6
UCSR0C = (3<<UCSZ01) | (3<<UCSZ00)
7
8
//für 16 MHz und 9600 8N1 muss im UBBR 103 stehen
9
UBBR0H = 0x00
10
UBBR0L = 0x67
11
}

von Justus S. (jussa)


Lesenswert?

smdfreak schrieb:


>
1
> UCSR0C = (3<<UCSZ01) | (3<<UCSZ00)
2
>

Was ist denn das für ein Käse? Warum soll er bitte UCPOL0 setzen? Und 
warum bitte UCSZ00 zweimal auf 1 setzen?

von Modellflieger (Gast)


Lesenswert?

Hallo,

jetzt blick ich garnicht mehr durch.
Ich dachte in dieser Schreibweise würde das Bit um 3 Stellen nach links 
verschoben, oder wie?
Müsste dann nicht eigentlich UPM00 und UPM01 gesetzt werden??

Danke

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Dein Problem ist nicht die RS232 Schnittstelle. Dein Problem ist das 
hier:
> UCSR0C = (3<<UCSZ01) | (3<<UCSZ00)
Wieder mal das Thema "Bitmanipulation in C" nicht verstanden.
> Ich dachte in dieser Schreibweise würde das Bit um 3 Stellen nach links
> verschoben, oder wie?
Nein, es wird die 3 um irgendwas verschoben.
Es wird aber nicht irgendwas um 3 verschoben.
3 = 0x03 = 0b00000011 wird um UCSZ01 (#define UCSZ01 2) nach links 
geschoben: 0b00001100.
3 = 0x03 = 0b00000011 wird um UCSZ00 (= 1) nach links geschoben: 
0b00000110.
0b00001100 verodert mit 0b00000110 ergibt 0b00001110.
Wolltest du das?

BTW:
1
    UCSR0A |= 0x00;
2
    UCSR0B |= 0x18;
3
    UCSR0C |= 0x06;
4
    UBRR0H |= 0x00;
5
    UBRR0L |= 0x67;
Dort wird irgendwas zu irgendwas anderem dazugeodert. Willst du das 
wirklich? Mal angenommen, im UBRROL wäre vorher schon 0xFF drin. Was 
würden diese Zuweisungen dann ändern?
Das war vermutlich deine Absicht:
1
    UCSR0A = 0x00;
2
    UCSR0B = 0x18;
3
    UCSR0C = 0x06;
4
    UBRR0H = 0x00;
5
    UBRR0L = 0x67;

von Justus S. (jussa)


Lesenswert?

Lothar Miller schrieb:
> Dein Problem ist nicht die RS232 Schnittstelle. Dein Problem ist das
> hier:
>> UCSR0C = (3<<UCSZ01) | (3<<UCSZ00)
> Wieder mal das Thema "Bitmanipulation in C" nicht verstanden.

Der Quark kommt von smdfreak, modellflieger hatte es imo schon 
richtig...

von Modellflieger (Gast)


Lesenswert?

Danke für diese Erklärung!

Jetzt habe ich diese Bitmanipulation endlich verstanden.
Für mich hat das auch immer garkeinen Sinn gemacht das um eins nach 
links zu verschieben. Deswegen verwende ich lieber die direkte 
Schreibweise mit hex.

Dann ergeben mir die Codes aus dem Forum auch viel mehr Sinn.

Also nochmals vielen Dank!!!

Ich glaube es wurde auch langsam mal Zeit das ich diese Schreibweise nun 
endlich verstanden habe.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Justus Skorps schrieb:
> Der Quark kommt von smdfreak, modellflieger hatte es imo schon richtig...
Oh, das hatte ich übersehen...

Modellflieger schrieb:
> Jetzt habe ich diese Bitmanipulation endlich verstanden.
> Für mich hat das auch immer garkeinen Sinn gemacht das um eins
> nach links zu verschieben.
Aber der letzte Schubser hatte offenbar trotzdem noch gefehlt  ;-)

von Modellflieger (Gast)


Lesenswert?

Ja wie gesagt wäre ich auch garnicht auf diese Schreibweise gekommen, 
wenn  Karl heinz Buchegger mir nicht dazu geraten hätte, weil ich 
wusste, dass ich das garnicht verstanden habe.
Mich wundert es nur, dass ich es sonst auch immer irgendwie hingemurkst 
bekommen habe. Naja das hab ich dann eben immer mit hex gemacht.

Wie kann man Lothar Miller nur dafür danken ?! =)

Aber die Lösung meines Problems ist es ja auch nicht!
Also es funktioniert immer noch nicht.

Hier nochmal der aktuelle Code:

USART.C
1
void usart_init(void)
2
{
3
    UCSR0A = 0x00;
4
    UCSR0B = 0x18;
5
    UCSR0C = 0x06;
6
    UBRR0H = 0x00;
7
    UBRR0L = 0x67;
8
9
}
10
11
12
13
14
unsigned char usart_getchar(void)
15
{
16
while(!(UCSR0A & (1<<RXC0)))
17
    {
18
        ;
19
    }    
20
    
21
return UDR0;
22
} 
23
24
void usart_putchar(unsigned char c)
25
{
26
while(!(UCSR0A & (1<<UDRE0)))
27
    {
28
        ;
29
    }
30
31
UDR0 = c;
32
}



MAIN.C
1
void main(void)
2
{
3
    
4
    app_init();
5
    
6
    lcd_init();
7
                    
8
    delay_ms(50);
9
    
10
    lcd_clear();
11
    
12
    lcd_home;
13
14
    lcd_string("USART-Zeichen:");
15
    
16
    usart_init();
17
      
18
    delay_ms(50);
19
    
20
    for(;;)
21
    {
22
    usart_putchar('U');
23
 
24
    } 
25
26
}

von Helmut L. (helmi1)


Lesenswert?

#include <avr/io.h>

void usart_putchar(unsigned char c)
{
    while(!(UCSR0A & (1<<UDRE0)))
    {
        ;
    }

    UDR0 = c;
}
void  main(void)
{

    UCSR0A = 0x00;
    UCSR0B = 0x18;
    UCSR0C = 0x06;
    UBRR0H = 0x00;
    UBRR0L = 0x67;


  for(;;)
    {
    usart_putchar('T');
    usart_putchar('E');
    usart_putchar('S');
    usart_putchar('T');

    }
}

Also ich habe das gerade mal getestet und es funktioniert.
Hast du auch den ATMega 88  im AVR-Studio richtig eingetragen ?

Gruss Helmi

von Modellflieger (Gast)


Lesenswert?

Hallo,

also ich benutze CodeVision AVR und da war alles richtig eingestellt.
Also auf dem LCD wird auch "UART Zeichen" angezeigt.
Deswegen kann nicht grundsätzlich was kaputt sein oder was auch immer.
Oder kann es sein das nur der UART kaputt geht und der Rest noch 
funktioniert?!

Ich meine mich zu erinnern, dass der UART unter Bascom schonmal was 
ausgespuckt hat.
Werde wohl mal wieder das Bascomprogramm draufmachen und gucken, wenn 
ich Zeit habe.

Danke für die Antwort und viele Grüße.

von Helmut L. (helmi1)


Angehängte Dateien:

Lesenswert?

Dann versuch mal diese Hex-File. Bei mir funktioniert es.

von Modellflieger (Gast)


Lesenswert?

Hallo zusammen,

da ich im Moment in der Klausurphase bin, konnte ich den .hex-file 
gerade erst ausprobieren.
Und siehe da, es funktioniert! Ich bin verwirrt! Ich zweifle langsam an 
mir selbst.
Naja aber herzlichen Dank für die super Hilfe (besonders durch Helmut 
Lenzen)!!!

Dann werde ich mal weiter suchen; kann jetzt den Fehler ja sehr weit 
eingrenzen!

von Modellflieger (Gast)


Lesenswert?

Hallo,

hab mal alles mögliche nochmal ausprobiert und exakt den gleichen Code 
von Helmut Lenzen verwendet. Doch mein Programm funktioniert immer noch 
nicht.
So langsam weiß ich echt nicht mehr was ich noch machen kann.

Wenn noch jemand eine Idee hat, dann wäre ich dankbar.

von Helmut L. (helmi1)


Lesenswert?

@ Modellflieger

Versuch mal das AVR Studio mit dem GCC zu installieren.
Das ist der Compiler den ich verwende.
Kann sein das in Codevision noch was einzustellen ist. Was weiss ich 
aber nicht da ich mit dem bisher noch nichts zu tun hatte.

von Modellflieger (Gast)


Lesenswert?

Habe ich auch schon gedacht.
Werde es jetzt mal versuchen.
Danke

von Helmut L. (helmi1)


Lesenswert?

Na dann berichte mal obs geklappt hat

von Fabio W. (modellbu)


Lesenswert?

Hallo,

bekomme immer folgende Fehlermeldung:

Build started 8.12.2009 at 20:14:29
avr-gcc -I"C:\Users\Fabio\Documents\µC\UARTTest\."  -mmcu=atmega88 -Wall 
-gdwarf-2 -std=gnu99   -DF_CPU=16000000UL -Os -funsigned-char 
-funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT main.o -MF 
dep/main.o.d  -c  ../main.c
/usr/bin/sh: avr-gcc: command not found
make: *** [main.o] Error 127
Build failed with 1 errors and 0 warnings...


Kann mir jemand helfen?

von Fabio W. (modellbu)


Lesenswert?

P.S: ICh hieß vorher Modellflieger, damit ihr Bescheid wisst.

von Fabio W. (modellbu)


Lesenswert?

Habe alles noch einmal neu installiert.
Hat sich aber nicht an dem Error geändert.
Wo soll denn der Ordner /usr/bin/sh sein?
Und was muss da drin sein?

Danke

von Oliver (Gast)


Lesenswert?

>Habe alles noch einmal neu installiert.

Wohin? Unter welcher Windowsversion?

>avr-gcc -I"C:\Users\Fabio\Documents\µC\UARTTest\."  -mmcu=atmega88 -Wall

Sonderzeichen wie in "µC" sind im Pfad gefährlich. Mach da besser "uC" 
draus.

Oliver

von Fabio W. (modellbu)


Lesenswert?

Ich habe es unter Vista installiert.

von Fabio W. (modellbu)


Lesenswert?

Habe alles nochmal unter uC installiert und funktioniert trozdem nicht.

von Fabio W. (modellbu)


Lesenswert?

Hallo,

habe mal wieder Zeit gefunden mich mit dem Problem zu beschäftigen.
Und siehe da es funktioniert. Was genau falsch war, weiß ich nicht, ist 
aber auch egal, denn es funktioniert ja nun !
Das Problem ist nur, dass die Zeichen nur solange empfangen werden wie 
der Programmer noch aufgesteckt ist. Wenn man ihn abzieht (bei keiner 
Stromversorgung) kommt garnichts mehr (auch nach reset).
Weiß jemand woran das liegen könnte?

Danke

von spess53 (Gast)


Lesenswert?

Hi

>Weiß jemand woran das liegen könnte?

Sieht nach fehlender Masseverbindung aus.

MfG Spess

von Fabio W. (modellbu)


Lesenswert?

So jetzt funktioniert alles.

Danke an alle "Helfer" !

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.