Hallo, zum Einstieg in die AVR-Programmierung des ATMega8 habe ich ein kleines Programm, dass in 500ms Abständen den PIN 0 am Port B zwischen high und low hin und her wechselt. Wenn ich das Programm auf der Konsole mit make und selbst erstellter Makefile kompiliere stimmen die Zeitabstände von 500ms. Nun bin ich gerade dabei zu Eclipse zu wechseln. Den Source-Code habe ich 1:1 übernommmen, aber nun sind die high/low Phasen nicht mir 500ms sondern ca. 10000ms lang. Woran könnte dies liegen? ---------------------------------------------------------- Hier noch der Quellcode: main.c: #include <avr/io.h> #include <util/delay.h> int main (void) { unsigned char zwischenspeicher; DDRB = 0b00000001; while(1) { zwischenspeicher = PORTB; zwischenspeicher = zwischenspeicher ^ 0b00000001; PORTB = zwischenspeicher; _delay_ms(500); } return 0; }
Alexander G. schrieb: > Woran könnte dies liegen? das du F_CPU vermutlich unterschiedlich definiert hast.
Peter II schrieb: > das du F_CPU vermutlich unterschiedlich definiert hast. Daran habe ich schon gedacht und folgendes versucht: Bei dem händischen Makefile einmal F_CPU=16000000 und dann F_CPU=8000000 ausprobiert. In beiden Fällen hatte ich am Pin die 500ms Phasen. F_CPU scheint hier keinen Einfluss zu haben. Was vielleicht noch Interessant ist, ist folgende Warnmeldung beim Ausführen von make: /usr/avr/include/util/delay.h:90:3: warning: #warning "F_CPU not defined for <util/delay.h>" [-Wcpp] # warning "F_CPU not defined for <util/delay.h>" Aber wahrscheinlich habe ich beim Makefile noch was falsch gemacht und muss noch irgendwo die F_CPU-Variable als Parameter übergeben ??? ----- Makefile------------------- TARGET=main MCU=atmega8 F_CPU=16000000 CC=/usr/bin/avr-gcc SOURCES=$(TARGET).c PROGRAMMER=avrispmkII PORT=-P usb BAUD=-B 10 OPT = s # -----------Ab hier nichts verändern --------- OBJECTS=$(SOURCES:.c=.o) CFLAGS=-c -Os LDFLAGS= all: hex eeprom hex: $(TARGET).hex eeprom: $(TARGET)_eeprom.hex $(TARGET).hex: $(TARGET).elf avr-objcopy -O ihex -j .data -j .text $(TARGET).elf $(TARGET).hex $(TARGET)_eeprom.hex: $(TARGET).elf avr-objcopy -O ihex -j .eeprom --change-section-lma .eeprom=1 $(TARGET).elf $(TARGET)_eeprom.hex $(TARGET).elf: $(OBJECTS) $(CC) $(LDFLAGS) -mmcu=$(MCU) $(OBJECTS) -o $(TARGET).elf .c.o: $(CC) $(CFLAGS) -mmcu=$(MCU) $< -o $@ size: avr-size --mcu=$(MCU) -C $(TARGET).elf program: avrdude -p$(MCU) $(PORT) $(BAUD) -c$(PROGRAMMER) -Uflash:w:$(TARGET).hex:a clean_tmp: rm -rf *.o rm -rf *.elf --------------------------------------------- Bei der Eclipse-Variante steht in der Makefile kein F_CPU drin. Ein händisches ändern habe ich hier bislang nicht hinbekommen, da Eclipse es beim kompilieren jedesmal überschreibt.
:
Bearbeitet durch User
Alexander, C hast Du bisher nicht gelernt ? Alexander G. schrieb: > Hallo, > zum Einstieg in die AVR-Programmierung des ATMega8 habe ich ein kleines > Programm, dass in 500ms Abständen den PIN 0 am Port B zwischen high und > low hin und her wechselt. > > Wenn ich das Programm auf der Konsole mit make und selbst erstellter > Makefile kompiliere stimmen die Zeitabstände von 500ms. > > Nun bin ich gerade dabei zu Eclipse zu wechseln. Den Source-Code habe > ich 1:1 übernommmen, aber nun sind die high/low Phasen nicht mir 500ms > sondern ca. 10000ms lang. > > Woran könnte dies liegen? > > ---------------------------------------------------------- > Hier noch der Quellcode: > main.c: > > #include <avr/io.h> > #include <util/delay.h> > > int main (void) > { > unsigned char zwischenspeicher; > DDRB = 0b00000001; > while(1) > { > zwischenspeicher = PORTB; > zwischenspeicher = zwischenspeicher ^ 0b00000001; > PORTB = zwischenspeicher; > _delay_ms(500); > } return 0; > }
1 | #define LED PB0
|
2 | |
3 | int main (void) |
4 | {
|
5 | DDRB |= (1<<LED); // set LED to output |
6 | // PORTB &= ~(1<<LED); // set LED output to low
|
7 | // PORTB |= (1<<LED); // set LED output to high
|
8 | |
9 | while(1) |
10 | {
|
11 | PORTB = (1<<LED); // toggle LED output |
12 | _delay_ms(500); |
13 | }
|
14 | return 0; |
15 | }
|
Alexander G. schrieb: > F_CPU scheint hier keinen Einfluss zu haben. Sollte sie aber. Denn damit sagst du dem Compiler, womit dein Controller läuft... > muss noch irgendwo die F_CPU-Variable als Parameter übergeben ??? Der Compiler muss wissen, welche Taktfrequnz verwendet wird. Also muss die F_CPU in die Compilerkommandozeile.
:
Bearbeitet durch Moderator
Ups - Tastaturfehler.
1 | PORTB ^= (1<<LED); // toggle LED output |
Oder du probierst es mal so: #include <avr/io.h> #define F_CPU 16000000ul #include <util/delay.h>
Alexander G. schrieb: > .c.o: > $(CC) $(CFLAGS) -mmcu=$(MCU) $< -o $@ Hier wird der Compiler aufgerufen. Dort werden nur CFLAGS und -mmcu$(MCU) übergeben. Du kannst im dem Makefile so viel definieren wie du willst, wenn der Compiler das nicht übergeben bekommt, ändert sich nichts. Defines übergibt man mit -Dname=abc.
An welcher Stelle des Make-Files wird denn die "make-Variable" "F_CPU" verwendet, sprich an den Comiplier übergeben? Es sollte als Preprozessor-Makro ankommen, also müsste irgendwo ein "-DF_CPU=" stehen. Z.B. könnte CFLAGS=-c -Os durch CFLAGS=-c -Os -DF_CPU=16000000 ersetzt werden. Wichtig aber, die Zahl sagt nur dem Compiler, was die Hardware tut. Also hier 16MHz Quarz/externer Oszilator mit "ohne DIV8 Fuse".
avr schrieb: > Defines übergibt man mit -Dname=abc. Siehe z.B. auch http://www.makerconnect.de/index.php?threads/f_cpu.2396/ (mit Google in 1 min. gefunden...)
Carl D. schrieb: > An welcher Stelle des Make-Files wird denn die "make-Variable" > "F_CPU" > verwendet, sprich an den Comiplier übergeben? Es sollte als > Preprozessor-Makro ankommen, also müsste irgendwo ein "-DF_CPU=" stehen. > Z.B. könnte > CFLAGS=-c -Os > durch > CFLAGS=-c -Os -DF_CPU=16000000 > ersetzt werden. > Wichtig aber, die Zahl sagt nur dem Compiler, was die Hardware tut. Also > hier 16MHz Quarz/externer Oszilator mit "ohne DIV8 Fuse". Dies scheint mir doch ein sehr guter Hinweis. Vor Allem zeigt sich nun folgendes: **** Ohne F_CPU=16000000 (CFLAGS=-c -Os) **** Man bekommt die Warnmeldung /usr/avr/include/util/delay.h:90:3: warning: #warning "F_CPU not defined for <util/delay.h>" [-Wcpp] # warning "F_CPU not defined for <util/delay.h>" Aber die Phasen sind tatsächlich die gewünschten 500ms lang **** Mit F_CPU=16000000 (CFLAGS=-c -Os -DF_CPU=16000000) **** Keine Fehlermeldung mehr, aber statt 500ms sind die Phasen ca. 10Sek lang. **** Mit F_CPU=8000000 (CFLAGS=-c -Os -DF_CPU=8000000) **** Die Phasen sind ca. 5Sek lang.
Alexander G. schrieb: > Dies scheint mir doch ein sehr guter Hinweis. Vor Allem zeigt sich nun > folgendes: Mit welchem Takt betreibst du denn dein Atmega?
Peter II schrieb: > Mit welchem Takt betreibst du denn dein Atmega? Das ist mir gerade auch durch den Kopf gegangen. Diesen ATMega8-16PU hatte ich hier noch rumliegen (seit 7 Jahren) ... und ich habe keine Ahnung, ob ich damals irgendwelche "Taktfrequenzen" geändert habe. Bin gerade dabei im Datenblatt nachzusehen, wo man das einstellt (aber noch nix gefunden). Jedenfalls habe keinen externen Quarz oder sowas dran. (Dies sind halt meine ersten Schritte der AVR-Programmierung)
:
Bearbeitet durch User
Im Datenblatt über den ATMega8 findet man auf S.26: The device is shipped with CKSEL = “0001” and SUT = “10” (1 MHz Internal RC Oscillator, slowly rising power). --> D.h. also, obwohl es ein 16Mhz Mikrocontroller ist, wird er werkseitig mit 1Mhz ausgeliefert. Setzt man F_CPU=1000000 dann stimmt auch alles. Jetzt stellt sich mir nur noch die Frage: wie/wo kann ich in Eclipse eine Einstellung für das Makefile machen, das dort auch F_CPU Einträge erscheinen?
Lothar M. schrieb: > Oder du probierst es mal so: > #include <avr/io.h> > #define F_CPU 16000000ul > #include <util/delay.h> Funktioniert! nur dass ich nun statt 16000000ul die 1000000ul einsetzen muss.
:
Bearbeitet durch User
Alexander G. schrieb: > Funktioniert! ja, aber das ist eine ganz schlechte Idee. Das müsstest du in jedem C file machen und das ist die große Gefahr das du verschiedene Werte hast, wenn du mal die Taktfrequenz änderst.
Wenn du Eclipse mit AVR nutzt, kann ich dir dieses Plugin wärmstens empfehlen: http://avr-eclipse.sourceforge.net/wiki/index.php/The_AVR_Eclipse_Plugin Da kannst du F_CPU direkt bei den Projekteinstellungen festlegen.
:
Bearbeitet durch User
Das AVR-Plugin habe ich bereits installiert und nehmen an, dass ich deswegen nun auch in den Project-Properties unter C/C++ Build -> Environment bei der Variable AVRTARGETFPU die Taktfrequenz angeben kann. ... und das funktioniert auch wunderbar :-)
Karl M. schrieb: > Besser F_CPU=16000000UL Wieso "Besser"? Entweder der Compiler versteht es ohne "UL" richtig oder nicht. Ein bisschen schwanger gibt es nicht.
Alexander G. schrieb: > Funktioniert! Dann überleg mal, warum. _delay_ms() muss die Taktfrequenz kennen. Der eine Weg ist es, das dafür nötige define von Hand zu machen, der bessere Weg ist es, dieses define über die Kommandozeile festzulegen. Und natürlich musst du in diesem define genau die Frequenz angeben, mit der der Controller tatsächlich läuft. Du kannst ihn mit dieser Einstellung nicht auf die "Wunschtaktfrequenz" umstellen. Diese Einstellung passiert woanders. Karl M. schrieb: > Besser F_CPU=16000000UL Im Makefile ist das unnötig, dort wird das UL sowieso noch angehängt...
:
Bearbeitet durch Moderator
Alexander G. schrieb: > deswegen nun auch in den Project-Properties unter C/C++ Build -> > Environment bei der Variable AVRTARGETFPU die Taktfrequenz angeben kann. Falsche Stelle! Da gehört das hin, wenn du das Plugin verwendest.
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.