Programació en C del PIC 18F45K20

Referència Trucs Perifèrics   Recursos CITCEA
Tutorial Exemples Projectes   Inici

Exemple CP - Control amb polsador

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
	}
}

 

 

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