Interrupt Flag in ISR zurücksetzen funktioniert nicht

OP #2191295
Lesenswert?

Hallo!

ich habe einen Datenlogger gebaut, der alle paar Minuten für die 
Messungen von einer RTC (DS1337) geweckt wird. Datenlogger mit 
sämtlichen Schnick Schnack funktioniert, nur in der ISR nach dem 
Aufwecken läuft was schief...
Ich setz den Timer an der DS1337 und schick den ATmega324PA schlafen. 
Wenn der avr über den INT0 aufgeweckt wird, wird die ISR(INT0_vect) 
ausgeführt. Soweit OK. In der ISR steht folgendes:
1
ISR(INT0_vect){
2
  led_on();
3
  rtc_clear_alm();
4
}

Die Funktion rtc_clear_alm() soll das INT Flag in der DS1337 
zurücksetzen. Bei der Zeile i2c_start(); is aber Schluss und der avr 
steckt!
1
unsigned char rtc_clear_alm(void){
2
  
3
  unsigned char errorStatus;
4
  
5
  errorStatus = i2c_start();
6
  if(errorStatus == RTC_ERROR)
7
  {
8
    i2c_stop();
9
    return(RTC_ERROR);
10
  }
11
  
12
  errorStatus = i2c_sendAddress(DS1337_W);
13
  if(errorStatus == RTC_ERROR)
14
  {
15
    i2c_stop();
16
    return(RTC_ERROR);
17
  } 
18

19
  ...
20

21
  i2c_stop();
22
  return(!RTC_ERROR);
23
  
24
  
25
}

kann mir da jemand einen Denkanstoß geben? Bin schon leicht verzweifelt!

Vielen Dank schon mal...

Roman
Gast #2191299
Lesenswert?

Wahrscheinlich werden in den i2c Routinen auch Interrupts verwendet. Die 
sind natürlich solange blockiert, wie Du noch in der Interrupt-Routine 
bist.

Das eigentlich anzuwendende Schema ist sowies in Interrupts nur Flags zu 
setzen und in main, wenn dieses Flag gesetzt ist, dann die entsprechende 
Aktion auszulösen. LEDs einschalten geht ja noch, aber komplexe 
Funktionen aufrufen ist eher zu vermeiden. Du siehst ja warum.
Gast #2191302
Lesenswert?

Roman Dissauer schrieb:
> Die Funktion rtc_clear_alm() soll das INT Flag in der DS1337
> zurücksetzen. Bei der Zeile i2c_start(); is aber Schluss und der avr
> steckt!

I2C ist (aus MC Sicht) grottenlangsam, sowas macht man nicht in einer 
ISR. Lagere das in die main() aus.

Der MC bleibt hängen, weil standardmässig immer nur eine ISR aktiv ist, 
und i2c eine eigene ISR mitbringt. Du kannst das zwar anders haben 
(sei), scheint mir aber keine gute Idee (tm) zu sein. :)
OP #2191311
Lesenswert?

Guru schrieb:
> Das eigentlich anzuwendende Schema ist sowies in Interrupts nur Flags zu
> setzen und in main, wenn dieses Flag gesetzt ist, dann die entsprechende
> Aktion auszulösen. LEDs einschalten geht ja noch, aber komplexe
> Funktionen aufrufen ist eher zu vermeiden. Du siehst ja warum.

Hab ich schon probiert, nur wird die ISR(INT0_vect) immer wieder 
ausgeführt, solange INT0 auf 0V liegt! Deswegen will ich ja Das INT Flag 
der DS1337 zurücksetzen... damit ich wieder ins Main Programm komme.

Hab ich da einen Denkfehler??

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