www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Tiny45 Interrupt wird in ISR nicht wieder eingeschaltet


Autor: concept (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wieder ein Problem

Grob das Programm:

TIMSK = 1<<OCIE0A;
MCUCR = 0;
GIMSK = 1<<PCIE;
PCMSK = 1<<PCINT2;
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sei();
sleep_mode();

die main loop ist leer.

Taste gedrückt.

ISR(PCINT0_vect)
{
  GIMSK &= ~(1<<PCIE);
}

Dann nudelt das Programm, in einer Timer-ISR ist dann Schluss

GIMSK |= (1<<PCIE);
sleep_mode();

Aber der PCInterrupt wird anschließend nicht mehr ausgeführt.

Gibt es da irgendwelche Einschränkungen, dass man das Register nicht aus 
einer ISR schreiben kann oder so?

Autor: FBI (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

Du solltest Dich nochmal mit der Funktionsweise von Interruptroutinen 
beschäftigen!
Während einer Interruptroutine sind alle weiteren Interrupts gesperrt 
und werden erst wieder beim Verlassen freigegeben (RETI in ASM). Wenn Du 
also deinen Controller innerhalb der Interruptroutine schlafen legst 
hast Du verloren.
Schmeiß das "sleep_mode();" aus Deinem Timerinterrupt und verschiebe 
selbiges aus main in die Endlosschleife.

CU

Autor: Willi Wacker (williwacker)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oder mach es manuell, ich glaube STI oder so ähnlich heißt der Befehl. 
Die Lösung von FBI ist aber die bessere.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Oder mach es manuell, ich glaube STI oder so ähnlich heißt der Befehl.

Du meinst vermutlich sei(), aber innerhalb einer Interrupt-Routine 
sollte man keine Interrupts einschalten, wenn's nicht unbedingt nötig 
ist bzw. man ich über die Auswirkungen nicht 100% im Klaren ist.

Autor: Fred S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi concept,

Deine Frage kann ich nicht gut mit dem Code in Verbindung bringen. Du 
fragst, warum der PC-Interrupt nicht ausgelöst wird. Anhand des 
geposteteten Codes würde ich sagen, weil Du PCMSK für PCINT2 
initialisierst ( PCMSK = 1<<PCINT2; ), aber keine entsprechende ISR, 
sondern nur eine für PCINT0 ( ISR(PCINT0_vect) ) verwendest. Um Deine 
Verwendung von "sleep()" im Power-Down Modus zur verstehen, brauchte man 
mehr vom Programm. Aber vielleicht findest Du mit meiner obigen 
Anmerkung das eigentliche Problem. Lass doch zunächst mal alle "sleep()" 
usw. Befehle weg.

Gruß

Fred

Autor: concept (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ARGH!

> Während einer Interruptroutine sind alle weiteren Interrupts gesperrt
> und werden erst wieder beim Verlassen freigegeben (RETI in ASM). Wenn Du
> also deinen Controller innerhalb der Interruptroutine schlafen legst
> hast Du verloren.

Danke!


@Fred
Dieser Interrupt kann von mehreren Pins ausgelöst werden.

Autor: concept (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Leider gibt es noch ein Problem, wahrscheinlich übersehe ich wieder 
sowas Blödes :-)

TIMSK = 1<<OCIE0A;
MCUCR = 0;
GIMSK = 1<<PCIE;
PCMSK = 1<<PCINT2;
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sei();
for (;;)
{
   sleep_mode();
}

ISR(PCINT0_vect)
{
   GIMSK &= ~(1<<PCIE);
   set_sleep_mode(SLEEP_MODE_IDLE);
}

ISR(TIM0_COMPA_vect)
{
  GIMSK = (1<<PCIE);
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
}


Das ist auch so in etwa der Ablauf. Die Timer-ISR wird nicht mehr 
aufgerufen, daher gehe ich davon aus, dass er wirklich im PWR_DOWN ist.
Leider greift der Interrupt nicht, und er schläft immer weiter.

Sehr viel später passiert allerdings irgendetwas und er wacht wieder auf 
Knopfdruck auf. Ich kann leider nicht nachvollziehen, was das ist 
(reset?).

Aber wenn es prinzipiell so funktionieren sollte, weiß ich, dass ich den 
Fehler woanders suchen kann.

Autor: concept (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wird bei meinem Gefasel nicht so ganz klar: einmal nach dem Einschalten 
funktioniert das Ganze.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Timer wird nirgends gestartet. Aber mal abgesehen davon: Woher weißt 
du eigentlich, daß die Timer-ISR nicht aufgerufen wird?

Autor: concept (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,
der Timer wird vor den Codeausschnitten gestartet, und läuft mit 32kHz. 
Im Timerinterrupt schalte ich einen Pin ein und aus.

Ich habe mittlerweile das Programm komplett leergemacht, die Beschaltung 
sicherheitshalber entkoppelt, die Schaltung aus einer Batterie (3.2V) 
versorgt. Interner Takt mit 8MHz.
#include <avr/io.h>
#include <stdint.h>
#include <stdlib.h>
#include <avr/sleep.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>

ISR(TIM0_COMPA_vect)
{
  PORTB |= 1<<PB0;
  GIMSK = (1<<PCIE);
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  PORTB &= ~(1<<PB0);
}

ISR(PCINT0_vect)
{
  GIMSK &= ~(1<<PCIE);
  set_sleep_mode(SLEEP_MODE_IDLE);
} 

int main( void )
{

OSCCAL = 0x55;

PORTB = 1<<PB2;
DDRB = 1<<PB0;

ACSR = 1<<ACD;

TCCR0A = 1<<WGM01;
TCCR0B = 1 << CS00;  
OCR0A = 250;
TCCR1 = 1<<PWM1A | 1<<CS10 | 1<<COM1A1;
OCR1A = 0;

TIMSK = 1<<OCIE0A;
MCUCR = 0;
GIMSK = 1<<PCIE;
PCMSK = 1<<PCINT2;
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sei();
  for (;;)
  {
    sleep_mode();
  }
}

Nach Anlegen der Versorgung messe ich an PB0 erwartungsgemäß je einen 
High-Impuls beim Drücken/Loslassen von PB2. Das Ganze funktioniert sogar 
mehrmals hintereinander, aber irgendwann ist dann Schluß - warum?

Autor: concept (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tja, nachdem ich den AVR ausgetauscht habe (kein Unterschied) habe ich 
noch die überflüssigen Includes gelöscht - jetzt geht's. Der Impuls bei 
einem Tastendruck ist ca. 1,2µs lang.
#include <avr/io.h>
#include <stdint.h>

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

ISR(TIM0_COMPA_vect)
{
  PORTB |= 1<<PB0;
  GIMSK |= 1<<PCIE;
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  PORTB &= ~(1<<PB0);
}

ISR(PCINT0_vect)
{
  GIMSK &= ~(1<<PCIE);
  set_sleep_mode(SLEEP_MODE_IDLE);
} 

int main( void )
{

PORTB  = 1<<PB2;
DDRB   = 1<<PB0;
  
TCCR0A = 1<<WGM01;  // CTC MODE
TCCR0B = 1<<CS00;  // 8MHz
OCR0A  = 250;    // 32000Hz
  
TIMSK  = 1<<OCIE0A;

GIMSK  = 1<<PCIE;
PCMSK  = 1<<PCINT2;

set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sei();

  for (;;)
  {
    sleep_mode();
  }
}


Dann Versuch ich jetzt mal, das Programm wieder zum Laufen zu kriegen.

Autor: concept (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zu früh gefreut. Es geht ein paar (3-15) Tastendrücke, aber irgendwann 
nicht mehr.
Kann mir jemand vielleicht auf die Sprünge helfen, das Problem weiter 
einzugrenzen?

Fuses:
BOD 2.0V
Int. Osc. 8MHz + 4ms

Autor: concept (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
neuer thread, da betreff nicht mehr zutreffend:
Beitrag "Tiny45 stürzt ab trotz Minimalprogramm"

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.