Forum: Mikrocontroller und Digitale Elektronik ATmega32: UART klappt nicht


von P4 (Gast)


Lesenswert?

Hallo, ich versuche heute schon den ganzen Nachmittag einfach nur ein 
Zeichen über die serielle Schnittstelle des uC zu senden, aber am PC 
kommt rein garnichts an...

Als Mikrocontroller verwende ich einen ATmega32 mit 16MHz Quarz auf 
einem STK500. Die Verkabelung (RS232 Spare auf PD0 und PD1) sollte so 
weit auch stimmen. Wenn ich auf dem STK500 einen Jumper zwischen RX und 
TX auf RS232_spare setze kommt beim hyperterminal am PC auch alles 
korrekt zurück, was von mir eingegeben wird.

Eistellung am PC: 8 Daten- 1 Stop Bit, kein parity, keine flusskontrolle

Ich habe es bereits so versucht wie es im Datenblatt des mega32 stand 
und so wie hier im AVR-GCC Tutorial.

Hier ist der Code, mit dem ich es momentan versuche:
1
#include <avr/io.h>
2
//#include<util/delay.h>
3
#ifndef F_CPU
4
5
#warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 16000000"
6
#define F_CPU 16000000UL    // Systemtakt in Hz - Definition als unsigned long beachten >> Ohne ergeben Fehler in der Berechnung
7
#endif
8
 
9
#define BAUD 9600UL          // Baudrate
10
 
11
// Berechnungen
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
int i;
20
 
21
int main(void)
22
{
23
  UCSRB |= (1<<TXEN);                // UART TX einschalten
24
  UCSRC |= (1<<URSEL)|(3<<UCSZ0);    // Asynchron 8N1 
25
 
26
  UBRRH = UBRR_VAL >> 8;
27
  UBRRL = UBRR_VAL & 0xFF;
28
  
29
  DDRB=0xff;
30
  PORTB=0xAA;  //Test
31
  
32
  while(1)
33
  {
34
  
35
    while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich                   */
36
    {
37
    }
38
   
39
    UDR = 'a';                    /* schreibt das Zeichen x auf die Schnittstelle */
40
    
41
    
42
      for(i=0;i<10000;i++);  // kurze verzoegerung
43
  }
44
45
}

Langsam bin ich schon am Verzweifeln...
Hat noch jemand Vorschläge/Tipps was ich noch unternehmen könnte?

mfg Patrick

von Totaler (Gast)


Lesenswert?

Hallo,

hatte vor kurem das gleiche Problem mit einem ATTINY.

1. Arbeite nicht mit Hyperterminal, ist schlecht zum Diagnostizieren,
   sondern verwende TERMINAL.exe.
   (Terminal zeigt dir jede aktivität auf der Schnittstelle an)
   Da ich es leider gerade nicht zur Hand habe kann ich Dir nicht sagen 
von wem es ist.

2. Überprüfe mal Deine FUSES, ob es da eines gibt, welches DIV8 oder so 
ähnlich heißt .

Gruß Hannes

von P4 (Gast)


Lesenswert?

