www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik UART Problem


Autor: Matthias S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,
Ich weiß, das Problem UART ist scho oft besprochen worden, aber ich 
komme einfach nicht weiter.

Ich habe einen ATMEGA8 auf dem STK600 mit einem externen Quarz 
(7.23728H4F - der ja eigentlich für UART Übertragungen geeignet sein 
soll) und Fusebits müssten alle passen.

Wenn ich jetzt ein einzelnes Zeichen mit dem uC übertrage, kommt auf dem 
Rechner ein anderes heraus.
Komischer Weiße passiert auch folgendes: Wenn ich zwei mal das selbe 
Zeichen übertrage kommt zweimal das selbe "falsche" Zeichen am PC an. 
Wenn ich jedoch die zwei gleichen Zeichen übertrage mit einem 
_delay_ms(100) dazwischen, kommen 2 unterschiedliche Zeichen am PC an. 
(Vielleicht hilft das...)

Hier mein Code:

#include <avr/io.h>
#include <stdlib.h>
#include <util/delay.h>

/* 
  UART-Init: 
Berechnung des Wertes für das Baudratenregister 
aus Taktrate und gewünschter Baudrate
*/
 
#ifndef F_CPU
/* In neueren Version der WinAVR/Mfile Makefile-Vorlage kann
   F_CPU im Makefile definiert werden, eine nochmalige Definition
   hier wuerde zu einer Compilerwarnung fuehren. Daher "Schutz" durch
   #ifndef/#endif 
 
   Dieser "Schutz" kann zu Debugsessions führen, wenn AVRStudio 
   verwendet wird und dort eine andere, nicht zur Hardware passende 
   Taktrate eingestellt ist: Dann wird die folgende Definition 
   nicht verwendet, sondern stattdessen der Defaultwert (8 MHz?) 
   von AVRStudio - daher Ausgabe einer Warnung falls F_CPU
   noch nicht definiert: */
#warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 4000000"
#define F_CPU 7372800UL  // Systemtakt in Hz - Definition als unsigned long beachten 
//#define F_CPU 16000000UL
                         // 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 


/* UART-Init Bsp. ATmega16 */
 
void uart_init(void)
{
  UCSRB |= (1<<TXEN);  // UART TX einschalten
  UCSRC |= (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);  // Asynchron 8N1 
 
  UBRRH = UBRR_VAL >> 8;
  UBRRL = UBRR_VAL & 0xFF;
}

int main(void) {

  DDRB &= ~(1 << PB0);  //Taster
  DDRD |= (1<<PD7);    //LED
  DDRD &= ~(1<<PD0);    //RxD
  DDRD |= (1<<PD1);    //TxD
  
  uart_init(); 

  while(1) {
        while (!(UCSRA & (1<<UDRE))) {}
        UDR = 'j';

      _delay_ms(10);

        while (!(UCSRA & (1<<UDRE))) {}
        UDR = 'j';
  }

  return 0;
}


irgendeine Idee?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Matthias S. schrieb:
> Hi,
> Ich weiß, das Problem UART ist scho oft besprochen worden, aber ich
> komme einfach nicht weiter.

Dann kennst du ja auch die Standardantworten :-)

> Ich habe einen ATMEGA8 auf dem STK600 mit einem externen Quarz
> (7.23728H4F - der ja eigentlich für UART Übertragungen geeignet sein
> soll) und Fusebits müssten alle passen.

'Müssten' ist nicht gut genug.
Hast du kontrolliert ob der Quarz verwendet wird?

Autor: Helmut -dc3yc (dc3yc)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gib uns weitere Infos: welches Zeichen wird empfangen, wenn du was 
sendest? Verwendest du RS232 oder TTL-Signale zum Rechner?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Matthias S. schrieb:

