Programació en C del PIC 18F45K20

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

Exemple OR - Oscil·lador del rellotge

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

 

 

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