Hallo! Ich wollte anfangen, ISRs zu benutzen. Dazu habe ich einfach mal den Code aus dem Artikel geklaut (http://www.mikrocontroller.net/articles/Interrupt#.28AVR-.29_Beispiele_f.C3.BCr_die_praktische_Programmierung), geringfügig verändert: 1. Port B ist Ausgabe 2. Timer ist jetzt Timer 0 und versucht, dass auf einem Atmega8 im STK500 zum Laufen zu bringen. Das Programm sollte die LED an PB1 blinken lassen. Ihr ahnt es bereits: Die PortB-LEDs gehen an, auch PB1, aber es blinkt nicht. Ich hab dann mal die Forensuche bemüht, aber die Leute haben meist fortgeschrittenere Probleme mit ISR, nicht sowas simples... Um die Antworten auf einige typische Fragen vorweg zu nehmen: Atmega8 ist als Device ausgewählt uC ist auf 1 MHz intern gefust Ich freue mich über jede Hilfe! Gruß, Krischan #define F_CPU 1000000 #include <avr/io.h> #include <stdint.h> #include <avr/interrupt.h> // globale Variablen volatile uint8_t flag = 0; int main() { // IO konfigurieren DDRB = 0xFF; PORTB = 0xFF; // Timer2 konfigurieren TCCR0 = (1<<CS02) | (0<<CS01) | (0<<CS00); // Vorteiler 256 -> ~65ms Überlaufperiode @ 1 MHz TIMSK |= (1<<TOIE0); // Timer Overflow Interrupt freischalten // Interrupts freigeben sei(); // Endlose Hauptschleife while(1) { if (flag == 1) { // Neuer Timerzyklus ? flag = 0; // hier steht jetzt in Normalfall ein grosser Programmblock ;-) PORTB ^= (1 << PB1); // LED toggeln } } } // Timer2 overflow Interrupt // hier wird der Hauptschleife ein neuer Timerinterrupt signalisiert ISR( TIMER0_OVF_vect ) { flag = 1; }
65ms? Also 130ms Periode. Mensch, musst Du schnell gucken können! Wir könnten da nur eine scheinbar dauerhaft leuchtende LED sehen.
Krischan schrieb: > 7 Hz wären noch als Blinken/Flackern zu sehen und ich wäre zufrieden. Mach das trotzdem mal länger: if (flag >= 8) {... ISR( TIMER0_OVF_vect ) { flag++; } mfg.
Danke, Thomas, das war eine gute Idee. Leider liegt der Fehler nicht an dieser Stelle - ich habe den Wert auch mal auf 80 gesetzt, mit dem gleichen Ergebnis: die LEDs sind alle gleich hell. Da stimmt grundsätzlich irgendwas nicht, eine LED, die in 50% der Zeit an/aus gepulst ist, müsste, unabhängig von der Frequenz der Pulse, mit 50% insgesamt wahrgenommener Helligkeit scheinen. Aber bei mir sind alle LEDs gleich hell. Es scheint so, als würde das Programm die ISR garnicht wahrnehmen.
Krischan schrieb: > eine LED, die in 50% der > Zeit an/aus gepulst ist, müsste, unabhängig von der Frequenz der Pulse, > mit 50% insgesamt wahrgenommener Helligkeit scheinen. Nö, dein Auge ist ziemlich nichtlinear. Aber sehen sollte man den Unterschied schon...
Wieso "alle" LEDs? Da wird doch nur ein Portpin getoggelt. Aber wie schon gesgt: Nachmessen. Das gibt die zuverlässigsten Informationen.
Funktioniert leider auch nicht. Hätte ja gelacht, wenns das gewesen wäre, das wäre dann ein Compilerfehler gewesen, oder? Mein erster... Aber, wie gesagt, leider nicht. Ich benutze übrigens AVR GCC.
"Alle" LEDs, weil ich in das mit DDRB = 0xFF; PORTB = 0xFF; so eingestellt habe. Du hast recht, es wird nur PB1 getoggelt, aber der Rest ist 1, nicht 0. Ich habe Dir zuliebe auch mal nachgemessen, an PB1 liegt Vdd=4,94 V an.
>Ich habe Dir zuliebe auch mal nachgemessen, an PB1 liegt Vdd=4,94 V an. Wieso "mir zuliebe"? DU willst doch das es blinkt. Jedenfalls kann die LED bei einer statischen Spannung von 4.94V natürlich nicht blinken. Du hast Dir hoffentlich schon gedacht, das Du nicht mit nem Multimeter sondern dem Oszi messen sollst, hoffe ich.
Dein Programm sollte funktionieren, ich habe legendlich den Vorteiler vergrößert: TCCR0 = (1<<CS02) | (0<<CS01) | (1<<CS00); //1024 ==> 262ms ==> 3,8 Hz Probier doch bitte mal die anghängte hex-datei aus. Gruss Andreas PS: Habe jetzt mein STK500 nicht rausgekramt aber im Simulator funktioniert es.
Es stimmt, dass ich das will, dass es blinkt. Ich glaube allerdings nicht, dass die Fehlerursache im Bereich "es blinkt zu schnell" zu suchen ist. Siehe dazu der Post weiter oben (der mit den 50%) und Eumels Korrektur dazu. Ich habe mit einem Multimeter gemessen. Das Ding ist träge genug und nimmt eine (hochfrequente) Pulsweitenmodulation - und das hätten wir ja schließlich, falls die LED zu schnell blinkt - als gemittelte Spannung wahr. Das weiß ich aufgrund früherer Erfahrungen Da bei einem 50% duty cycle mit annähernd 5V Vdd = Vmax um die 2,5V Spannung zu erwarten wären, spricht das meiner Meinung nach für die Theorie, dass die ISR irgendwie vom Programm misachtet wird.
Hallo Andreas, Dein .hex funktioniert, wie es zu erwarten gewesen wäre. Das ist gut! Und jetzt wird es interessant: Wenn ich Deine Änderungen in meinen Code übernehme, die Sache kompiliere und flashe, dann bekomme ich wieder mein eintöniges "Es tut sich nichts"-Ergebnis. Darf ich Dich bitten, den Quellcode zu posten?
Wenn Du nicht messen willst oder kannst, dann bleibt Dir noch der Simulator. Am Code sehe ich jedenfalls kein Problem. Dann kann es noch die Schaltung sein. Deine Vermutung, dass garnicht gepulst wird halte ich für durchaus nicht abwegig. Aber das ein Programm einen Interrupt ignoriert, das gibt es nicht. Sobald Interrupts enabled sind und der fragliche Overflow auch, muss die CPU den Interrupt behandeln. Wenn man also Deinen, durch das Multimeter behaupteten, statischen Pegel als gegeben annimmt und das das Programm an sich gehen müsste, dann kommt man auf einen Widerspruch, der sich allenfalls noch im Simulator oder auch mit dem Oszi aufklären lässt.
Krischan schrieb: > Es stimmt, dass ich das will, dass es blinkt. Das Programm blinkt auch. Da ist alles in Ordnung. Timer0 hat 2 Register. Da kann selbst der grösste Idiot wenig falsch machen. Auch hat man bei den 4 relevanten Bits nur 16 Möglichkeiten. Und bei fast allen funktioniert es irgendwie. Also die übliche Checkliste: Richtige Taktquelle eingestellt? CKDIV8-Fuse? Geht glaube ich beim 8er ein bisschen anders, können wir aber schon abhaken. Richtiger Controller eingestellt(Compiler)? Richtiger Controller eingestellt(Brenner)? Wird die richtige Datei geflasht? Äusserst beliebter Fehler! Funktioniert die Hardware? Teste mal mit einem Miniprogramm: while(1) { DDRB = 0xFF; PORTB = 0; _delay_ms(500); PORTB = 0xFF; } Wenn das nicht blinkt ist deine Hardware im A... mfg.
Bleibt noch die weitere Möglichkeit das der hier gepostete Code nicht der tatsächlich ablaufende Code ist. Das ist durchaus nicht unwahrscheinlich. Einfach mal das falsche Hex-File im Programmierdialog ausgewählt. Ist schon mehreren Leuten so gegangen.
Thomas Eckmann schrieb: > while(1) > { > DDRB = 0xFF; > PORTB = 0; > _delay_ms(500); > PORTB = 0xFF; //Da fehlt noch ein Delay > _delay_ms(500); > } > Also die übliche Checkliste: Watchdog und BOD fehlen noch. mfg.
Die übliche Checkliste. Richtiger Controller eingestellt(Compiler)? War Atmega128 eingestellt. Don't taunt the Checkliste! Es blinkt jetzt. Das ist top, weil, es blinkt jetzt, andererseits auch ein bisschen traurig, weil, ahh, Gott... ich hab den ganzen Nachmittag schon dran gesessen und gedacht, dass kann nicht sein... Ich gehe mit einem lachenden und einem weinenden Auge ins Bett. Euch allen, in diesem Sinne, eine Gute Nacht, und Danke!
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.