> Ich habe einen ATMEGA8 auf dem STK600 mit einem externen Quarz
> (7.23728H4F


> #define F_CPU 7372800UL  // Systemtakt in Hz - Definition als unsigned

Ziffernsturz! (bzw. da fehlt eine 2, dafür ist eine 0 zu viel)
Was steht wirklich auf deinem Quarz drauf?

Autor: H.Joachim Seifert (crazyhorse)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
7.23728H4F
#define F_CPU 7372800UL

Das sind schon mal 2%, kann schon eng werden.
Ich nehme aber mal an, dass du dich ober nur verschrieben hast.

Ohne jetzt alles durchzugehen, es müsste am Ende so aussehen (list-File)

// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 9600
UCSRA=0x00;
UCSRB=0x18;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x2F;

Ja ich weiss, so macht man es nicht :-), der Wizard aber.

Autor: Matthias S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jep ich hab mich oben verschrieben am Quarz steht: 7.3728H4F.

Der Quarz müsste schon verwendet werden, ich hab das mit dem 
Testprogramm aus der "AVR Checklist" getestet, außerdem hab ich das 
ganze schon auf dem Steckbrett mit eigener Schaltung gehabt und da wird 
der uC auch mit dem Quarz getaktet und alles funkt bis auf den UART. 
(bin aber jetzt für den UART doch aufs STK600 zurückgekehrt, bis er 
funkt)

RS232 oder TTL? Wie meinen? und wie kann ich das Überprüfen? Ich habs 
zwischendurch scho mal mit nem Oszi gemessen und da kommt eigentlich 
genau das raus was der PC anzeigt...

wenn ich ein 'h' sende kommt ',' raus, und bei 'a' kommt 'h' raus.

und bei meinem Baudraten rechner kommt bei der Frequenz des Quarzes (die 
auch im Code steht) genau 0% Fehler heraus...

mfg Matthias

Autor: Matthias S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@H.joachim Seifert: wo seh ich das List-File oder ist das einfach der 
Code vom Wizard?

Autor: Matthias S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
und noch etwas zum Thema falsche Baud Rate: Ich habs schon mit mehreren 
Einstellungen und Quarzen probier: (intern, externer 4MHZ, Clock vom 
Oszi und immer mehr oder weniger das selbe. Schließlich bin ich zu 
diesem Quarz, weil er die besten Fehlertoleranzen hat (laut 
Baud-Raten-Rechner und priv. Bauteilbestand ;)

Autor: g457 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast Du die jeweiligen Einstellungen auch überprüft? Da [1] gibts neben 
zahlreichen anteren Tipps auch ein kurzes Beispieltestprogrämmchen.

HTH

http://www.mikrocontroller.net/articles/AVR_Checkl...

Autor: H.Joachim Seifert (crazyhorse)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn du deinen Compiler anschmeisst, gibts normalerweise ein list-file.
Da kann man dann mal reinschauen.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
g457 schrieb:
> Hast Du die jeweiligen Einstellungen auch überprüft? Da [1] gibts neben
> zahlreichen anteren Tipps auch ein kurzes Beispieltestprogrämmchen.
>
> HTH
>
> http://www.mikrocontroller.net/articles/AVR_Checkl...

Ich denke das ihm das in diesem Fall ausnahmsweise nicht viel helfen 
wird. Meine Vermutung geht dahin, dass seine Taktfrequenz, aus welchem 
Grund auch immer, ein klein wenig daneben liegt, so dass man diesen 
Unterschied nicht sehen wird.

Ev. ist der Mega sogar noch auf 8Mhz intern gefust. Die Differnz zu 
7.3Mhz wird man mit freiem Auge nicht mehr sehen können. Meine 
Vorgehensweise wäre: Fuses doppelt und dreifach kontrollieren. 2tes oder 
3tes Augenpaar einen Blick drauf werfen lassen.
Gezielt den µC auf 1Mhz intern umfusen. Mittels _delay kontrollieren, ob 
das auch wirklich so ist. Dann auf externen QUarz fusen, wieder 
kontrollieren. Gegentest machen: Quarz rausziehen

Autor: Matthias S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@H.joachim Seifert
Ich benutz AVRStudio4 und irgendwie find ich das List file nicht.

Autor: Matthias S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Fusebits (so wies im AVR Studio drin steht):

SUT_CKSEL: Ext. Crystal/Resonator Medium Freq.; Start-up time: 1K CK + 
0ms
HIGH: 0xD9
LOW: 0xEC

Autor: g457 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn man länger zusieht (mit der Stoppuhr in der Hand), dann sollte man 
7.4MHz und 8MHz schon auseinandernhalten können :-)

