Hallo! Ich versuche vergeblich mein Timergesteuertes Programm auf meinem ATMega8 ans laufen zu bekommen. Es soll eine Leuchtdiode im Sekundentakt an und ausschalten. Dieses Programm schreibe ich, um den Umgang mit Interrupts und Timern zu verstehen. Statt dass die Leuchtdiode an und ausgeht, bleibt sie einfach an. Ich verstehe nicht, warum. Ich glaube, meine Interrupte werden nicht ausgeführt und die Leuchtdiode ist an, weil sie standartmäßig angeschaltet wird, wenn ich den Port als Ausgang definiere, oder? Auch der Simulator in Linux (simulavr) lässt die Lampe nicht im sekundentakt leuchten, wenn ich ihn mit $ simulavr -d atmega8 -c 1000000 ./a.out starte. Der ausdokumentierte Quellcode ist im Anhang. Martin
Hmm, warum fängst Du nicht mit dem demo.c an, das zur avr-libc dazugehört? Es hat alles, was ein ,,Hello world'' Programm so braucht -- einschließlich Interrupts. Und Kommentare. ;-)
Achso, ich wusste nicht, dass es sowas gibt. Ich habe es mir gerade angeguckt, bekomme aber beim kompilieren die Fehlermeldung: #error "Don't know what kind of MCU you are compiling for" Ich habe natürlich nicht vergessen, meinen Mikrocontroller mit #define _AVR_ATmega8_ anzugeben. Vielleicht ist das Programm nicht für diesen geschrieben. Wenn ich diese error-Zeile aus der demo.c lösche, bekomme ich lauter Error-Meldungen, z.B. findet er kein OCR. Ich kenne mich damit nicht aus. In meinem Programm ist schon das aller- nötigste und es klappt trotzdem nicht. Hat jemand vielleicht eine Idee, wo der Fehler liegt? Martin
> Ich habe natürlich nicht vergessen, meinen Mikrocontroller mit > #define __AVR_ATmega8__ > anzugeben. Schon falsch. Die Compileroption -mmcu macht das für Dich. > Wenn ich diese error-Zeile aus der demo.c lösche, bekomme ich lauter > Error-Meldungen, z.B. findet er kein OCR. Nun, wie Dir die #error Zeile suggerieren wollte, kennt das Progrämmchen von sich aus noch keinen ATmega8 (einfach, weil ich selbst keinen habe, mit dem ich es testen könnte). Leider benennt Atmel die Steuerregister von AVR zu AVR ein wenig anders (je nachdem, was die jeweilige Hardware halt tatsächlich hergibt), so daß man kleine Anpassungen für jeden AVR braucht. Mit einem Datenblatt in der Hand sollte das allerdings kein Thema sein, das für den ATmega8 nachzuholen. Wahrscheinlich kannst Du einen der existierenden #ifdef Blöcke übernehmen (oder gar nur ein || defined(_AVR_ATmega8_) mit reinschreiben), besonderes Augenmerk solltest Du dem OC-Ausgang widmen, da Port und Pin-Nummer dafür in der Hardware vorgegeben sind. So als Schuß ins Blaue: #elif defined(_AVR_ATmega8_) # define OC1 PB1 # define DDROC DDRB # define OCR OCR1A # define PWM10 WGM10 # define PWM11 WGM11 Wenn Du mir bestätigst, daß es damit funktioniert, nehme ich das in den offiziellen Sourcecode mit auf.
HI! Ja, das funktioniert bei mir. SUPER!!! Danke! Die Leuchtdiode leuchtet bei einem 8 MHz-Quarz fast im Sekundentakt. (in 15 Sekunden 1 Sekunde Unterschied). Bei einem 1 MHz-Quarz ist sie VIEL langsamer. Wo kann ich eigentlich im Programm einstellen, welchen Quarz ich benutze? Martin
> Ja, das funktioniert bei mir. SUPER!!! Danke! OK, ist im offiziellen Sourcecode drin. > Wo kann ich eigentlich im Programm einstellen, welchen Quarz ich > benutze? Gar nicht, weil Quarze Hardware sind und nicht Software. ;-) (Wahrscheinlich wolltest Du was anderes fragen, aber ich komm nicht drauf, was es sein sollte.)
Die Frage ist, wie ich im Programm (demo.c) festlegen kann, dass die Leuchtdiode einmal in der Sekunde an- und ausgeht. Das hängt natürlich vom Quarz ab, den ich benutze. Was muss ich verändern, wenn ich einen 8 MHz-Quarz benutze und was muss ich verändern, wenn ich einen 1 MHz-Quarz benutze? Ich besitze nämlich diese beiden Quarze.
Dazu mußt Du Dir mal die Doku zum PWM in der Beschreibung des Timer 1 durchlesen. Du kannst erstmal den Vorteiler des Timers ändern, allerdings gibt das natürlich nur grobe Schritte. Dann kannst Du die Zählweite des Timers umschalten (10-bit = 1024, 9-bit = 512, 8-bit = 256), damit ändert sich auch die Frequenz, allerdings mußt Du das Programm dann auch ändern, da sich der TOP-Wert des Zählers ändert. Du kannst den PWM bei den neueren ATmegas auch auf `fast PWM' schalten, siehe Doku. Bringt nochmal doppelte Frequenz.
"Was muss ich verändern, wenn ich einen 8 MHz-Quarz benutze und was muss ich verändern, wenn ich einen 1 MHz-Quarz benutze?" Den Code so schreiben, daß er für Dich alles genau ausrechnet, z.B.: http://www.mikrocontroller.net/forum/read-4-57760.html Peter
Nee Peter, das hilft beim PWM so nicht weiter. Du hast dort ein paar Freiheitsgrade weniger.
Hat er ja aber mittlerweile -- demo.c benutzt eine PWM und läßt die LED auf- und abschwellen. Fällte trotzdem noch in die Klasse ,,Hello world!'' Programm, der PWM auf dem AVR ist so simpel.
Hi! So langsam verstehe ich die demo.c. Ich habe jedoch noch einige Fragen: 1) Ich versteh nicht, wofür die Bytes 4-7 im "Timer/Counter 1 Control Register A" (TCCR1A) da sind: COM1A1 COM1A0 COM1B1 COM1B0 Wird in der demo.c in folgendem Beispiel in der main verwendet: TCCR1A = _BV (PWM10) | _BV (PWM11) | _BV (COM1A1); \ 10 bit PWM / \ ? / ------------------------ ----------- Nach einer Beschreibung sollen sie angeblich der Compare Ausgang A und B sein. Heißt das, dass der Timer ständig mit einem bestimmten Wert verglichen wird, wenn diese Bits gesetzt sind? Was ist dann der Unterschied zwischen COM1A1 und COM1A0? Und was bedeutet das A und das B in COM1A1 und COM1B1? 2) OCR ist doch die Pulsweite, oder? Bei 10 bit PWM ist für OCR=1024 die Pulsweite am größten, oder? Wenn ich keine Pulsweite brauche, sondern nur einen sekündlichen Impuls (an / aus), dann kann ich die Pulsweite doch zwischen 1024 und 0 immer hin- und herspringen lassen, oder? 3) Falls jemand vielleicht Lust hat, in meinem Programm ganz oben nachzugucken, wieso mein Interrupt nicht funktioniert und die Lampe ständig hell bleibt, würde ich mich sehr freuen, falls er mir Tipps geben würde, wo der Fehler liegt. Ich bedanke mich nochmal vielmals für eure Hilfe und wäre sehr froh, wenn ich mein Programm ans Laufen bekomme. Martin
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.