attaccare interrupt al timer 0

in questo momento sto giocando con un display a 7 segmenti e 4 cifre, tralasciando che sto ancora capendo come scrivere una libreria (e non la solita accozzaglia di funzioni [1]), come potrei fare ad evitare il polling?

capisco abbastanza bene come funziona un arduino, e il resto piu o meno lo intuisco (mio malgrado assembly è utile... :sob: ) e so altrettanto bene dell ISR che attaccata al timer 0 si gestisce millis, e che non è una cosi buona idea toccarlo o toccare l'ISR stessa di millis.

avevo pensato quindi di attaccare un interrupt al compare unit del registro[2],ma non so esattamente come fare.

credo che

ISR(TIMER0_COMPx_vect)
{
/codice ISR/
}

dovrebbe funzionare, ma prima di gettarmi a scrivere il codice e scervellarmi poi a capire se l'errore è questo o io che sbaglio a settare qualche oscuro registro preferisco chiedervi conferma :smiley:

[1] è un po OT, ma se avete qualche link utile al riguardo (non la striminzita pagina di arduino.cc) ve ne sarei molto grato :grinning:

[2] con un po di matematica sono arrivato alla conclusione che millis non sfrutta l'overflow del registro, ma un interrupt sollevato dalla compare unit. per decidere quale usare per il mio progetto devo sapere prima quale viene utilizzata da millis, qualcuno sa darmi il percorso del file in cui è contenuta la funzione?

grazie delle dritte! ;D

Io ho usato TimerOne per scandire le colonne.
Poi dipende anche se usi a catodo comune oppure ad anodo.
Però è meglio se accedi direttamente alla PORTD

#include <TimerOne.h>                   // temporizzazione al 1/100 secondo

// tabella di rappresentazione dei segmenti sul display
static const uint8_t digitCodeMap[] = {
    0xc0,                               // 0                index 0
    0xf9,                               // 1                index 1
    0xa4,                               // 2                index 2
    0xb0,                               // 3                index 3
    0x99,                               // 4                index 4
    0x92,                               // 5                index 5
    0x82,                               // 6                index 6
    0xf8,                               // 7                index 7
    0x80,                               // 8                index 8
    0x90,                               // 9                index 9
    0xff,                               // BLANK            index 10
    0xbf,                               // DASH             index 11
    0x89,                               // H                index 12
    0xab,                               // n                index 13
    0xaf,                               // r                index 14
    0x40,                               // 0 dotted         index 15
    0x79,                               // 1 dotted         index 16
    0x24,                               // 2 dotted         index 17
    0x30,                               // 3 dotted         index 18
    0x19,                               // 4 dotted         index 19
    0x12,                               // 5 dotted         index 20
    0x2,                                // 6 dotted         index 21
    0x78,                               // 7 dotted         index 22
    0x0,                                // 8 dotted         index 23
    0x10,                               // 9 dotted         index 24
    0x7f,                               // BLANK dotted     index 25
    0x3f,                               // DASH dotted      index 26
    0x9,                                // H dotted         index 27
    0x2b,                               // n dotted         index 28
    0x2f                                // r dotted         index 29
    };
void timerIsr() {
    if (ticks % 2) {
        digitalWrite(11, LOW);
        digitalWrite(10, HIGH);
        PORTD = digitCodeMap[display0];
    }
    else {
        digitalWrite(10, LOW);
        digitalWrite(11, HIGH);
        PORTD = digitCodeMap[display1];
    }
    if (ticks) {
        ticks--;
    }
    else {
        ticks = 100;
        zeroX = 1;
    }
}

void setup() {

#ifdef DEBUG
   Debug.begin(57600);
   Debug.println(F("monitor attivo"));
#endif
   DDRD = 255;                         // uso completo della porta D
   PORTD = 0;                          // impostata come uscita
    Timer1.initialize(10000);           // timer1 scandisce al 1/100 di secondo
    Timer1.attachInterrupt( timerIsr ); // la routine di servizio e timerIsr
}

Nel qui caso, zeroX serve a dare il passaggio allo zero sul secondo netto. Eppoi ci sono solo 2 display. Quindi c’è una cadenza di aggiornamento ogni centesimo di secondo. Sarebbe opportuno valutare il rinfresco dei display con valori di 50~100 per il numero di display. Con 4 display credo sia meglio impostare il timer1 con un valore di 4000 o meno. Dipende da cosa si ha da fare durante quel lasso di tempo.

Se fossero di pi√Ļ allora si deve usare la PORTB e far ruotare i bit per accendere una colonna alla volta.
Ci sono delle define per le maschere delle porte in modo che si presenta nella logica voluta.
Qui viene usata la compilazione condizionale, seguendo quello dichiarato prima nello sketch.

void timerIsr()
    if (rotate < NUMCOLS) rotate++;
    else rotate = 0;
    #ifdef COL_ACTIVE_LOW
    PORTB = COLMASK;
    #else
    PORTB = 0;
    #endif
    #ifdef COMMON_ANODE
    PORTD = digitCodeMap[display[rotate]]^ ROWMASK;
    #else
    PORTD =digitCodeMap[display[rotate]];
    #endif
    #ifdef COL_ACTIVE_LOW
    bitWrite(PORTB, rotate, 0);
    #else
    bitWrite(PORTB, rotate, 1);
    #endif
}