Hallo, ich habe ein Problem mit einem Atmega32. Obwohl auf diesen Mikrocontroller 32 KB Programmspeicher passen sollte, funktioniert meine Software nur bis zu folgender Größe der ELF Datei: Größe: 7,95 KB (8.149 Bytes) Größe auf Datenträger: 7,95 KB (8.149 Bytes) Ich habe ein (unschönes) Beispielprogramm geschrieben. Es soll einfach dazu dienen 8 KB Programmgröße zu erreichen: #define _AVR_ATmega32_ #include<avr/io.h> #define F_OSC 8000000 /* oscillator-frequency in Hz */ #define UART_BAUD_RATE 9600 //#define UART_BAUD_CALC(UART_BAUD_RATE,F_OSC) ((F_OSC)/((UART_BAUD_RATE)*16l)-1) #define UART_BAUD_CALC(UART_BAUD_RATE,F_OSC) ((F_OSC + (UART_BAUD_RATE)*8l) /((UART_BAUD_RATE)*16l)-1) //Define für delay.h # define F_CPU 8000000UL #include<util/delay.h> #include<functions.c> // Hauptsächlich Uartfunktionen //#include<spi.h> //#include<spi.c> void uart_auswertung(char c); void init_all(void); int main(void); void sleep(void) { _delay_loop_2(1); //1 ms delay _delay_loop_2(1); //1 ms delay //_delay_loop_2(1) wird innerhalb dieser Funktion ca. 470 mal aufgerufen! ... ... } void uart_ausgabe(char c) { uart_putc('E');delay();uart_putc('R');delay();uart_putc('R');delay(); uart_putc('O');delay();uart_putc('R');delay(); } void init_all(void) { uart_init(); // UART initialisieren } int main(void) { init_all(); char temp_c; /* Entlosschleife; Warten auf UART-Empfang: */ for(;;) { temp_c = uart_getc_wait(); uart_auswertung(temp_c); } } Ich kontrolliere die Funktionalität des Programmes über eine einfache UART<->RS232 kommunikation. Leider muss ich zugeben kein Makefile zu verwenden und nötige Anweisungen dem Compiler (avr-gcc.exe) als Parameter zu übergeben. ..\avr-gcc.exe" groesser.c -Os -o groesser.bin Ich benutze Ponyprog2000 V207A(Atmega32 ist eingestellt) Über Tips oder Ideen würde ich mich sehr freuen! Gruß Timo
Timo wrote: > #define __AVR_ATmega32__ Schon in der ersten Zeile falsch. Einen derartigen Makro darfst du nicht definieren, es sei denn, die Dokumentation würde dich ausdrücklich dazu auffordern, das zu tun (wie z. B. bei __STDIO_FDEVOPEN_COMPAT_12). Dass du ihn definiert hast, lässt mich vermuten, dass du sowohl beim Compilieren als auch beim Linken die Option -mmcu=atmega32 vergessen hast. Damit baust du (aus hysterischen Kompatibilitätsgründen) Code für einen AT90S8515. Das sollte dir dann auch erklären, warum das Ergebnis auf 8 KiB Größe limitiert ist, aber da hängen noch mehr Pferdefüße dran, wie z. B. einen falsche Interruptvektortabelle.
Ist mmcu=atmega32 vorhanden wie z.B.: ..\avr-gcc.exe" groesser.c -mmcu=atmega32 -Os -o groesser.bin läst sich die Software nicht starten(keine RS232-Kommunikation) Welche Definitionen/Einstellungen müsste ich sonst noch vornehmen?
Timo wrote: > Ist mmcu=atmega32 vorhanden wie z.B.: > > ..\avr-gcc.exe" groesser.c -mmcu=atmega32 -Os -o groesser.bin > > läst sich die Software nicht starten(keine RS232-Kommunikation) > > Welche Definitionen/Einstellungen müsste ich sonst noch vornehmen? Wenn UART Kommunikation nicht stimmt, dann hat das in praktisch 100% aller Fälle folgende Ursachen * Quarzfrequenz stimmt nicht * Quarzfrequenz stimmt nicht * interner Oszi wird benutzt anstatt externem Quarz * Quarzfrequenz stimmt nicht * Umrechnungsformel ist fehlerhaft In diesem Licht: Was'n das
1 | #define UART_BAUD_CALC(UART_BAUD_RATE,F_OSC) ((F_OSC + (UART_BAUD_RATE)*8l) /((UART_BAUD_RATE)*16l)-1)
|
für eine Berechnung?
> //_delay_loop_2(1) wird innerhalb dieser Funktion ca. 470 mal
Du hast eine Funktion geschrieben, in der du 470 mal hintereinander
_delay_loop_2 so aufrufst, daß es eine Warteschleife mit jeweils einem
einzelnen Durchgang ausführt? Wozu das?
> Du hast eine Funktion geschrieben, in der du 470 mal hintereinander > _delay_loop_2 so aufrufst, daß es eine Warteschleife mit jeweils einem > einzelnen Durchgang ausführt? Wozu das? Hat er doch geschrieben: > Ich habe ein (unschönes) Beispielprogramm geschrieben. Es soll einfach > dazu dienen 8 KB Programmgröße zu erreichen: > Einfach Platz verbraten...
Rolf Magnus wrote: >> //_delay_loop_2(1) wird innerhalb dieser Funktion ca. 470 mal > > Du hast eine Funktion geschrieben, in der du 470 mal hintereinander > _delay_loop_2 so aufrufst, daß es eine Warteschleife mit jeweils einem > einzelnen Durchgang ausführt? Wozu das? Sagte er doch: Um das Flash zu Testzwecken voll zu kriegen.
Ich habe eine Software welche über 8 KB groß wird. Ich rufe über 400 mal die gleiche Funktion auf um auf 8 KB Programmgröße zu kommen. Programmiere ich den Atmega32 mit <8 KB läuft die Kommunikation über RS232 fehlerfrei. Erst ab einer Programmgröße von >= 8 KB (nur hinzufügen von z.B. vielen,vielen Sleep-Funktionen läuft die Software nicht mehr. Nur dies ist mein Problem. Mit den RS232-Einstellungen ist alles ok.
Also, Timo,
Hast du jetzt schonmal ausprobiert, dem Compiler auch mitzuteilen,
welchen µC du hast?
> #define __AVR_ATmega32__
Rauslöschen
und beim Compiler/Linker Aufruf -mmcu=atmega32 angegeben?
Wenn du das nicht machst, funktioniert deine UART-Kommunikation bis zu
einer Programgröße von 8KB und darüber hinaus nicht mehr :).
Timo wrote: > Ist mmcu=atmega32 vorhanden wie z.B.: > > ..\avr-gcc.exe" groesser.c -mmcu=atmega32 -Os -o groesser.bin > > läst sich die Software nicht starten(keine RS232-Kommunikation) Ach, und deine ,,Abhilfe'' ist es, -mmcu=atmega32 dann wegzulassen? "Meine Öldruckkontrollampe leuchtet, was soll ich tun?" "Die Lampe ausbauen." Ungefähr so kommst du mir vor... Du wirst nicht drumherum kommen, deine reale Applikation zu debuggen. Stichworte: Oszilloskop (für die RS-232-Leitung), JTAG (ein einfacher Clone genügt für den ATmega32, aber ein AVR Dragon würde es auch tun), ... Genau das, an dem ein Mikrocontroller halt beginnt, Arbeit zu werden. Ach, wart' mal... Was ist "groesser.bin" in obigem Kommando? Da sollte "groesser.o" stehen. Mir schwant was... versuchst du etwa, den verschieblichen Objektcode ohne zu Linken zu benutzen?
Arbeitsschritte: 1.: Über PN avr-gcc.exe -bla -bla ... starten 2.: PonyProg öffnen und Atmega beschreiben 3.: Ich linke wohl nichts s.o. ein Tip wäre hilfreicher als sich über meine Versuche lustig zu machen -> DANKE! Starte ich mit avr.gcc mit: ../avr-gcc.exe -mmcu=atmega32 -groesser.c -Os - groesser.o Läuft die Software nicht. benutze ich -mmcu=atmega32 nicht und definiere den Mikrocontroller in der Software, läuft die UART(allerdings nur bis 8 kB) Hat jemand einen möglichst einfachen Tip?
>Hat jemand einen möglichst einfachen Tip?
Makefile benutzen.
>Hat jemand einen möglichst einfachen Tip? Ja: Verwende AvrStudio zusammen mit WinAVR! AvrStudio generiert das Makefile automatisch, wenn auch nicht immer ein mustergültiges Makefile, aber für den Anfang tut es alleweil.
Man kann das Makefile auch über Mfile generieren lassen, das sollte prima zu PN2 passen. Ich mache mich nicht lustig, sondern schüttele nur den Kopf. Trial&error war noch nie 'ne gute Methode. Es ist erstaunlich, dass du überhaupt so weit gekommen bist. Mit der Hand, ohne Makefile:
1 | avr-gcc -mmcu=atmega32 -g -Os -c groesser.c |
2 | avr-gcc -mmcu=atmega32 -o groesser.elf groesser.o -lm |
3 | avr-objcopy -O ihex -j .text -j .data groesser.elf groesser.hex |
Leider hast du nur Fragmente zitiert und einiges weggelassen, offenbar bekommst du ja ein Hexfile irgendwoher -- daher kann ich nur meine Kristallkugel fragen, was du weggelassen hast und was du wirklich nicht machst. Da ist es schwer, gute Ratschläge zu geben. Wenn avr-gcc über WinAVR installiert ist, sollte es sich ordentlich im ${PATH} befinden, und man muss es nicht mit ../ aufrufen.
Er linkt schon, er ruft gcc nicht mit der Option -c auf, dann compilt und linkt gcc automatisch nacheinander. Soweit ich (auch Anfänger) das beurteilen kann, vergisst du "nur" mmcu=µCTYP. Damit gcc dieses auch an den Linker weiterleitet muss zudem -Wa (oder war es -Wl? sry, weiss es nicht mehr genau, ich compile und linke auch getrennt in meinem makefile) angegeben werden.
ydear wrote: > Er linkt schon, er ruft gcc nicht mit der Option -c auf, dann compilt > und linkt gcc automatisch nacheinander. Ja, stimmt. Das erklärt zumindest, warum es einigermaßen gegangen ist. > Soweit ich (auch Anfänger) das beurteilen kann, vergisst du "nur" > mmcu=µCTYP. Damit gcc dieses auch an den Linker weiterleitet muss zudem > -Wa (oder war es -Wl? -Wl, aber das ist nicht nötig. Wenn man dem Compiler einmal -mmcu mitgibt, weiß er dann, was er dem Linker sagen muss.
Ich habe mich in das Thema Makefile eingearbeitet und die Software läuft jetzt ohne probleme. War doch alles viel einfacher als ich dachte.
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.