Programació en C del PIC 18F45K20

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

Exemple LI - Encendre un LED de manera intermitent

Ara volem que el mateix LED estigui encès de manera intermitent. A primer cop d'ull podríem pensar en aquest programa:

#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
void main (void)				// Inici del programa principal
{
	TRISD = 0b01111111; 			// Posa el bit 7 del port D com a sortida
	while (1)				// Mentre el contingut del parèntesi sigui 1
	{					// repetim aquest bucle
		LATDbits.LATD7 = 1;		// Activa el bit 7 del port D i, per tant, encén el LED
		LATDbits.LATD7 = 0;		// Desactiva el bit 7 del port D i, per tant, apaga el LED
	}					// Fi del bucle
}						// Fi del programa

Aquest programa té dues diferències respecte a l'anterior. La primera és que després d'activar el LED (LATD7) es torna a desactivar. La segona és que ara es torna a repetir indefinidament el procés d'activació i desactivació i, per això, el bucle while inclou les dues línies (per fer-ho, emprem unes claus que engloben totes les línies que es repeteixen).

Si proveu aquest programa veureu que no fa el que esperàvem. El LED està encès tota l'estona encara que, si ens hi fixem bé, veurem que fa menys llum. Per què passa això?

Les instruccions al microcontrolador s'executen de manera molt ràpida, per això no ens dóna temps de veure-ho. Podem posar un retard després de cada instrucció per aconseguir el que volem. La funció _delay() afegeix un retard del nombre de cicles especificat dins el parèntesi. La funció _delay() està definida al fitxer <xc.h> ; per tant cal carregar-lo.

#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
void main (void)				// Inici del programa principal
{
	TRISD = 0b01111111; 			// Posa el bit 7 del port D com a sortida
	while (1)				// Mentre el contingut del parèntesi sigui 1
	{					// repetim aquest bucle
		LATDbits.LATD7 = 1;		// Activa el bit 7 del port D i, per tant, encén el LED
		_delay(50000);			// Retard de 50000 cicles
		LATDbits.LATD7 = 0;		// Desactiva el bit 7 del port D i, per tant, apaga el LED
		_delay(50000);			// Retard de 50000 cicles
	}					// Fi del bucle
}						// Fi del programa

El bucle while d'aquest programa té quatre línies. Podríem fer el mateix amb només dues si a cada bucle llegim el valor de LATD7 i l'escrivim invertit al mateix lloc. Per invertir un bit fem servir ~:

#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
void main (void)				// Inici del programa principal
{
	TRISD = 0b01111111; 			// Posa el bit 7 del port D com a sortida
	while (1)				// Mentre el contingut del parèntesi sigui 1
	{					// repetim aquest bucle
		LATDbits.LATD7=~LATDbits.LATD7;	// Inverteix el bit 7 del port D
		_delay(50000);			// Retard de 50000 cicles
	}					// Fi del bucle
}						// Fi del programa

Podeu variar el valor que poseu com a paràmetre de la funció _delay( ) per variar el temps. Per exemple amb 150000 anirà tres cops més lent. Però si proveu amb valors gaire més grans us trobareu que el compilador us dóna una errada ja que la funció no admet valors tan grans. En aquest cas, podem repetir la funció diverses vegades.

També podem indicar el temps exacte del retard, com en el següent exemple:

#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 _XTAL_FREQ  1000000			// La freqüència del rellotge és 1 MHz
void main (void)				// Inici del programa principal
{
	TRISD = 0b01111111; 			// Posa el bit 7 del port D com a sortida
	while (1)				// Mentre el contingut del parèntesi sigui 1
	{					// repetim aquest bucle
		LATDbits.LATD7=~LATDbits.LATD7;	// Inverteix el bit 7 del port D
		__delay_ms(500);		// Retard de 500 ms
	}					// Fi del bucle
}						// Fi del programa

 

 

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