bei "Terminal.exe" (ich nehme an du meinst das hier: 
http://www.b-kainka.de/terminal.jpg ) kommt ins Textfeld "Bytes 
empfangen" immer nur eine 0 hinzu, wenn ich auf "Open" klicke.

Ein DIV8 Fuse oder ähnlich konnte ich leider weder über AVR-Studio noch 
im Burn-o-mat finden. Das sind meine Fuses:
hfuse: 0x89
lfuse: 0xFF

Danke für deine Antwort, mfg
Patrick

von Totaler (Gast)


Lesenswert?

Hallo patrick,

die Fuse kann ich mir nicht ansehen, hab nur einen Internet Terminal.

Wenn ich an meinem Rechner bin schicke ich Dir info zu dem Programm


Gruß Hannes

von Karl H. (kbuchegg)


Lesenswert?

P4 wrote:
> bei "Terminal.exe" (ich nehme an du meinst das hier:
> http://www.b-kainka.de/terminal.jpg ) kommt ins Textfeld "Bytes
> empfangen" immer nur eine 0 hinzu, wenn ich auf "Open" klicke.
>
> Ein DIV8 Fuse oder ähnlich konnte ich leider weder über AVR-Studio noch
> im Burn-o-mat finden. Das sind meine Fuses:
> hfuse: 0x89
> lfuse: 0xFF


Hmm. Die Fuses sollten laut
http://www.engbedded.com/cgi-bin/fc.cgi
in Ordnung sein

von Hannes 0. (totaler)


Lesenswert?

Hallo Patrick,

ich meine dieses Terminal Programm
von Bray++
http://braypp.googlepages.com/terminal

Diese Programm ist ein muss bei versuchen mit serieller Schnittstelle.

Gruß Hannes

von Andreas M. (schnitzeltony)


Lesenswert?

Ich hätte da folgende Anmerkung:

In 99% der Fälle von UART Problemen ist eine Falsche Baudrate die 
Ursache (hab ich mal gelesen und kann es nur bestätigen :-))

Warum verwendest Du für die Baudraten Berechnung nicht util/setbaud.h? 
Das funktioniert bei mir sehr schön bei verschieden µC / Taktraten.

Bist Du sicher, dass der ATMega auch mit 16Mhz läuft? Bau doch mal eine 
LED-Blinkroutine, mit der Du das überprüfen kannst.

von P4 (Gast)


Lesenswert?

Hallo Andreas!
> Warum verwendest Du für die Baudraten Berechnung nicht util/setbaud.h?
gute Idee, wusste nicht dass es soetwas gibt. Hab das gleich mal 
eingefuegt.
Danke fuer den Tipp.

> Bist Du sicher, dass der ATMega auch mit 16Mhz läuft? Bau doch mal eine
> LED-Blinkroutine, mit der Du das überprüfen kannst.

Habe es gerade nocheinmal überprüft und eine Sekunde im Code dauert da 
auch eine Sekunde. (also mit dem Auge betrachtet, µs Stoppuhr ;) (bzw 
Oszilloskop) habe ich keine.

Ist dieser Code in Ordnung?
1
#define F_CPU 16000000
2
#include <avr/io.h>
3
#include <util/delay.h>
4
5
#define BAUD 9600
6
#include <util/setbaud.h>  //Berechnung der Baudrate wird dem Praeprozessor ueberlassen
7
8
int main(void)
9
{
10
  DDRB=0xff;  
11
  PORTB=0xAA;          //Test (jeder 2.pin=1)
12
  
13
  UCSRB |= (1<<TXEN);                // UART TX einschalten
14
  UCSRC |= (1<<URSEL)|(3<<UCSZ0);    // Asynchron 8N1 
15
  
16
  UBRRH = UBRRH_VALUE;  // von setbaud.h berechnet
17
  UBRRL = UBRRL_VALUE;  // ----------//-----------
18
19
  while(1)
20
  {
21
    
22
    PORTB = ~PORTB;        // Toggle PORTB
23
    _delay_ms(1000);        // stimmt bei 16MHz auch.
24
    
25
    while (!(UCSRA & (1<<UDRE))) { }    // warten bis Senden moeglich 
26
    UDR = 'a';          // Schreibe a ins Senderegister
27
        
28
  }
29
  
30
  return 0;
31
}

Danke für eure Antworten.

mfg Patrick

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Statt
1
  UCSRB |= (1<<TXEN);                // UART TX einschalten
2
  UCSRC |= (1<<URSEL)|(3<<UCSZ0);    // Asynchron 8N1

besser Register komplett setzen (entspricht Beispiel im Datenblatt)
1
  UCSRB = (1<<TXEN);                // UART TX einschalten
2
  UCSRC = (1<<URSEL)|(3<<UCSZ0);    // Asynchron 8N1

Dass du
> #include <util/setbaud.h>  //Berechnung der Baudrate wird dem Praeprozessor 
ueberlassen
verwendest finde ich interessant und gut. Diese Makros sind mir bisher 
entgangen. Ich habe das AVR-GCC-Tutorial im Abschnitt /UART 
initialisieren/ entsprechend ergänzt.

von P4 (Gast)


Lesenswert?

Danke Stefan, ich hab es geändert.

Mir ist es schon fast peinlich, dass ich ein UART Thema eröffnen habe, 
wo es doch schon so viele davon hier gibt, aber ich weiß einfach nicht 
mehr weiter...
Gibts noch irgendwelche Hinweise, die mich weiterbringen könnten?

Das "Terminal Programm von Bray++" zeigt mir an, dass 0 empfangen wurde, 
wenn ich auf Connect klicke. wenn das Board nicht angeschlossen ist 
steht nichts. Von dem senden in der Schleife bekomm ich am Terminal  gar 
nichts mit.

mfg Patrick

von Karl H. (kbuchegg)


Lesenswert?

P4 wrote:
> Danke Stefan, ich hab es geändert.
>
> Mir ist es schon fast peinlich, dass ich ein UART Thema eröffnen habe,
> wo es doch schon so viele davon hier gibt, aber ich weiß einfach nicht
> mehr weiter...
> Gibts noch irgendwelche Hinweise, die mich weiterbringen könnten?

Hmm.
Hast du dir schon mal angesehen, ob du auf den Leitungen Pegelwechsel 
hast (Oszi. Multimeter, Led dranhängen)

Deine Symptome sind normalerweise ein Klassiker dafür, dass die Baudrate 
nicht stimmt. Die häufigste Ursache dafür ist wiederrum, dass die 
tatsächliche Taktfrequenz nicht mit der im Pgm verwendeten 
übereinstimmt.

Ich denke die erste Frage, die beantwortet werden sollte ist:
Sendet der µC überhaupt. Mit einer LED an der Tx Leitung, die vom µC 
kommt, kannst du das leicht überprüfen.

von P4 (Gast)


Lesenswert?

>Ich denke die erste Frage, die beantwortet werden sollte ist:
>Sendet der µC überhaupt. Mit einer LED an der Tx Leitung, die vom µC
>kommt, kannst du das leicht überprüfen.
zeischen PD1 und VCC sind ständig 2,87 V, zwischen PD1 und GND sind es 
1,13 V. Änderungen sind keine erkennbar. (Gemessen mit Multimeter)

mfg Patrick

von Karl H. (kbuchegg)


Lesenswert?

P4 wrote:
>>Ich denke die erste Frage, die beantwortet werden sollte ist:
>>Sendet der µC überhaupt. Mit einer LED an der Tx Leitung, die vom µC
>>kommt, kannst du das leicht überprüfen.
> zeischen PD1 und VCC sind ständig 2,87 V, zwischen PD1 und GND sind es
> 1,13 V. Änderungen sind keine erkennbar. (Gemessen mit Multimeter)

Sendet dein µC dauernd?
Wenn ja, dann schaut das nicht so schlecht aus.
(Mach auch mal den Gegentest: UART nicht senden lassen. Dann muss sich 
der Pegel sauber stabilisieren).
Halt auch wirklich mal eine LED an den Pin. Wenn der UART sendet, 
müsstest du die deutlich flackern sehen.

Wie sehen die Pegel nach dem MAX232 (sprich am Kabel) aus?
(Mutlimeter, Led)

von P4 (Gast)


Lesenswert?

die vorherigen Werte wurden beim Senden eines Zeichens im 1-Sekunden 
Takt aufgenommen.

Beim Dauersenden habe ich zwischen PD1 und GND nur 0,5V gemessen (klingt 
nachvollziehbar, da es bei der seriellen Schnittstelle nur beim Senden 
Absenkungen der Spannung geben kann.)

Komischerweise sind die Spannungen konstant...

Nach dem MAX 202 habe ich an der Buchse beim Senden im 1-sekunden Takt 
als auch beim durchgehenden Senden 5,75V an Pin2 gegen GND...

Ich habe auch ein paar MAX232 hier herumliegen, kann ich die auch mit 
Keramik Kondensatoren betreiben? Vielleicht liegt der Fehler am 
Pegelwandler.

mfg Patrick

von P4 (Gast)


Lesenswert?

wobei, am MAX202 wirds wohl doch nicht liegen, da auch alles über ein 
echo zurückgekommen ist was ich am PC eingegeben habe, als ich Rx und Tx 
mit einem Jumper verbunden hatte.

von Karl H. (kbuchegg)


Lesenswert?

P4 wrote:
> wobei, am MAX202 wirds wohl doch nicht liegen, da auch alles über ein
> echo zurückgekommen ist was ich am PC eingegeben habe, als ich Rx und Tx
> mit einem Jumper verbunden hatte.

Ich bin aus deiner Beschreibung nicht recht schlau geworden, wo du den 
Jumper gesetzt hast. Nimm doch mal die Mega32 aus der Fassung und 
jumpere dort direkt PD0 mit PD1. Damit hast du dann die komplette 
Übertragungskette bis zum Prozessor getestet. Incl. aller Kabel die 
dazwischen liegen.

von Peter (Gast)


Lesenswert?

Kann es sein das PortD erst als out definert werden muss, oder übersehe 
ich etwas?

von Karl H. (kbuchegg)


Lesenswert?

Peter wrote:
> Kann es sein das PortD erst als out definert werden muss,


Nein, kann nicht sein (schadet aber auch nicht).
Sobald du die Uart Richtung einschaltest, übernimmt der UART-Schaltkreis 
den Pin.

von P4 (Gast)


Lesenswert?

Ich glaube ich bin den Fehler nun Dank Karl heinz Buchegger auf der 
Spur.

Ich habe ja ein STK500, wo man auf dem Board mit einem 2-Adrigen 
Steckverbindungs-Kabel von "RS232 SPARE" (für die serielle Schnittstelle 
des Target µCs) mit den beiden Pins am Zielsystem-Sockel (in meinem Fall 
PD0 und PD1) verbinden muss. (ca 10 cm langes Kabel)

Meine bisherigen Erkenntnisse:
- Rx und Tx auf RS232 Spare über Jumper kurzgeschlossen führt zu einem 
funktionierenden Echo

- Wenn ich am Sockel PD0 mit PD1 kurzschließe funktioniert die 
Durchgangsprüfung mittels Multimeter an den Anschlüssen von PD0 und PD1.

- wenn ich das 2 Adrige kabel von RS232 Spare nach PD0 und PD1 führe, 
sind laut Durchgangsprüfung auch Rx und Tx auf RS232 wie gaplant 
verbunden, also gleich wie bei Erkenntnis1, wo da direkt ein Jumper 
drauf war.
ABER: das Echo bei der Terminal Software funktioniert nicht mehr, im 
Gegensatz zur Situation in Erkenntnis1. (obwohl die Durchgangsprüfung 
immer noch funktioniert).

Kann es sein, dass sich hier die beiden Adern gegenseitig beeinflussen? 
Ich denke dabei gerade an Verseilungsarten/Verdrillung aus den HF 
Unterricht. Aber kann das bei 9600BAUD wirklich schon daran liegen?

mfg Patrick

von Stefan B. (stefan) Benutzerseite


Angehängte Dateien:

Lesenswert?

Übersprechen o.ä. wird es bei 9600 Baud nicht geben.

Das Kabel hat ja farbige Adern. Hast du geprüft, ob es richtig 
angeschlossen ist? PD0 auf RXD und PD1 auf TXD.

Das Kabel vom 2. RS232 Anschluss des STK500 zum PC sollte ein 
1:1 verschaltetes RS232-Kabel sein mit mindestens drei Adern: TX, RX 
und GND und auch kein sog. Nullmodemkabel mit RX/TX Kreuzung.

von P4 (Gast)


Lesenswert?

Hallo Stefan, genau so wie von dir genannt ist es auch verbunden. (auch 
farbrichtig).

Ich habe jetzt den µC wieder in den Sockel gegeben und hab das andere 
Ende vom RS232 SPARE Kabel (mit rausstehenden Jumperstücken, die man 
normalerweise bei Platinen an einer seite einlötet)  DIREKT an den PIN 
des ATmega32 gehalten, und siehe da:

Es hat funktioniert! :)

