Hallo Leute,
ich versuch mit WinAVR ein Programm zu schreiben,
das mir über den UART meines ATmega32 ein paar Zeichen
zum PC sendet.
Dafür hab ich eine Funktion UART_init geschrieben die
mir den UART initialisieren soll.
Compilieren funktioniert ohne Probleme, beim debuggen
spring er allerdings nicht in UART_init. Kann es sein
das der Compiler das Unterprogramm wegoptimiert??
WAs kann ich dagegen machen? Bei Gelegenheit vielleicht
noch ein Tip ob die Übertragung auf diese Weise
funktionieren könnte!
Danke, Stefan
Hab das Programm mal drangehängt.
#include <avr/io.h>
void UART_init(void)
{
// Baudrate einstellen
sbi(UBRRH,7); // Zugriff auf UBRRH ermöglichen
UBRRH = (UBRRH | 0x00);
UBRRL = 0x17; // 9600 bps
// Frame Format einstellen
cbi(UCSRC,7); // Zugriff auf UCSRC
cbi(UCSRC,6); // Asynchrone Übertragung
UCSRC = (UCSRC | 0x10); // Even Parity
cbi(UCSRC,3); // 1 Stop Bit
UCSRC = (UCSRC | 0x03); // 8 Datenbit
cbi(UCSRB,2);
// RxD, TxD freischalten
sbi(UCSRB,3); // TxD Pin freischalten
sbi(UCSRB,4); // RxD Pin freischalten
}
void send_fkt(char byte)
{
while ( !(UCSRA & (1<<UDRE)));
UDR = byte;
}
int main(void)
{
UART_init;
while(1)
{
send_fkt("O"); // Zeichen übertragen
send_fkt("k");
send_fkt(" ");
}
return 0;
}
> Kann es sein das der Compiler das Unterprogramm wegoptimiert?
Sowas könnte bei -O3 Optimierung in der Tat erfolgen, bei allen
geringeren Optimierungen dagegen nicht.
Aber:
> UART_init;
Dafür hast Du keine Warnung bekommen (`statement has no effect' oder
sowas)? Das würde mich wundern...
Du solltest Dir mal ansehen, wie man in C Funktionen aufruft. ;-) Du
hast die Adresse der Funktion referenziert, sie aber nicht aufgerufen.
Da Du die Adresse hernach nicht benutzt, hat der Compiler das
natürlich wirklich wegoptimiert.
Hinweis: Falls Du die Optimierung ganz ausschaltest (-O0), dann
bekommst Du eine Reihe von Warnungen nicht mehr, die erst im
Optimiererlauf (Programmflußanalyse) festgestellt werden können.
`statement has no effect' könnte dazu gehören.
Das mit dem Programmaufruf hatte ich schon
gefunden, war wirklich ein blöder Fehler! :-)
Allerdings ist mir das mit der Optimierung
des Compilers schon passiert, deswegen würd
mich mal interessieren wo sich das einstellen
läßt. Denk mal im makefile aber ich konnte
nichts entsprechendes finden.
Noch ne Frage zur Adressierung der UART Register.
Ich benutze eine ATmega32, soviel ich verstanden
hab liegen die Register UCSRC & UBRRH auf der
selben Adresse. Nach dem Datenblatt lassen sich
die beiden Register durch das setzen des MSB
auswählen.
Hab das folgendermaßen versucht:
cbi(UCSRC,7);
UCSCR = 0x...
sbi(UBRRH,7);
UBRRH = 0x...
aber beim debuggen bleibt das ohne Erfolg.
Wie kann ich die Register adressieren?
Ciao Stefan
> Allerdings ist mir das mit der Optimierung des Compilers schon> passiert, ...
Was denn?
> deswegen würd mich mal interessieren wo sich das einstellen> läßt. Denk mal im makefile aber ich konnte nichts entsprechendes> finden.
So schwer zu finden? Im Standard-WinAVR-Template gibt's extra
einen Makro OPT dafür, einschließlich Kommentar.
Oder <werbung>
http://www.sax.de/~joerg/mfile/
</werbung>
> Hab das folgendermaßen versucht:> sbi(UBRRH,7);> UBRRH = 0x...
Nun, das kann nicht gehen. Überleg doch mal, Dein Schreibzugriff auf
UBRRH würde doch das zuvor geschriebene Bit 7 wieder überschreiben.
Ganz davon abgesehen: Du hast die Werte von Bit 7 vertauscht. Bit 7
low selektiert UBRRH, Bit 7 high selektiert UCSRC.
Aber die Sache ist viel einfacher, als es sich auf den ersten Blick
liest: die zulässigen Vorteilerwerte in UBRRH sind allesamt so klein,
daß beim Schreiben von UBRRH Bit 7 sowieso immer low ist. Wenn Du
beim Beschreiben dieser Adresse dagegen UCSRC meinst, dann mußt Du
stets auch »| _BV(URSEL)« mit reinnehmen. Lesen ist etwas
komplizierter, siehe Datenblatt. Allerdings solltest Du normalerweise
keinen Grund haben, eins dieser Register zu lesen, da Du ja deren
Inhalt normalerweise schon kennen solltest.
Bevor der Beitrag auf der nächsten Seite verschwunden ist:
Probiere auch schon länger das UART beim 8515 in C-Code zum laufen
bringen, mit dem STK500:
#include <avr/io.h>
void send(char zeichen);
int main()
{
sbi(UCR,3); // TX aktivieren
outp(25,UBRR); // 4MHz -> 9600 bps
for(;;)
{
send('T');
send('e');
send('s');
send('t');
send('!');
}
}
void send(char zeichen)
{
while ( !( USR & (1<<UDRE)) )
{
UDR = zeichen;
}
}
Sendet leider nichts ans Terminal, darum wollte ich mal fragen ob meine
send-Funktion bzw. das USR richtig ist.
Das Assembler-Beispiel aus dem Tut habe ich mit dem 4433 auch
ausprobiert, funktioniert auch, leider nicht immer. Manchmal muss ich
erst den Reset-Taster drücken, dass "merkwürdige" Zeichen wieder
"Test!" ergeben - mit dem STK-Board.
Kleiner Hinweis (da ich auch das Problem hatte):
Das STK500 verwendet einen Takt von 3,69MHz für den
"Slave"-Controller. Zumindest war das beim mitgelieferten at90s8515
so.
Einstellen kannst du die Frequenz im AVR-Studio bzw. mit
STK500-Plug-in.
Schönen Gruß
Rahul
@funker:
void transmit(unsigned char data){
while(! (USR & (1<<UDRE)))
;
UDR = data;
}
Hier wird eine while-Schleife so lange ausgeführt (und NICHTS gemacht),
so lange die Bedingung "1" ergibt. Du könntest das ";" nach
Assembler in ein NOP übersetzen.
void send(char zeichen)
{
while ( !( USR & (1<<UDRE)) )
{
UDR = zeichen;
}
}
Hier wird in dieser while-Schleife Ständig das an die Funktion
übermittelte "zeichen" in UDR geschrieben.
So wäre das richtig (nur, um sicher zu stellen, daß das auch korrekt
verstanden wird :):
void send(char zeichen)
{
while ( !( USR & (1<<UDRE)) )
{
/* NOP ;) */
}
UDR = zeichen;
}
Gruß,
Patrick...