En aquest exemple partirem de l'exemple RL i farem que la rotació de LED avanci cada cop que es premi el polsador. Recordem que el polsador manté activada l'entrada RB0 i l'entrada es desactiva quan el premem. El programa per fer-ho és el següent:
#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 #define Polsador PORTBbits.RB0 // Li assigna un nom a l'adreça del polsador
unsigned char Valor; // Variable de 8 bits sense signe (0 a 255)
void main (void)
{
TRISD = 0b00000000; // El port D és de sortida
ANSELH = 0x00; // Les entrades AN8-12 són digitals (AN12 coincideix amb RB0)
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
Valor = 1; // Inicialment posem 1 (activem LED 0)
while (1) // Bucle infinit
{
LATD = Valor; // Copiem el valor al port (als LED)
if (Valor == 128) // Si ja estem al LED 7, no podem rodar més
Valor = 1; // tornem al LED 0
else // Si no estem al LED 7
Valor = 2*Valor; // Multipliquem per 2 i passem al LED següent
while (Polsador == 1) // Mentre el polsador no estigui premut
; // No fa res
}
}
Observem que on hi havia la funció de retard hi hem posat un bucle que es queda bloquejat fins que es prem el polsador.
Si heu provat aquest programa, haureu vist que no funciona. Mentre el polsador està premut es produeix la rotació de bits i quan el deixem anar es para.
A la versió següent, esperem a que el polsador es deixi anar:
#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 #define Polsador PORTBbits.RB0 // Li assigna un nom a l'adreça del polsador
unsigned char Valor; // Variable de 8 bits sense signe (0 a 255)
void main (void)
{
TRISD = 0b00000000; // El port D és de sortida
ANSELH = 0x00; // Les entrades AN8-12 són digitals (AN12 coincideix amb RB0)
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
Valor = 1; // Inicialment posem 1 (activem LED 0)
while (1) // Bucle infinit
{
LATD = Valor; // Copiem el valor al port (als LED)
if (Valor == 128) // Si ja estem al LED 7, no podem rodar més
Valor = 1; // tornem al LED 0
else // Si no estem al LED 7
Valor = 2*Valor; // Multipliquem per 2 i passem al LED següent
while (Polsador == 1) // Mentre el polsador no estigui premut
; // No fa res
while (Polsador == 0) // Mentre el polsador estigui premut
; // No fa res
}
}
Ara funciona millor però no funciona bé ja que de tant en tant se salta un o dos LED. Els polsadors i els interruptors tenen el problema que quan canvien d'estat els contactes reboten i, per això, sovint el microcontrolador no veu només una activació entrada sinó unes quantes. En el nostre cas, el polsador de la placa és força bo i rebota molt poc.
El que cal fer és assegurar-nos que l'estat és estable. El programa que es proposa ara incorpora un filtre per no veure els rebots del polsador.
#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 #define Polsador PORTBbits.RB0 // Li assigna un nom a l'adreça del polsador
unsigned char Valor; // Variable de 8 bits sense signe (0 a 255)
void main (void)
{
TRISD = 0b00000000; // El port D és de sortida
ANSELH = 0x00; // Les entrades AN8-12 són digitals (AN12 coincideix amb RB0)
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
Valor = 1; // Inicialment posem 1 (activem LED 0)
while (1) // Bucle infinit
{
unsigned char Compta = 0; // Variable local per comptar
LATD = Valor; // Copiem el valor al port (als LED)
if (Valor == 128) // Si ja estem al LED 7, no podem rodar més
Valor = 1; // tornem al LED 0
else // Si no estem al LED 7
Valor = 2*Valor; // Multipliquem per 2 i passem al LED següent
while (Polsador == 0); // Esperem a que el polsador es deixi anar
; // No fem res
do
{ // Bucle per comptar quants cops detectem el polsador premut
if (Polsador == 0) // Si el polsador està premut
Compta++; // Incrementa Compta
else // Si no està premut
Compta = 0; // Posa el comptador zero
_delay(250); // Retard de 250 cicles
} while (Compta < 5); // Es repeteix fins que hem comptat 5 cops
}
}
En el programa següent hem desactivat les entrades analògiques amb el bit de configuració PBADEN i ens estalviem de fer servir el registre ANSELH.
#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 #define Polsador PORTBbits.RB0 // Li assigna un nom a l'adreça del polsador
unsigned char Valor; // Variable de 8 bits sense signe (0 a 255)
void main (void)
{
TRISD = 0b00000000; // El port D és de sortida
// Les entrades AN8-12 són digitals per configuració
// (AN12 coincideix amb RB0)
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
Valor = 1; // Inicialment posem 1 (activem LED 0)
while (1) // Bucle infinit
{
unsigned char Compta = 0; // Variable local per comptar
LATD = Valor; // Copiem el valor al port (als LED)
if (Valor == 128) // Si ja estem al LED 7, no podem rodar més
Valor = 1; // tornem al LED 0
else // Si no estem al LED 7
Valor = 2*Valor; // Multipliquem per 2 i passem al LED següent
while (Polsador == 0); // Esperem a que el polsador es deixi anar
; // No fem res
do
{ // Bucle per comptar quants cops detectem el polsador premut
if (Polsador == 0) // Si el polsador està premut
Compta++; // Incrementa Compta
else // Si no està premut
Compta = 0; // Posa el comptador zero
_delay(250); // Retard de 250 cicles
} while (Compta < 5); // Es repeteix fins que hem comptat 5 cops
}
}

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