Irgend etwas zwischen dem 10 Poligen Stecker von Port-D und dem Sockel 
selbst verträgt sich wohl mit höheren Frequenzen oder sonst irgendetwas 
nicht...

Danke Leute für eure Geduld mit mir! Aber woran könnte das Problem 
zwischen 10pol Steckerleiste und Sockel wirklich liegen?

mfg Patrick

von STK500-Besitzer (Gast)


Lesenswert?

>Danke Leute für eure Geduld mit mir! Aber woran könnte das Problem
>zwischen 10pol Steckerleiste und Sockel wirklich liegen?

Dass du die beiden falschen Pins erwischt hast.
Für die RS232-Spare benutzt man auch nicht die 10poligen Leitungen...

von P4 (Gast)


Lesenswert?

> Für die RS232-Spare benutzt man auch nicht die 10poligen Leitungen...
Leitungen habe ich auch die 2-poligen genommen. Ich meinte nur, dass die 
auf den 10 Poligen Port-D "Buchsen-Teil" geht, wie hier im Bild: 
http://www.mikrocontroller.net/attachment/48241/stk500_rs232.png

und das müsste doch gehen...


Ich messe gerade, dass ich zwischen PD1 Pin am Sockel und PD1  auf der 
10 poligen Steckleiste (Wannenbuchse nennt sich das glaub ich) 3,2V 
Spannungsabfall habe, obwohl es eigentlich 0V Spannungsabfall sein 
sollten , da dazwischen ja nur eine Leiterbahn ist.
Bin mal gespannt was da die Ursache ist.

mfg Patrick

von Waldorf (Gast)


Lesenswert?

Hallo erstmal,

selbige Probleme hatte ich auch (mit ATmega168, 16MHz). Die 
Kommunikation sollte mit 9600 baud laufen. Eingefangen habe ich sie mit 
14400 baud. Offen ist noch, ob das das Board mit einem Quarz von 
16MHz(freeduino) oder der Baudratenrechner nicht so tun wie sie tun 
sollen.

Waldorf

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.