A l'exemple VV hem fet servir un temporitzador per a comptar el temps però era el propi programa que estava pendent de si el temporitzador habia assolit el valor o no. El mateix passava amb el polsador. Ara farem que el temporitzador generi una interrupció quan arribi a zero. Serà a la funció d'interrupció on farem rodar els LED.
#pragma config FOSC = INTRCIO, WDTE = OFF, PWRTE = OFF, MCLRE = OFF, CP = OFF #pragma config CPD = OFF, BOREN = OFF, IESO = OFF, FCMEN = OFF #include <xc.h> // Carrega el fitxer de funcions #define Polsador RA3 // Li assigna un nom a l'adreça del polsador #define FiTimer0 INTCONbits.T0IF // Li assigna un nom al bit que indica el final del Timer 0 #define flipbit(var, bit) ((var) ^= (1<<(bit)))
unsigned char Valor; // Variable de 8 bits sense signe (0 a 255) unsigned char Compta; // Variable de 8 bits sense signe (0 a 255) char Premut; // Estat del polsador char Adreta; // Sentit de gir
// Definició de les funcions que farem servir unsigned char Analogica (void); // Funció de lectura del conversor
void main (void) {
// Inicialització de variables
Adreta = 0; // Iniciem girant a l'esquerra
Premut = 0; // Suposem el polsador no premut
Valor = 1; // Inicialment posem 1 (activem LED 0)
Compta = 0; // Compta el nombre de cops que ha acabat el Timer
// Configuració d'entrades i sortides
TRISC = 0b00000000; // Posa el port C com a sortida
TRISAbits.TRISA0 = 1; // La pota RA0 és d'entrada
ANSEL = 0; // Desactiva totes les entrades analògiques
ANSELH = 0;
ANSELbits.ANS0 = 1; // I ara activa la del potenciòmetre (AN0)
ADCON1 = 0b00010000; // Posa el conversor a 1/8 de la freqüència
ADCON0 = 0b00000001; // Activa el conversor connectat a AN0
// amb el resultat justificat per l'esquerra
// Configuració d'interrupció
INTCON = 0b00100000; // Habilitem la interrupció per Timer0
// i deshabilitem les altres
// Configuració del Timer 0
FiTimer0 = 0; // Aquest bit es posarà a 1 quan el temporitzador acabi
// cal desactivar-lo des del programa
OPTION_REG = 0b10000110; // Configuració de Timer0
// Com a temporitzador basat en rellotge
// 110 - Factor d'escala de 128
// I resistències de pull-up desactivades (valor per defecte)
INTCONbits.GIE = 1; // Habilitem les interrupcions a nivell general
while (1) // Inici del bucle de programa
{ // En el bucle mirem si s'ha premut el polsador i, si és així,
// canviem el sentit de gir
if (Polsador == 1) // Si el polsador no està premut (1 és no premut)
Premut = 0; // Memoritzem l'estat del polsador
else if (Premut == 0) // Si el polsador està premut però fa un moment no ho estava
{
flipbit(Adreta, 0); // Invertim el sentit de gir
Premut = 1; // Memoritzem el nou estat del polsador
}
}
}
unsigned char Analogica (void) // Funció de lectura del conversor
{
ADCON0bits.GO_DONE = 1; // Posa en marxa el conversor
while (ADCON0bits.GO_DONE == 1) // Mentre no acabi
; // ens esperem
return ADRESH; // Retornem el resultat llegit
}
void __interrupt() temporit(void){ // Línia alternativa
// void interrupt temporit(void){ // funció d'interrupcions
if (FiTimer0){ // Comprovem que hi ha interrupció per Timer 0
Compta++; // Incrementa Compta
if (Compta == 30) { // Si ha acabat setze vegades
PORTC = Valor; // Copiem el valor al port (als LED)
Compta = 0; // Reinicialitza Compta
if (Adreta == 0) {
Valor = (Valor << 1)|(Valor >> 7); // Desplacem els bits a l'esquerra
if (Valor == 16) // Si ja estem al LED 5,
Valor = 1; // tornem al LED 0
}
if (Adreta == 1) {
Valor = (Valor >> 1)|(Valor << 7); // Desplacem els bits a la dreta
if (Valor == 128) // Ja hem sortit fora,
Valor = 8; // tornem al LED 4
}
}
FiTimer0 = 0; // Tornem a posar el bit a zero
TMR0 = Analogica(); // Cridem a la funció de lectura del conversor i
// copiem el resultat llegit com a precàrrega del Timer
}
}

Aquesta obra d'Oriol Boix està llicenciada sota una llicència no importada Reconeixement-NoComercial-SenseObraDerivada 3.0.