grundlegendes ISR-Problem

Gast #2843519
Lesenswert?

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;
}
Gast #2843546
Lesenswert?

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.
Gast #2843560
Lesenswert?

"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.
Gast #2843566
Lesenswert?

>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.
Gast #2843573
Lesenswert?

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.
Gast #2843576
Lesenswert?

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?
Gast #2843579
Lesenswert?

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.
#2843580
Lesenswert?

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.
Gast #2843581
Lesenswert?

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.
Gast #2843598
Lesenswert?

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!

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren