Forum: Compiler & IDEs Uart Fehler mit atmega8


von kartoffel (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,
leider hab ich einen sehr komischen Fehler mit der Uart auf meinem 
atmega8.
Der mega8 kann Daten zum Pc senden und der Pc empfängt diese auch. Der 
umgekehrt Weg aber funktioniert nicht.
Aufbau:
Das meiste ist auf den Bilder im Anhang gut zu erkennen.
-  Max232N mit 1uF Elkos
-  Atmega8-16U mit 100nF (und Programmer-Schnittstelle)

Ich hab auch schon einige Dinge versucht:
-  Am rs232 Pin 2 und 3 überbrückt. Das Echo kam an
-  Pin 12 und 11 am max232 überbrückt. Echo kam nicht an.
-  Max232 ausgetauscht.  Keine Auswirkung.
-  R2 anstatt R1 am max232 benutzt. Hatte auch keine Auswirkung
Ich habe mir auch schon einige Anleitungen angeschaut darunter auch 
diese hier:
http://www.mikrocontroller.net/articles/AVR-Tutorial:_UART
Auch habe ich diverse Beiträge im Forum durchgelesen aber diese bringen 
mir auch nichts. Leider steht mir kein Oszilloskop zur Verfügung, um 
genau feststellen zu können was bis wo ankommt.

Ich hoffe dass mir jemand helfen kann. Im Anhang sind noch Bilder der 
Schaltung zu finden.
Vielen Dank schon mal im Voraus.


Quellcode:



#include <avr/io.h>
#ifndef F_CPU

#warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 
4000000"
#define F_CPU 4000000UL  // Systemtakt in Hz - Definition als unsigned 
long beachten
                         // Ohne ergeben sich unten Fehler in der 
Berechnung
#endif

#define BAUD 9600UL      // 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





// bei neueren AVRs andere Bezeichnung fuer die Statusregister, hier 
ATmega8:
int uart_putc(unsigned char c)
{
    while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
    {
    }

    UDR = c;                      /* sende Zeichen */
    return 0;
}


/* puts ist unabhaengig vom Controllertyp */
void uart_puts (char *s)
{
    while (*s)
    {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen" */
        uart_putc(*s);
        s++;
    }
}
static uint8_t uart_getc_wait()
{
    // Warten, bis etwas empfangen wird
    while (!(UCSRA & (1 << RXC)))
        ;

    // Das empfangene Zeichen zurückliefern
    return UDR;
}

int main(void)
{
    UCSRB |= (1<<TXEN);                // UART TX einschalten
    UCSRC |= (1<<URSEL)|(3<<UCSZ0);    // Asynchron 8N1

    UBRRH = UBRR_VAL >> 8;
    UBRRL = UBRR_VAL & 0xFF;

        do
    {
        UDR;
    }
    while (UCSRA & (1 << RXC));

  while(1){
      uart_putc('s');
      uint8_t data=uart_getc_wait();
      //data++;
  }


}

von Floh (Gast)


Lesenswert?

Also:
- beide Vcc anschließen
- an jedes Vcc/Gnd-Pärchen ein Blockkondensator (100nF)
- Kabellängen am besten so kurz wie möglich
- Litzekabel is nicht so toll fürs Steckbrett -> Kontaktschwierigkeiten

ansosnten haste deinen Fehler ja schon eingegrenzt:
> -  Pin 12 und 11 am max232 überbrückt. Echo kam nicht an.
:-) Das muss funktionieren.

Übrigends, wie erkennst du das dein uC nichts empfängt?
> while(1){
>       uart_putc('s');
>       uint8_t data=uart_getc_wait();
>       //data++;
>   }

von Thomas W. (lodentoni)


Lesenswert?

kartoffel schrieb:
> Ich hab auch schon einige Dinge versucht:
> -  Am rs232 Pin 2 und 3 überbrückt. Das Echo kam an
> -  Pin 12 und 11 am max232 überbrückt. Echo kam nicht an.
> -  Max232 ausgetauscht.  Keine Auswirkung.
> -  R2 anstatt R1 am max232 benutzt. Hatte auch keine Auswirkung

