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:
1
#include<avr/io.h>
2
#include<stdlib.h>
3
#include<util/delay.h>
4
5
/*
6
UART-Init:
7
Berechnung des Wertes für das Baudratenregister
8
aus Taktrate und gewünschter Baudrate
9
*/
10
11
#ifndef F_CPU
12
/* In neueren Version der WinAVR/Mfile Makefile-Vorlage kann
13
F_CPU im Makefile definiert werden, eine nochmalige Definition
14
hier wuerde zu einer Compilerwarnung fuehren. Daher "Schutz" durch
15
#ifndef/#endif
16
17
Dieser "Schutz" kann zu Debugsessions führen, wenn AVRStudio
18
verwendet wird und dort eine andere, nicht zur Hardware passende
19
Taktrate eingestellt ist: Dann wird die folgende Definition
20
nicht verwendet, sondern stattdessen der Defaultwert (8 MHz?)
21
von AVRStudio - daher Ausgabe einer Warnung falls F_CPU
22
noch nicht definiert: */
23
#warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 4000000"
24
#define F_CPU 7372800UL // Systemtakt in Hz - Definition als unsigned long beachten
25
//#define F_CPU 16000000UL
26
// Ohne ergeben sich unten Fehler in der Berechnung
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?
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?
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.
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
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 ;)
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_Checkliste#UART.2FUSART
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
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?
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
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.
@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...
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.
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
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
1
#ifndef F_CPU
2
#error "F_CPU: Bitte in den Project Options die Taktfrequenz eintragen"