Aber ich hab noch eine mögliche Fehlerquelle gefunden:

> #ifndef F_CPU
[..]
> #define F_CPU 7372800UL
[..]
> #endif

Ist das F_CPU möglicheweise schon (mit einem falschen Wert) definiert?

Autor: Julian O. (juliano)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist der Quarz zufällig gesockelt? Ich nehme den Quarz ganz gerne raus um 
zu checken ob er verwendet wird. Läuft der uC ohne Quarz nicht mehr los 
(bzw. lassen sich die Fuses z.B. nicht mehr auslesen) wird der Quarz 
verwendet und die Fuse-Einstellung stimmt

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
g457 schrieb:

> Ist das F_CPU möglicheweise schon (mit einem falschen Wert) definiert?


Ja, das ist gut. Könnte sein.
Auf die mögliche Fehlerquelle wird ja auch im Kommentar in diesem Block 
hingewiesen.

-> Beim Compilileren müsste man die Warnung sehen!
Sieht man sie nicht, kommt dieser #define gar nicht zum Zug.

Es gibt auch Leute, die mit einer derartigen #ifdef Absicherung extrem 
unglücklich sind. Eben genau aus diesem Grund.

Autor: Matthias S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@g457: Es war wirklich die definition von F_CPU falsch. Aber wo wird die 
noch gesetzt? In den Project Options habe ich nichts eingetragen und 
sonst auch nicht...

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Matthias S. schrieb:
> HIGH: 0xD9
> LOW: 0xEC

Das ist für einen Quarz im Bereich von 0,9 bis 3 MHz (CKSEL3..1 = 110, 
CKOPT = 1) gültig, also nicht für den eingesetzten.  Es dürfte 
wahrscheinlich nicht der eigentliche Grund sein (schwingt meistens 
trotzdem auf der Sollfrequenz), aber unsauber ist es schon.

Autor: Micha B. (mbcontrol)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Matthias S. schrieb:
> Fusebits (so wies im AVR Studio drin steht):
>
> SUT_CKSEL: Ext. Crystal/Resonator Medium Freq.; Start-up time: 1K CK +
> 0ms
> HIGH: 0xD9
> LOW: 0xEC

Probier doch mal ...
SUT_CKSEL: Ext. Crystal/Resonator High Freq; Start-up time: 16K CK + 
64ms

Gruß MB

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Matthias S. schrieb:
> @g457: Es war wirklich die definition von F_CPU falsch. Aber wo wird die
> noch gesetzt? In den Project Options habe ich nichts eingetragen und
> sonst auch nicht...

Dann musst du in Zukunft deinen Compiler-Output besser studieren.

#include <util/delay.h>


delay.h schreibt (genau wie dein Code) eine Warnung hin, dass F_CPU 
nicht definiert wurde und definiert sich selber eines.

Die Definition von F_CPU ist ein ständiges Ärgernis.
Du solltest dir angewöhnen, diese Einstellung ausschliesslich und nur 
über die Project Options zu machen. Nur dort kannst du gewährleisten, 
dass die immer und überall übereinstimmt!

Und am besten wäre ganz am Anfang im Hauptfile
#ifndef F_CPU
#error "F_CPU: Bitte in den Project Options die Taktfrequenz eintragen"
#endif

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

dann hätte dieser Spuk schnell ein Ende.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.