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.
hat sich auch schon wieder erledigt, warum verstehe ich zwar nicht, habe die funktionen nach avrfreak design geschrieben - jetzt gehts: #include <avr/io.h> void InitUART(unsigned char baudrate){ UBRR = baudrate; UCR |= (1<<TXEN); } void transmit(unsigned char data){ while(! (USR & (1<<UDRE))) ; UDR = data; } main(void){ InitUART(25); while(1){ transmit('a'); transmit('b'); } }
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...
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.