Pages: [1]   Go Down
Author Topic: Interrupt Service Routine pausieren sei(); cli();  (Read 2869 times)
0 Members and 1 Guest are viewing this topic.
Bremen / Germany
Offline Offline
Full Member
***
Karma: 0
Posts: 140
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo zusammen.

Kann mir vielleicht jemand bei folgendem Problem weiterhelfen? Ich habe eine Interrupt-Service-Routine (ISR) programmiert welche ich unter bestimmten Bedingungen mit den Befehlen sei(); und cli(); starten /anhalten möchte. Anschließend soll sie wie zuvor weiterarbeiten (jede Sekunde Werte ändern). Anhalten mit cli(); funktioniert. Der Befehl sei(); startet die ISR aber nicht wieder!?

Ausschnitte aus meinem Programm mit Teilen aus dem Internet:

int Counter = 0; //Variable für Interrupt-Counter-Overflow
//------------------------------------------------------------
// Interrupt-Service-Routine
// Aruino runs at 16 Mhz, so we have 1000 Overflows per second...
// 1/ ((16000000 / 64) / 256) = 1 / 1000
ISR(TIMER2_OVF_vect) {
  TCNT2 = 6; //Timer Reset
  Counter += 1;
  if (Counter == 1000) {
    Counter = 0;
    Sekunde +=1;
  }
};

void setup() {
  //Timer2 Settings: Timer Prescaler /64,
  TCCR2B |= (1<<CS22);
  TCCR2B &= ~((1<<CS21) | (1<<CS20));    
  // Use normal mode
  TCCR2A &= ~((1<<WGM21) | (1<<WGM20));   // turn off WGM21 and WGM20 bits
  TCCR2B &= ~(1<<WGM22);                  // turn off WGM22  
  // Use internal clock - external clock not used in Arduino
  ASSR |= (0<<AS2);
  //Timer2 Overflow Interrupt Enable
  TIMSK2 |= (1<<TOIE2) | (0<<OCIE2A);  
  TCNT2 = 6; //Timer Reset              
  sei();
}

Damit läuft die ISR erst einmal. Das klappt auch alles ganz gut. Aber wenn ich mit folgender Abfrage in eine Unterroutine springe und die ISR anhalte bekomme ich sie nicht wieder zum Laufen. Das Programm friert einfach ein:

if (Taster_X == HIGH) { ISR_anhalten (); }

void ISR_anhaltenn () {
  cli();
  Serial.println("ISR angehalten");
  Register_setzen ();
  delay(1000);
  sei();
}
Logged

0
Offline Offline
God Member
*****
Karma: 0
Posts: 588
LumiNet rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

mit cli() hälst Du alle Interrupts an.
Somit läuft auch die delay() Funktion nicht mehr, da diese einen Hardwaretimer benutzt...
Ausserdem wird auch die serielle Kommunikation nicht mehr klappen, da der UART nicht mehr senden wird, oder klappt das bei Dir noch?

grundsätzlich macht man das ISR_anhalten so:

Code:
void ISR_anhaltenn () {
 uint8_t sreg = SREG;
 cli();
//irgendwas machen

 SREG = sreg;
}

Interrupts sind ein sehr komplexes Thema, ich empfehle dazu, das Datenblatt vom ATMega168 ausführlich zu studieren.

Am sinnvollsten wäre es, nur den Timer zu stoppen und dann wieder neu zu starten, also stoppen mit
Code:
TCCR2B &= ~(1 << CS22);
in Deinem Fall. Und starten so wie Du es in setup() machst.
Also nicht cli() und sei() benutzen, sondern nur den Timer stoppen und neu starten...
« Last Edit: March 12, 2009, 10:06:22 am by bohne » Logged


Bremen / Germany
Offline Offline
Full Member
***
Karma: 0
Posts: 140
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Vielen Dank für die schnelle Antwort! Ich werde dies gleich morgen mal ausprobieren und die Befehle gleichzeitig im Datenblatt ansehen  smiley-wink

Lieben Gruß
Poldi
Logged

Bremen / Germany
Offline Offline
Full Member
***
Karma: 0
Posts: 140
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey "bohne"! Da bin ich wieder ;-)

Hat alles super geklappt. Bin total happy! Vielen Dank nochmal!

Lieben Gruß
Poldi
Logged

0
Offline Offline
God Member
*****
Karma: 0
Posts: 588
LumiNet rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Klasse!

Und was wird Dein Programm machen wenn es fertig ist? Oder war das ein Experiment, um die Timer besser zu verstehen?
Logged


Bremen / Germany
Offline Offline
Full Member
***
Karma: 0
Posts: 140
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Das Programm ist eine Digitaluhr realisiert mit LEDs an Schieberegistern!

Sie lief auch schon klasse und zieht viele neugierige Blicke auf sich. Es hatte mich nur genervt das die ISR das Einsstellen der Uhrzeit immer unterbrochen hat ;-)

Nun habe ich einen Taster "Zeit" hinzugefügt. Solange er gedrückt ist ruht die ISR und ich kann die Register füllen wie ich mag smiley-grin

Lieben Gruß
Poldi
Logged

Pages: [1]   Go Up
Jump to: