Hallo!
Ich habe folgendes Problem:
Ich möchte mit meinem tiny2313 die UART-Schnittstelle (nur TXD) nutzen.
Der µc läuft dabei mit 8 MHz (CKSEL=1110 SUT=01), die Fuses sind korrekt
gesetzt.
Die Baudrate soll 9600 betragen (die kann ich ja frei wählen, richtig?).
Aber egal, was ich versuche, es kommt nur Müll am Terminal an.
Diese defines benutze ich:
1
#ifndef F_CPU
2
#define F_CPU 8000000
3
#endif
4
#ifndef UART_BAUD_RATE
5
#define UART_BAUD_RATE 9600
6
#endif
Mit der folgenden Formel soll die Baudrate gesetzt werden:
1
UBRRL=(F_CPU/(16*baud))-1;
Die ist doch richtig, oder?
Mit einer direkten Zuweisung, dessen Wert ich dem Datenblatt entnommen
habe, geht es auch nicht:
1
UBRRL=51;
Was ist an der ganzen Geschichte falsch?? Ich habe alle möglichen Werte
durchprobiert, aber immer kommt nur Buchstabensalat an, und dabei hab'
ich gar keinen Hunger...
Im Ernst, es wäre klasse, wenn jemand einen Tipp hätte. Ich bin am
verzweifeln...
MfG Matze
Hab jetzt nicht im Kopf, was die Fuses genau bewirken, aber zuerst mal
sollte es auf jedem Fall ein externer Oszillator sein (ist 1110 glaube
ich auch). Verkabelung ist nehme ich an auch richtig!? Ansonsten könnte
vielleicht UBRRH irgendeinen komischen wert haben, setzt das mal auf 0
und überprüfe nochnmal in der Programmierung und im Terminalprogramm die
Stoppbiteinstellungen.
@ _matze (Gast)
>Ich möchte mit meinem tiny2313 die UART-Schnittstelle (nur TXD) nutzen.>Der µc läuft dabei mit 8 MHz (CKSEL=1110 SUT=01), die Fuses sind korrekt>gesetzt.
Naja, GANZ korrekt wäre CKSEL=1111 und SUT=01, denn du hast sicherlichen
einen 8 MHz Quarz dran und keinen Keramikresonator, oder? Sollte aber
dennoch nicht das Problem sein.
>Die Baudrate soll 9600 betragen (die kann ich ja frei wählen, richtig?).>Aber egal, was ich versuche, es kommt nur Müll am Terminal an.>Diese defines benutze ich:>#ifndef F_CPU> #define F_CPU 8000000>#endif
Besser
#define F_CPU 8000000L
Das L sagt dem Compiler, dass mit 32 Bit gerechnet werden soll, sonst
rechnet er nur mit 16 Bit und es kommt Müll raus.
>#ifndef UART_BAUD_RATE> #define UART_BAUD_RATE 9600>#endif>Mit der folgenden Formel soll die Baudrate gesetzt werden:>UBRRL = (F_CPU/(16 * baud)) - 1;>Die ist doch richtig, oder?
Naja, wenn du deine defines benutzen willst dann eher
UBRRL = (F_CPU/(16 * UART_BAUD_RATE)) - 1;
>Mit einer direkten Zuweisung, dessen Wert ich dem Datenblatt entnommen>habe, geht es auch nicht:>UBRRL=51;
Das ist OK.
>Was ist an der ganzen Geschichte falsch?? Ich habe alle möglichen Werte>durchprobiert, aber immer kommt nur Buchstabensalat an, und dabei hab'>ich gar keinen Hunger...
Mahlzeit! ;-)
Bist du sicher dass die Fuses richtig programmiert sind? Klemm man den
Quarz ab, dann sollte gar nichts ankommen. Wenn doch was ankommt dann
ist noch der interne RC-Oszillator mit 8 MHz aktiv.
MfG
Falk
Erstmal vielen Dank für die zügige Hilfe!
Der Thread von Timo hat mich leider nicht weitergebracht (hatte ich
schon vorher durchgelesen). Auch eure Ratschläge haben leider nicht
geholfen.
Folgendes habe ich gemacht:
CKSEL=1111 SUT=01
^
#define F_CPU 8000000UL
^^
#define UART_BAUD_RATE 9600UL //obwohl ja hier nicht notwendig
^^
UBRRL=51; //fest, da ihr mir die Richtigkeit bestätigt habt
^^
Quarz abklemmen geht leider nicht, ich befinde mich auf einer festen
Platine, da kann ich nicht mal eben was ändern. Ich bin aber sicher,
dass die Fuses korrekt sind. Das AVR Studio bestätigt mir das (Fuses
einlesen), außerdem brenne ich fast täglich andere ICs mit den gleichen
Fuses. Da klappt's ja auch immer.
Ergänzung:
----------
(Das hätte ich wohl direkt erwähnen sollen, auch wenn ich der Ansicht
bin, dass das keinen Unterschied machen sollte.)
Der µC befindet sich auf einer Platine in einem Scanner, nicht auf dem
Testboard (STK500). Der Pin D0 ist nicht verbunden und somit frei für
die USART-Nutzung. Ich habe mir von einem Arbeitskollegen ein Kabel an
den Pin D0 löten lassen (untere Seite vom Sockel natürlich). Dieses
Kabel steckt auf dem STK500 auf dem TXD-Pin.
An dieser Vorgehensweise ist hoffentlich nichts auszusetzen, oder? Dass
überhaupt Daten ankommen, ist für mich das Indiz dafür, dass die
Kommunikation grundsätzlich klappt. Oder gibt es da noch etwas zu
beachten?
Übrigens, auf der Platine steckt ein 20 Mhz Quarz (Aufschrift AQ20.000).
Dürfte doch aber irrelevant sein, da der tatsächliche Takt zählt,
richtig?
Gruß Matze
> Übrigens, auf der Platine steckt ein 20 Mhz Quarz (Aufschrift AQ20.000).> Dürfte doch aber irrelevant sein, da der tatsächliche Takt zählt,> richtig?
Oh weh. Was meinst Du, wer denn den "tatsächlichen Takt" woraus erzeugt?
Entschuldige, ich bin neu in der Firma und habe von Elektrotechnik keine
Ahnung. Ich hab nur immer gelesen, dass die Fuses den Takt bestimmen,
und das dann so hingenommen.
Du meinst also, der µC läuft mit 20MHz, obwohl ich per Fuses 8MHz
einstelle??
Du stellst mit den Fuses/F_CPU keine 8 MHz ein.
Du gibst im Programm mit F_CPU lediglich bekannt, dass deine Taktquelle
mit 8 MHz arbeiten tut. Beispielsweise um die UART Einstellungen daraus
abzuleiten oder um Warteschleifen abzustimmen.
Wenn die Taktquelle mit einem anderen Takt läuft (weil ein anderer Quarz
verbaut ist), ist es Zufall, wenn das Programm richtig arbeitet.
Das F_CPU lediglich ein define ist und keine Auswirkungen hat, ist mir
bekannt. Die Sache mit den Fuses verstehe ich allerdings noch nicht so
ganz.
Bedeutet das, die Fuses sind letztlich egal, wenn ein externer Quarz zum
Einsatz kommt? Wozu setzt man dann verschiedene Frequenzen? Schließlich
sagt das AVR Studio, dass ich 8 MHz setze.
Oder anders gefragt: Reicht es bei externem Quarz, irgendeine Frequenz
einzustellen, da diese letztlich sowieso vom Quarz bestimmt wird? Kann
ich mir ehrlich gesagt kaum vorstellen, hört sich unlogisch an.
Übrigens vielen Dank für eure Geduld! Ich stelle bestimmt jede Menge
dumme Fragen (doch, es gibt dumme Fragen!), aber irgendwie muss ich es
ja lernen...
Wie sieht es mit dem STK500 aus? Da gibt es ja Jumper (OSCSEL, XTAL1,
...), die die Frequenz und den verwendeten Quarz (intern/extern)
bestimmen. Kann sich diese Einstellung auswirken, obwohl der µC gar
nicht auf dem Board sitzt? Schließlich will ich das Board nur wegen der
RS232-Schnittstelle missbrauchen.
Gruß Matze
_matze wrote:
> Wozu setzt man dann verschiedene Frequenzen? Schließlich> sagt das AVR Studio, dass ich 8 MHz setze.
Das AVRStudio sagt sicher nicht, dass Du genau 8 MHz hast, sondern
dass Du einen externen Quarz mit einer Frequenz >= 8 MHz anschließt! Die
Angaben für die Fuses sind alle von...bis und sind erforderlich, da der
Oszillator auf den Frequenzbereich abgestimmt werden muss.
> Oder anders gefragt: Reicht es bei externem Quarz, irgendeine Frequenz> einzustellen, da diese letztlich sowieso vom Quarz bestimmt wird? Kann> ich mir ehrlich gesagt kaum vorstellen, hört sich unlogisch an.
Nein, wie oben schon angedeutet: Die Fuses konfigurieren den im µC
eingebauten Oszillator. Für höhere Frequenzen muss dieser anders
angepasst werden als für niedrige Frequenzen. Für einen 16 MHz-Quarz
sind die Einstellungen anders als für einen 2 MHz-RC-Oszillator.
> Wie sieht es mit dem STK500 aus? Da gibt es ja Jumper (OSCSEL, XTAL1,> ...), die die Frequenz und den verwendeten Quarz (intern/extern)> bestimmen. Kann sich diese Einstellung auswirken, obwohl der µC gar> nicht auf dem Board sitzt?
Wenn kein µC auf dem Board ist, wirkt sich da gar nichts aus. Und die
Auswahl der Taktquelle geschieht eben über die Fuses. Wenn die Fuses auf
"interner RC-Oszillator" stehen, ist es dem µC völlig egal, ob da extern
ein Quarz dranhängt oder nicht.
> Bedeutet das, die Fuses sind letztlich egal, wenn ein externer Quarz zum> Einsatz kommt?
Nein.
DIE eine Fuses-Einstellung für "externer Quarz" gibt es nicht. Die
Einstellungen unterscheiden sich untereinander jenachdem ob es ein
langsamer oder ein schneller Quarz ist. Der µC liefert den Saft, mit dem
der Quarz zum Schwingen gebracht wird und der µC muss die Schwingungen
als Takt entgegen nehmen. Das kannst du mit dem "Feintuning der Fuses"
anpassen. So gesehen ist die Einstellung natürlich nicht egal.
> Wozu setzt man dann verschiedene Frequenzen?
Um den Wert für F_CPU zu generieren und damit im Programm zu wurschteln.
Und vielleicht (!) auch, um automatisch die eine passende
Fuses-Einstellung bei verschienden Möglichkeiten zu setzen. Weiss ich
jetzt nicht ohne Nachschauen in AVRStudio.
> Schließlich sagt das AVR Studio, dass ich 8 MHz setze.
Sicher, oder ist das nur die Defaulteinstellung in der Auswahlbox?
Ok, das mit den Fuses habe ich nun (endlich!) verstanden! Danke für die
ausführlichen Erklärungen und die unendliche Geduld, die ich allerdings
noch weiter strapazieren muss...
Könnt ihr mir denn sagen, was dann noch falsch sein soll? Ich denke, die
Berechnung der Baudrate ist richtig, und auch sonst sollte alles
stimmen, oder?
1
#ifndef F_CPU
2
#define F_CPU 20000000UL
3
#endif
4
#ifndef UART_BAUD_RATE
5
#define UART_BAUD_RATE 9600UL
6
#endif
7
8
/***************/
9
intmain(void){
10
/***************/
11
12
USART_init(UART_BAUD_RATE);
13
14
for(;;){
15
USART_transmit('A');
16
_delay_ms(10);
17
_delay_ms(10);
18
USART_transmit('B');
19
_delay_ms(10);
20
_delay_ms(10);
21
}
22
}
23
24
/***************/
25
staticvoidUSART_init(unsignedintbaud){//nochmal genau ansehen und schöner formulieren!
26
/***************/
27
UCSRA=0x00;
28
29
UBRRL=(F_CPU/(16*baud))-1;
30
UBRRH=0x00;
31
32
UCSRB=(1<<RXEN)|(1<<TXEN);
33
}
34
35
/***************/
36
voidUSART_transmit(unsignedcharcData){//sendet ein Zeichen ans Terminal
37
/***************/
38
while(!(UCSRA&(1<<UDRE))){
39
;//warten, bis der transmit buffer leer ist, so dass wieder übertragen werden kann
Bitte nicht auf fehlende Prototypen etc. achten, der Code war natürlich
wesentlich größer und wurde von mir (mehr oder weniger) fachgerecht
beschnitten! Es fehlt aber nichts, was für die Problematik relevant sein
könnte.
Hast Du im AVRStudio auch die korrekte Taktfrequenz für den µC
eingestellt? Das
1
#define F_CPU 20000000UL
hat nur dann einen Effekt, wenn es nicht durch eine Einstellung im
Makefile (bzw. in den Configuration Options im AVRStudio)
"überschrieben" wird. Und wenn da ein falscher Wert angegeben ist, dann
funktioniert es nunmal nicht.
_matze wrote:
> DDRD ist irrelevant für UART, oder? Meines Wissens wirkt sich die> Datenrichtung ja nur aus, wenn die Pins zu normalen I/O-Zwecken genutzt> werden.
Richtig, im Falle des UART werden die DDRD-Einstellungen ignoriert.
Johannes, bist du vielleicht ein Wesen aus der Zukunft? Ein Gott? Mehr
als das? Jedenfalls HERZLICHEN DANK, dein Vorschlag war die Lösung!
Auch wenn ich es nicht verstehe. Laut deiner Aussage wird der selbst
definierte Wert F_CPU von der Einstellung im AVR-Studio überschrieben
(wenn vorhanden). So habe ich es zumindest verstanden.
Das scheint wohl nicht ganz richtig zu sein, denn mit einem Eintrag in
den Options läuft es plötzlich! Ich kannte diese Einstellung nicht,
deswegen habe ich da auch nicht nach der Lösung gesucht. Und bislang
habe ich immer mit internem Takt gearbeitet, da trat das Problem nicht
auf.
So kann's gehen, da sucht man Stunden vergebens nach der Lösung, und
schließlich geht's nur um eine Kleinigkeit (mit fatalen Folgen).
Jedenfalls nochmal Dankeschön an Johannes und alle anderen Meister der
Geduld!
Gruß Matze
@ _matze (Gast)
>Johannes, bist du vielleicht ein Wesen aus der Zukunft? Ein Gott? Mehr
<Blasphemie>
Neee, er hat einfach nur elementare Grundlagen drauf
</Blasphemie>
>als das? Jedenfalls HERZLICHEN DANK, dein Vorschlag war die Lösung!>Auch wenn ich es nicht verstehe. Laut deiner Aussage wird der selbst>definierte Wert F_CPU von der Einstellung im AVR-Studio überschrieben>(wenn vorhanden). So habe ich es zumindest verstanden.
Mit
#define F_CPU 20000000UL
sagt du AVR Studio, dass ein 20 MHz Quarz angeschlossen ist. Denn woher
soll die Software (AVR-Studio) wissen, wie die Hardware aufgbaut ist?
Genauso wie du mit den Fuses der Hardware mitteilen musst, wie sie
arbeiten soll. Du kann den interen Oszillator verwenden, der hat ein
paar feste Frequenzen (8/4/1 MHz). Oder einen exteren Quarz. Dort wird
die Freqeunz aber durch den Quarz festgelegt, nicht durch die Fuses. Die
sagen nur, "Nimm den Quarz".
MfG
Falk
Richtig, aber leider wird mein define F_CPU überschrieben, auch wenn in
den Configuration Options GAR KEIN Wert steht. Allein mit dem define
funktioniert es leider nicht. Hab jetzt Feierabend, muss mir morgen aber
mal das Makefile, das AVR Studio erzeugt, ansehen. Da sollte der Wert ja
letztlich stehen.
Gruß Matze