Meine Vorschläge zum testen wären:
-Als erstes den Mikrocontroller abklemmen.
-Alle Spannungen durchmessen VCC, V+, V-. Die Spannungen sollten alle 
innerhalb ihrer Sollwerte liegen. Häufig haben die Steckbretter 
fehlerhafte Kontakte. Stecken alle Beinchen richtig drin?
-Den MAX232 spannungsfrei machen und die Pins 14 und 13 brücken, das 
Echo funktionierte bei dir ja bereits.
-dann die Brücke wieder öffnen, Spannung wieder anlegen und die Pins 1 
und 12 Brücken (echo?)

Wo holst du die Versorgungsspannung her? Welcher SUB-D Pin hängt an 
welchem MAX232 Pin? Benutzt du ein 1:1 oder ein Nullmodem (X-Over) 
Kabel?

von kartoffel (Gast)


Lesenswert?

also am max232 soll ja ein 1uF elko reichen..
und ich weiß nicht welchen Vcc du meinst Flo. Ich dachte ich hätte alle

ähm ja wie ich das erkenne. Wie im Programm oben zu erkennen müsste ich 
ja nach jedem empfangenden Zeichen ein "s" bekommen oder irre ich mich?

Ja vielleicht sehe ich einfach den Wald vor lauter Bäumen nicht.

Danke das du so schnell geantwortet hast.

von kartoffel (Gast)


Lesenswert?

Ok Thomas Weinhold ich werde dass dann mal eben machen

von Karl H. (kbuchegg)


Lesenswert?

>     UCSRB |= (1<<TXEN);                // UART TX einschalten

Receiver einschalten soll helfen.

von kartoffel (Gast)


Lesenswert?

Meine Ergebnisse:

Alle Pins beziehen sich auf den MAX232:
-PIN 16 zu 15 (Vcc, GND) 5 V
-PIN 2 (V+) zu GND 8,9 V
-PIN 6 (V-) zu GND -8,33 V

- das überbrücken am RS232 verlief erfolgreich. Also es war ein echo da
- T1in und R1out überbrücken (mit Spannung für Max232). OHAA geht auch 
=)

Jetzt schließe ich mein AVR zu

R1out an PD0
T1in an PD1

und es läuft nicht.

Hm dann muss wohl was am Programm sein.

Danke schonmal ^^

von kartoffel (Gast)


Lesenswert?

Jo danke das wars. Danke nochmal ^^.. Immer diese Kaka Fehler die man 
nie sieht.

Für alle die ein Testcode Brauchen:

Quellcode:
1
#include <avr/io.h>
2
#ifndef F_CPU
3
4
#warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 4000000"
5
#define F_CPU 4000000UL  // Systemtakt in Hz - Definition als unsigned long beachten
6
                         // Ohne ergeben sich unten Fehler in der Berechnung
7
#endif
8
9
#define BAUD 9600UL      // Baudrate
10
11
// Konstanten fuer die Baudrate aus der Taktfrequenz berechnen
12
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
13
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
14
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
15
16
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
17
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
18
#endif
19
20
// bei neueren AVRs andere Bezeichnung fuer die Statusregister, hier ATmega8:
21
int uart_putc( unsigned char c )
22
{
23
  while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
24
    ;
25
26
  UDR = c;                      /* sende Zeichen */
27
  return 0;
28
}
29
30
uint8_t uart_getc_wait()
31
{
32
  // Warten, bis etwas empfangen wird
33
  while (!(UCSRA & (1 << RXC)))
34
    ;
35
36
  // Das empfangene Zeichen zurückliefern
37
  return UDR;
38
}
39
40
/* String senden */
41
void uart_puts( const char *s )
42
{
43
  while (*s)
44
  {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen" */
45
    uart_putc(*s);
46
    s++;
47
  }
48
}
49
50
int main(void)
51
{
52
  uint8_t data;
53
54
  UCSRB |= (1<<TXEN) | (1<<RXEN);    // UART TX/RX einschalten
55
  UCSRC |= (1<<URSEL) | (3<<UCSZ0);    // Asynchron 8N1
56
57
  UBRRH = UBRR_VAL >> 8;             // Baudrate setzen
58
  UBRRL = UBRR_VAL & 0xFF;
59
60
  do                          // UART Empfangsbuffer entleeren
61
  {
62
    UDR;
63
  } while (UCSRA & (1 << RXC));
64
65
  while( 1 )
66
  {
67
    uart_putc( 's' );         // 's' Senden
68
    data = uart_getc_wait();  // Zeichen empfangen
69
    uart_putc( data );        // Zeichen als Echo zurücksenden
70
  }
71
}

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.