Ich zweifele gerade an meiner Intelligenz. Ich schreibe gerade mein
erstes C-Programm für einen Atmega8 (komme aus der Assembler-Ecke) und
möchte über USART/Midi ein Instrument ansteuern. Hier die relevanten
Code-Ausschnitte:
1
#ifndef F_CPU
2
#define F_CPU 4000000UL
3
#endif
4
5
#define BAUD 31250
6
#define UBRR_VAL ((F_CPU+BAUD+8)/(BAUD*16)-1)
7
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))
8
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD)
9
10
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
11
#error Baudratefehler!
12
#endif
13
14
voiduart_init(){
15
UCSRB|=(1<<TXEN);
16
UCSRC=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
17
UBRRH=UBRR_VAL>>8;
18
UBRRL=UBRR_VAL&0xFF;
19
}
20
21
22
23
intmain(void)
24
{
25
lcd_init();
26
uart_init();
27
28
lcd_string("TEST: ");
29
30
DDRB=0x01;//TEST
31
PORTB^=0x01;//TEST
32
33
while(!(UCSRA&(1<<UDRE)))
34
{
35
PORTB^=0x01;//TEST
36
}
37
UDR=145;
38
while(!(UCSRA&(1<<UDRE)));
39
{
40
PORTB^=0x01;//TEST
41
}
42
UDR=39;
43
while(!(UCSRA&(1<<UDRE)));
44
{
45
46
}
47
UDR=100;
48
49
while(1)
50
{}
51
return0;
52
}
Irgendwie spuckt nun TX nur Dauer-High aus. Mein TEST-TOGGLE sorgt für
einen kurzen HIGH-Puls(ca. 2,5us). Das LCD läuft einwandfrei (Code
fehlt).
Helft mir doch bitte auf die Sprünge. Das Datenblatt spuckt mir genau
den selben Code aus und ich stehe voll auf dem Schlauch.
Danke!!!
spess53 schrieb:>>Vielleicht einfach mal PD1 (Txd) auf Ausgang setzen.>> Das Pin wird automatisch Ausgang, wenn TXEN gesetzt wird.
Naja auf jeden Fall, hat ein manuelles setzen von PD1 in DDRD nichts
gebracht.
Der Quarz schwingt sauber mit einer Amplitude von 800mVpp. Das LCD tut
fleißig seinen Dienst. Die Messung des Signals erfolgt direkt an PD1.
Ich weiß nicht, was da an der Schaltung falsch sein sollte.
Timmo H. schrieb:> Ha:#define UBRR_VAL ((F_CPU+BAUD+8)/(BAUD*16)-1)mach da mal das draus:#define
UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)
Genial gesehen, Danke, bringt aber nichts. Schade :-(
Ja hab ich mir gedacht, aber ein Fehler ists dennoch.
Bist du sicher, dass du uns keinen Code vorenthalten hast, wo du ggf.
doch noch den Port anders befingerst?
Timmo H. schrieb:> Ja hab ich mir gedacht, aber ein Fehler ists dennoch.
Definitiv.
Ich habe mal das Sende-Zeug in eine Endlosschleife gepackt:
1
while(1){
2
while(!(UCSRA&(1<<UDRE)))
3
{
4
PORTB^=0x01;
5
}
6
UDR=145;
7
while(!(UCSRA&(1<<UDRE)))
8
{
9
PORTB^=0x01;
10
}
11
UDR=39;
12
13
while(!(UCSRA&(1<<UDRE))){}
14
UDR=100;
15
}
Auf dem Oszi ist rein gar nichts mehr zu sehen. Der PB0-Testpin wird
auch nicht mehr getoggelt, seit UBRR_VAL korrigiert wurde. Anscheinend
werden die while-Schleifen gar nicht durchlaufen.
Timmo H. schrieb:> Bist du sicher, dass du uns keinen Code vorenthalten hast, wo du ggf.> doch noch den Port anders befingerst?
Anbei alle Quelldateien. Möchte das jetzt nicht hier als Fließtext
reinpacken. Wenn gewünscht, mache ich das natürlich.
Der Code, insbesondere main(), sieht gerade etwas durcheinander aus,
wegen dem vielen Probieren.
So etwas mache ich äußerst ungern. Ist im Projekt ein abweichender
F_CPU-Wert eingetragen, kommen diese Zeilen gar nicht zum Tragen. Es
gibt noch nichtsmals eine Fehlermeldung, dass hier ein abweichender Wert
steht.
Entweder nur:
Daniel schrieb:> void uart_init(){> UCSRB |= (1<<TXEN);> UCSRC = (1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0);> UBRRH = UBRR_VAL >> 8;> UBRRL = UBRR_VAL & 0xFF;> }
Vertausch mal versuchsweise die Reihenfolge:
void uart_init(){
UBRRH = UBRR_VAL >> 8;
UBRRL = UBRR_VAL & 0xFF;
UCSRB |= (1<<TXEN);
UCSRC = (1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0);
}
Im Datenblatt ist es so beschrieben. Vielleicht mag der UART nicht, die
Baudrate-Register zu ändern, wenn er schon enabled ist.
Gruß Dietrich
Ich habe einen neuen ATmega8 eingesetzt, das half nichts.
Aber irgendwie läuft es jetzt nachdem ich alle Ratschläge umgesetzt
habe. Jetzt wollt ihr bestimmt noch wissen, wessen Idee das Teil zum
Laufen gebracht hat?
Dietrich L. schrieb:> Vertausch mal versuchsweise die Reihenfolge:>> void uart_init(){> UBRRH = UBRR_VAL >> 8;> UBRRL = UBRR_VAL & 0xFF;> UCSRB |= (1<<TXEN);> UCSRC = (1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0);> }
Der Gewinner ist Dietrich. Also euch allen ein ganz dickes Dankeschön.
Timmo H. schrieb:> Hast du auch UDR vorher mal ausgelesen?
Jo, und auf dem LCD ausgegeben. Ich weiß aber nicht, was das auf deutsch
heißt^^ Cheng-Peng
Besonders hart finde ich ja, dass ich diesen Quäl-Code aus dem Tutorial
habe. Da sollte man vielleicht mal die richtige Version einstellen. Soll
ich das mal versuchen?
Frank M. schrieb:> Daniel schrieb:>> Jetzt wollt ihr bestimmt noch wissen, wessen Idee das Teil zum>> Laufen gebracht hat?>> Na klar :-)
Sorry, Frank, du warst es leider nicht (obwohl ich dich zunächst
favorisiert habe). Ich werde deinen Ratschalg aber in Zukunft
beherzigen, klingt nämlich recht logisch.
Daniel schrieb:> Besonders hart finde ich ja, dass ich diesen Quäl-Code aus dem Tutorial> habe. Da sollte man vielleicht mal die richtige Version einstellen. Soll> ich das mal versuchen?
Ja.
Frank M. schrieb:> Daniel schrieb:>> Besonders hart finde ich ja, dass ich diesen Quäl-Code aus dem Tutorial>> habe. Da sollte man vielleicht mal die richtige Version einstellen. Soll>> ich das mal versuchen?>> Ja.
Das ist ja leichter, als ich dachte. Man benötigt ja nichteinmal einen
Account. Hab's angepasst mit dem Verweis auf diesen Thread.
Daniel schrieb:> Sorry, Frank, du warst es leider nicht (obwohl ich dich zunächst> favorisiert habe).
Mein Favorit war auch Dietrich. Ist schon interessant, was man alles so
bei einer simplen UART-Initialisierung falsch machen kann. Auf die
Reihenfolge wäre ich nie gekommen, da benutze ich von Projekt zu Projekt
nur Copy-and-Paste. Und glücklicherweise kommt da die TXEN-Zeile immer
als letztes :-)
> Ich werde deinen Ratschalg aber in Zukunft beherzigen, klingt nämlich> recht logisch.
:-)
Hi
>Das ist ja leichter, als ich dachte. Man benötigt ja nichteinmal einen>Account. Hab's angepasst mit dem Verweis auf diesen Thread.
Vielleicht etwas voreilig. Das URSEL-Bit haben nicht alle AVRs. Bei
denen ist die Reihenfolge egal.
MfG Spess
spess53 schrieb:> Vielleicht etwas voreilig. Das URSEL-Bit haben nicht alle AVRs. Bei> denen ist die Reihenfolge egal.
Das URSEL-Bit stand aber auch schon vorher an dieser Stelle. Das könnte
man natürlich noch mit
1
#ifdef URSEL
2
...
3
#else
4
...
5
#endif
schöner machen.
@Daniel:
Mir ist aufgefallen, dass die offenbar falsche TXEN-Reihenfolge mehrfach
im Artikel vorkommt. Du hast aber nur eine korrigiert ;-)
Frank M. schrieb:> @Daniel:>> Mir ist aufgefallen, dass die offenbar falsche TXEN-Reihenfolge mehrfach> im Artikel vorkommt. Du hast aber nur eine korrigiert ;-)
Stimmt, das hatte ich nicht gesehen, weil ich nur den Empfangen-Teil
bearbeitet habe. Wurde inzwischen aber von einem anderen User angepasst.
Sorry.
spess53 schrieb:> Vielleicht etwas voreilig. Das URSEL-Bit haben nicht alle AVRs. Bei> denen ist die Reihenfolge egal.
Was ist daran voreilig?
Für den Fall, dass der verwendetet AVR kein URSEL hat, schadet die
Änderung nicht.
Für den Fall, dass der verwendete AVR ein URSEL hat, spart die Änderung
richtig Zeit und Nerven. Siehe mein Fall. So nen rießen Spaß hat's jetzt
auch nicht gemacht.
Hi
>Für den Fall, dass der verwendete AVR ein URSEL hat, spart die Änderung>richtig Zeit und Nerven. Siehe mein Fall. So nen rießen Spaß hat's jetzt>auch nicht gemacht.
Ein Blick ins Dtenblatt hätte gereicht. Dort steht das laut und deutlich
drin.
MfG Spess
spess53 schrieb:>>Für den Fall, dass der verwendete AVR ein URSEL hat, spart die Änderung>>richtig Zeit und Nerven. Siehe mein Fall. So nen rießen Spaß hat's jetzt>>auch nicht gemacht.>> Ein Blick ins Dtenblatt hätte gereicht. Dort steht das laut und deutlich> drin.
Was genau soll denn da stehen?
Ich sehe jedenfalls so auf Anhieb nicht, was diese Reihenfolge vorgeben
soll. Insbesondere nichts in Zusammenhang mit URSEL.
spess53 schrieb:> Ein Blick ins Dtenblatt hätte gereicht. Dort steht das laut und deutlich> drin.
Mit einem solchen Argument könnt ihr euer Tutorial komplett einstampfen.
Außerdem habe ich einen Blick ins Datenblatt gewagt. Ich bin ja nicht
unbedingt blöd, aber ich habe meinen Fehler dadurch nicht bemerkt.
Du willst jetzt nicht wirklich meckern, weil ich das Tutorial
anfängerfreundlicher gemacht habe, ohne ein Zeichen zu löschen oder
hinzuzufügen?
HI
>Was genau soll denn da stehen?>Ich sehe jedenfalls so auf Anhieb nicht, was diese Reihenfolge vorgeben>soll. Insbesondere nichts in Zusammenhang mit URSEL.
Was ist mit 'Accessing UBRRH/UCSRC Registers' im Kapitel UART?
MfG Spess
spess53 schrieb:> Was ist mit 'Accessing UBRRH/UCSRC Registers' im Kapitel UART?
Ja, was ist damit? Warum soll sich daraus irgendein Zwang für eine
bestimmte Reihenfolge ergeben?
spess53 schrieb:> HI>>>Was genau soll denn da stehen?>>Ich sehe jedenfalls so auf Anhieb nicht, was diese Reihenfolge vorgeben>>soll. Insbesondere nichts in Zusammenhang mit URSEL.>> Was ist mit 'Accessing UBRRH/UCSRC Registers' im Kapitel UART?
Um ehrlich zu sein, ich versteh jetzt auch nicht worauf du hinaus
willst. Beim SChreiben sollte doch eigentlich mit dem URSEL Bit alles
geregelt sein.
(Obwohl ich mich auch an dieses Problem bei meinen ersten UART
Funktionen erinnern kann. Aber dann wird halt der Code immer
weiterkopiert, wenn er mal läuft, sodass ich dem nie weiter nachgegangen
bin)