PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Interruptproblem



tobhu
05.02.2007, 13:41
Hallo, ich habe ein RN Controll Mega 32 Board und kenne mich mit der C Prog. nur teilweise aus.Ich möchte gerne, dass erst nach einer bestimmten Zeit mein Controller anfängt zu arbeiten, vieleicht so nach 5 Sekunden, die Zeit muß nicht genau sein. Ich wollte dies mit dem Timer0 und Interrupt realisieren, nur leider funktioniert es mit meinem Code nicht und ich weiß nicht so recht warum.Wie kann ich denn überprüfen, ob das Interruptflag nach einem Timeroverflow gesetzt wurde, oder nicht. Bei meinem Programm gehen die LEDs die vom PORTC Lowaktiv angesteuert werden gar nicht an.
Vielen Dank.

SprinterSB
05.02.2007, 18:01
Eher so was in der Richtung.

Da war einiges nicht korrekt, ich überlass mal dir rauszufinden, was...

Mal ins Blaue und nicht getestet, aber auf jeden Fall näher dran:



#include <avr/io.h>
#include <avr/interrupt.h>

volatile int i;

ISR(TIMER0_OVF_vect)
{
i++;
}


int main (void)
{
TCCR0 |= (1<<CS00) | (1<<CS02);
TIMSK |= (1<<TOIE0);

sei();

// main loop
while (1)
{
do // loop while i <= 2000
{
int j;

// atomic!
cli();
j = i;
sei();

if (j > 2000)
break;
}

DDRC=0xFF;
PORTC=0x00; //LEDS sollen jetzt nach Ablauf der Zeit zugeschaltet werden

// freeze
cli();
while (1);
}
}

tobhu
05.02.2007, 18:58
Danke für die schnelle Hilfe, aber hätte doch mal noch ne Frage.
Wozu die erste While Schleife vor der Do Schleife, wird denn nicht mit der letzten While Schleife eh immer wieder die Do Schleife aufgerufen?
Und warum weißt du die Variable i noch mal der Variablen j zu, obwohl i doch schon existiert?

toetzel
05.02.2007, 23:16
Hallo,
ich habe diesen Code geschrieben:
#include <avr/io.h>
#include <avr/interrupt.h>

volatile int i;
int main (void)
{
TCCR0 |= (1<<CS00) | (1<<CS02);
TIMSK |= (1<<TOIE0);
sei();

// schleife
while (1)
{
if (i<=10){ //i<=10 sollte sofort erfüllt sein , also LED an
PORTC |= (1<<PC1);
}
cli();

}
}

ISR(TIMER0_OVF_vect)
{
i++;
}

bei mir funzt es aber nicht. Warum wird der Timer immer außerhalb von Sei(); aktiviert? Muss ich eventuell noch andere Einstellungen machen?

Danke und Gruß
Tötzel

SprinterSB
06.02.2007, 11:42
@tobhu:

Ja, die äussere while wird eigentlich nicht gebraucht hier. Ist aber üblicher Programmaufbau, wenn mehr gemacht wird als nichts (ab freeze).

Die Hauptschleife wird dann immer wieder durchlaufen, weil immer die gleichen AKtionen gemacht werden zB "Eingabe abfragen -> darauf reagieren".

Warum ich i kopiere:
https://www.roboternetz.de/wissen/index.php/Fallstricke_bei_der_C-Programmierung#Nicht-atomarer_Code

@toetzel:
Übliche Vorgehensweise:
1) Hardware (Timer, IRQs, ...) initialisieren.
2) IRQs zulassen (sei)
3) Ewige Hauptschleife

Di stellst die IRQs in der Hauptschleife wieder ab, dadurch bekommst du keine Timer-IRQs mehr.

toetzel
06.02.2007, 14:04
@Sprinter

Danke für den Tipp,

Gruß
Tötzel

tobhu
06.02.2007, 18:49
Danke dir, funktioniert jetzt.