Ciao a tutti
Da una ISR si può saltare a eseguire un blocco di programma e poi continuare da lì?
Grazie
Gianluca
Ciao a tutti
Da una ISR si può saltare a eseguire un blocco di programma e poi continuare da lì?
Grazie
Gianluca
NO.
L'unico modo per rimuovere l'indirizzo di ritorno dallo stack è quello di tornare indietro dalla ISR. Se si salta fuori dall'ISR, il successivo ritorno nel programma principale utilizzerà l'indirizzo di ritorno più recente sullo stack e "tornerà" al punto in cui si è verificato l'interrupt, mandando in crash il programma.
Guglielmo
Quindi dalla ISR può solo tornare imprevedibilmente nel punto in cui si trovava l'esecuzione del programma nel momento in cui è arrivato l'interrupt? Non c'è modo di eseguire qualcosa subito dopo la ISR?
Nella ISR puoi chiamare una funzione, ma, alla fine della ISR, devi tornare al punto in cui eri uscito.
Nessuno ti vieta però, nella ISR, di alzare un flag che tieni costantemente sott'occhio nel loop() e che alzata indica che devi fare qualche cosa, anzi, questo è il sistema migliore; la ISR DEVE essere la più corta e veloce possibile, quindi, meno cose fai dentro la ISR e le demandi a subito dopo e meglio è.
Guglielmo
Quindi, piuttosto che mettere un po' di roba nella ISR, conviene chiamare una funzione che sarà eseguita fuori dalla ISR, dopodiché tornerà nella ISR e da lì uscirà.
Si, ma così sei SEMPRE dentro la ISR (chiami solo del codice che si trova da un'altra parte) ... come ti ho detto il sistema migliore è la flag ed il controllo al di fuori della ISR.
Guglielmo
Sto pensando alla ISR che viene chiamata da un timer alla scadere di un certo tempo: la ISR deve generare un impulso che può durare anche 200ms (se il periodo è almeno 2s, perché mantengo il duty cycle entro il 10%): se è attivo il menu, all'uscita dalla ISR il programma è bloccato. Se voglio rilevare un cambiamento del flag alzato dalla ISR devo fare un controllo continuo in ogni attimo del menu...
Quindi un primo timer che genera un impulso ed un secondo, avviato dal primo, che ne genera uno da 200 msec ... il tutto è indipendente dal software ...
Guglielmo
Altrimenti devo fare una cosa del genere, se delayMicroseconds() funziona in una ISR:
void loop()
{
if (flag==true)
{
flag=false;
// I/O 76543210
PORTD|=0b10000000;
delayMicroseconds(Ton);
PORTD&=0b01111111;
}
//...
}
Se no, posso fare un while() che controlla il tempo trascorso con micros().
Ah, ecco... Avevo paura di arrivare a questo!!!
Comincio col primo...
delayMicroseconds è limitato a 16383us, ma anche facondolo con un while interferisce col periodo, prolungandolo!
ISR(TIMER1_OVF_vect) // ISR Routine for TOV1 interrupt.
{
TCNT1 = 65511; // Ricarica il valore.
cont_overflow+=1;
if(cont_overflow==periodo)
{
cont_overflow=0;
t_shutter=micros();
PORTD|=0b10000000;
while(micros()-t_shutter<Ton);
PORTD&=0b01111111;
}
}
Va bene: va fatto anche questo con un timer!
No, basta contare gli overflow dello stesso timer... Funziona!
Ritorniamo a "Come strutturare un programma? (stroboscopio a LED da 100W)"
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.