AVR ATmega88 UART Problem

Gast #1499136
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
#1499696
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.
Gast #1499796
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.
#1499857
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
#1499862
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.
Gast #1499869
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.
Gast #1499902
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
}
Gast #1500538
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
}
Moderator (Firma: Titel) Persönliche Seite #1500553
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;
Gast #1500564
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.
Moderator (Firma: Titel) Persönliche Seite #1500566
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  ;-)
Gast #1500579
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
}
#1500617
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
Gast #1500677
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.
Gast #1503780
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!
#1512431
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?
#1526468
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren