En aquest programa farem que els LED mostrin un número binari que es va incrementant de 0 a 255 i torna a començar. Cada cop que es premi el polsador de la placa s'activarà una interrupció que incrementarà la velocitat de l'oscil·lador i així podrem veure com canvia la velocitat. Quan arribem al màxim de velocitat, tornarem al mínim.
Per eliminar els rebots del polsador necessitem un retard com a l'exemple IT però la funció _delay() no admet paràmetres variables i si la freqüència és diferent també hauria de ser-ho el retard. Per això aquí el retard el farem decrementant una variable.
Per a freqüències fins a 16 MHz, el valor que hem de posar als bits IRCF coincideix amb el número d'ordre de la freqüència. Com els bits IRCF corresponen a les posicions 4 a 6 de OSCCON i els altres bits els volem a zero, posarem a OSCCON el valor que correspondria a IRCF multiplicat per 16. Per als dos darrers valors, cal fer-ho diferent.
Només tindrem una interrupció (polsador), per tant no ens calen dos nivells. El programa que emprarem serà:
#pragma config FOSC = INTIO67, FCMEN = OFF, IESO = OFF // CONFIG1H #pragma config PWRT = OFF, BOREN = SBORDIS, BORV = 30 // CONFIG2L #pragma config WDTEN = OFF, WDTPS = 32768 // CONFIG2H #pragma config MCLRE = OFF, LPT1OSC = OFF, PBADEN = ON, CCP2MX = PORTC // CONFIG3H #pragma config STVREN = ON, LVP = OFF, XINST = OFF // CONFIG4L #pragma config CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF // CONFIG5L #pragma config CPB = OFF, CPD = OFF // CONFIG5H #pragma config WRT0 = OFF, WRT1 = OFF, WRT2 = OFF, WRT3 = OFF // CONFIG6L #pragma config WRTB = OFF, WRTC = OFF, WRTD = OFF // CONFIG6H #pragma config EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF, EBTR3 = OFF // CONFIG7L #pragma config EBTRB = OFF // CONFIG7H #include "p18f45k20.h" // Carrega el fitxer d'adreces i paràmetres del PIC 18F45K20 #include <xc.h> // Carrega el fitxer de funcions
unsigned char Valor; // Variable de 8 bits sense signe per als LED unsigned char Freq; // Variable que indica a quina freqüència treballem // 0 equival a 31 kHz i 9 equival a 64 MHz unsigned long Cicles; // A cada freqüència, el valor del retard del polsador és diferent
void main (void)
{
TRISD = 0b00000000; // El port D és de sortida
ANSEL = 0; // Desactiva totes les entrades analògiques
ANSELH = 0;
INTCON2bits.RBPU = 0; // Habilita el control de resistències de pull-up al port B
WPUBbits.WPUB0 = 1; // Activa la resistència de pull-up a RB0
TRISBbits.TRISB0 = 1; // RB0 és entrada
// Configuració d'interrupció a INT0 (RB0)
INTCON2bits.INTEDG0 = 0; // Interrupció quan es desactiva (quan es prem el polsador)
// INT0 sempre és de prioritat alta, no cal definir-ho
INTCONbits.INT0IF = 0; // Inicialitzem amb el bit de control desactivat
INTCONbits.INT0IE = 1; // Habilitem la interrupció INT0
RCONbits.IPEN = 0; // Només un nivell d'interrupció
INTCONbits.PEIE = 1; // Permet les interrupcions de perifèrics
INTCONbits.GIE = 1; // Permet les interrupcions globalment
Freq = 0; // Comencem a la freqüència més baixa
Cicles = 1; // Cicles de _delay()
Valor = 0; // Inicialitza la variable a zero
while (1) // Bucle infinit
{
LATD = ++Valor; // Incrementem el valor i el copiem als LED
_delay(50000); // Retard per permetre la visualització
}
}
void interrupt polsador(void) // funció d'interrupcions
{
unsigned int i; // Variable per comptar el retard
if (INTCONbits.INT0IF) // Comprovem que hi ha interrupció per INT0
{
i = 63 * Cicles; // Càlcul del número d'iteracions per al retard del polsador
while(i)
{
i--;
}
INTCONbits.INT0IF = 0; // Desactivem el bit que indica la interrupció
if (PORTBbits.RB0 == 0) // Si el polsador encara està premut
{
Freq++; // Incrementem la freqüència
Cicles = 2 * Cicles; // El doble de cicles per aconseguir el mateix temps
if (Freq == 10) // Si hem passat del màxim valor
{
Freq = 0; // tornem al primer
Cicles = 1; // Nombre d'iteracions que cal fer per al retard del polsador
}
if (Freq > 7) // Si hem passat del màxim valor
{
OSCTUNEbits.PLLEN = 1; // Activa multiplicació per 4
OSCCON = 16*(Freq-2); // Posa la freqüència que correspon
// i desactiva els altres bits
}
else
{
OSCTUNEbits.PLLEN = 0; // Desactiva multiplicació per 4
OSCCON = 16*Freq; // Posa la freqüència que correspon
// i desactiva els altres bits
}
}
}
}

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