Programació en C del PIC 16F690 amb PICkit 2

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

Exemple ST - Funcions

A l'Exemple VV tenim una part del programa que correspon a la inicialització del conversor i una altra part a la lectura de l'entrada analògica. Anem a posar aquestes parts en dues funcions. La primera funció (la d'inicialització) no tindrà cap paràmetre d'entrada ni cap valor de sortida; per tant formalment serà una funció. La de lectura del conversor no tindrà paràmetres d'entrada i donarà com a sortida el valor llegit.

Podem posar les funcions on vulguem però cal que quan les anem a fer servir estigui clar de quin tipus són; per això les declarem (sense posar-ne el contingut) després de la declaració de variables globals.

#pragma config FOSC = INTRCIO, WDTE = OFF, PWRTE = OFF, MCLRE = OFF, CP = OFF, CPD = OFF, BOREN = OFF, IESO = OFF, FCMEN = OFF
#include "pic16f690.h"				// Carrega el fitxer d'adreces i paràmetres del PIC 16F690
#define Polsador   PORTAbits.RA3		// Li assigna un nom a l'adreça del polsador
#define FiTimer0 INTCONbits.T0IF		// Li assigna un nom al bit que indica el final del Timer 0
unsigned char Valor;  				// Variable de 8 bits sense signe (0 a 255)
unsigned char Compta;  				// Variable de 8 bits sense signe (0 a 255)
bit Premut;					// Estat del polsador
bit Adreta;					// Sentit de gir
						// Definició de les funcions que farem servir 
void IniciAD (void);				// funció d'inicialització del conversor
unsigned char Analogica (void);			// Funció de lectura del conversor
void main (void)
{
						// Inicialització de variables
	Adreta = 0;				// Iniciem girant a l'esquerra
	Premut = 0;				// Suposem el polsador no premut
	Valor = 1;          			// Inicialment posem 1 (activem LED 0)
	Compta = 0;				// Compta el nombre de cops que ha acabat el Timer
						// Configuració d'entrades i sortides
	TRISC = 0b00000000; 			// Posa el port C com a sortida
	IniciAD ();				// funció d'inicialització del conversor
						// Configuració del Timer 0
	FiTimer0 = 0;       			// Aquest bit es posarà a 1 quan el temporitzador acabi
						// cal desactivar-lo des del programa
	OPTION_REG = 0b10000110;       		// Configuració de Timer0
						// Com a temporitzador basat en rellotge
						// 111 - Factor d'escala de 256
						// I resistències de pull-up desactivades (valor per defecte)
	while (1)				// Inici del bucle de programa
	{	
		Compta++;			// Incrementa Compta
		if (Compta == 30) {		// Si ha acabat setze vegades
			PORTC = Valor;		// Copiem el valor al port (als LED)
			Compta = 0;		// Reinicialitza Compta
			if (Adreta == 0) {
				Valor = (Valor << 1)|(Valor >> 7);	// Desplacem els bits a l'esquerra
				if (Valor == 16)			// Si ja estem al LED 5,
					Valor = 1;    			// tornem al LED 0
			}
			if (Adreta == 1) {
				Valor = (Valor >> 1)|(Valor << 7);	// Desplacem els bits a la dreta
				if (Valor == 128)			// Ja hem sortit fora,
					Valor = 8;    			// tornem al LED 4
			}
		}
		do				// Bucle que repetim mentre esperem que el temporitzador acabi
		{ 				// En el bucle mirem si s'ha premut el polsador i, si és així, 
						// canviem el sentit de gir
			if (Polsador == 1)	// Si el polsador no està premut (1 és no premut)
				Premut = 0;	// Memoritzem l'estat del polsador
			else if (Premut == 0)	// Si el polsador està premut però fa un moment no ho estava
			{ 
				Adreta = ~Adreta;			// Invertim el sentit de gir
				Premut = 1;	// Memoritzem el nou estat del polsador
			}
		} while (FiTimer0 == 0);	// Sortirà del bucle quan el bit es posi a 1
						// és a dir, quan Timer 0 acabi
		FiTimer0 = 0;          		// Tornem a posar el bit a zero
		TMR0 = Analogica();		// Inicialitza el Timer0
	}
}
void IniciAD (void)				// funció d'inicialització del conversor
{
	TRISAbits.TRISA0 = 1;			// La pota RA0 és d'entrada
	ANSEL = 0;				// Desactiva totes les entrades analògiques
	ANSELH = 0;	
	ANSELbits.ANS0 = 1;			// I ara activa la del potenciòmetre (AN0)
	ADCON1 = 0b00010000;			// Posa el conversor a 1/8 de la freqüència
	ADCON0 = 0b00000001;			// Activa el conversor connectat a AN0
						// amb el resultat justificat per l'esquerra
}
unsigned char Analogica (void)			// Funció de lectura del conversor
{
	ADCON0bits.GO = 1;			// Posa en marxa el conversor
	while (ADCON0bits.GO == 1)		// Mentre no acabi
		;    				// ens esperem
	return ADRESH;                    	// Retornem el resultat llegit
}

Les funcions (i altres parts del programa) poden estar en fitxers separats, de manera que estiguin ja preparats i comprovats i només calgui incloure'ls. Això permet reutilitzar fàcilment codi d'un programa a un altre.

Per exemple, les nostres funcions podrien estar en el fitxer analog.h i llavors el nostre fitxer de programa podria ser:

#pragma config FOSC = INTRCIO, WDTE = OFF, PWRTE = OFF, MCLRE = OFF, CP = OFF, CPD = OFF, BOREN = OFF, IESO = OFF, FCMEN = OFF
#include "pic16f690.h"				// Carrega el fitxer d'adreces i paràmetres del PIC 16F690
#include "analog.h"				// Carrega el fitxer de funcions del conversor AD
#define Polsador   PORTAbits.RA3		// Li assigna un nom a l'adreça del polsador
#define FiTimer0 INTCONbits.T0IF		// Li assigna un nom al bit que indica el final del Timer 0
unsigned char Valor;  				// Variable de 8 bits sense signe (0 a 255)
unsigned char Compta;  				// Variable de 8 bits sense signe (0 a 255)
bit Premut;					// Estat del polsador
bit Adreta;					// Sentit de gir
void main (void)
{
						// Inicialització de variables
	Adreta = 0;				// Iniciem girant a l'esquerra
	Premut = 0;				// Suposem el polsador no premut
	Valor = 1;          			// Inicialment posem 1 (activem LED 0)
	Compta = 0;				// Compta el nombre de cops que ha acabat el Timer
						// Configuració d'entrades i sortides
	TRISC = 0b00000000; 			// Posa el port C com a sortida
	IniciAD ();				// funció d'inicialització del conversor
						// Configuració del Timer 0
	FiTimer0 = 0;       			// Aquest bit es posarà a 1 quan el temporitzador acabi
						// cal desactivar-lo des del programa
	OPTION_REG = 0b10000110;       		// Configuració de Timer0
						// Com a temporitzador basat en rellotge
						// 111 - Factor d'escala de 256
						// I resistències de pull-up desactivades (valor per defecte)
	while (1)				// Inici del bucle de programa
	{	
		Compta++;			// Incrementa Compta
		if (Compta == 30) {		// Si ha acabat setze vegades
			PORTC = Valor;		// Copiem el valor al port (als LED)
			Compta = 0;		// Reinicialitza Compta
			if (Adreta == 0) {
				Valor = (Valor << 1)|(Valor >> 7);	// Desplacem els bits a l'esquerra
				if (Valor == 16)			// Si ja estem al LED 5,
					Valor = 1;    			// tornem al LED 0
			}
			if (Adreta == 1) {
				Valor = (Valor >> 1)|(Valor << 7);	// Desplacem els bits a la dreta
				if (Valor == 128)			// Ja hem sortit fora,
					Valor = 8;    			// tornem al LED 4
			}
		}
		do				// Bucle que repetim mentre esperem que el temporitzador acabi
		{ 				// En el bucle mirem si s'ha premut el polsador i, si és així, 
						// canviem el sentit de gir
			if (Polsador == 1)	// Si el polsador no està premut (1 és no premut)
				Premut = 0;	// Memoritzem l'estat del polsador
			else if (Premut == 0)	// Si el polsador està premut però fa un moment no ho estava
			{ 
				Adreta = ~Adreta;			// Invertim el sentit de gir
				Premut = 1;	// Memoritzem el nou estat del polsador
			}
		} while (FiTimer0 == 0);	// Sortirà del bucle quan el bit es posi a 1
						// és a dir, quan Timer 0 acabi
		FiTimer0 = 0;          		// Tornem a posar el bit a zero
		TMR0 = Analogica();		// Inicialitza el Timer0
	}
}

La instrucció #include "analog.h" llegeix les funcions. Com això es fa abans d'iniciar-se el programa, ja no cal declarar les funcions com fèiem abans.

Per crear el fitxer de funcions, anem al menú lateral i piquem sobre Source Files amb el botó dret. Allà triem New Empty File i s'obrirà una finestra per posar el nom.

El contingut del fitxer analog.h seria:

void IniciAD (void)				// funció d'inicialització del conversor
{
	TRISAbits.TRISA0 = 1;			// La pota RA0 és d'entrada
	ANSEL = 0;				// Desactiva totes les entrades analògiques
	ANSELH = 0;	
	ANSELbits.ANS0 = 1;			// I ara activa la del potenciòmetre (AN0)
	ADCON1 = 0b00010000;			// Posa el conversor a 1/8 de la freqüència
	ADCON0 = 0b00000001;			// Activa el conversor connectat a AN0
						// amb el resultat justificat per l'esquerra
}
unsigned char Analogica (void)			// Funció de lectura del conversor
{
	ADCON0bits.GO = 1;			// Posa en marxa el conversor
	while (ADCON0bits.GO == 1)		// Mentre no acabi
		;    				// ens esperem
	return ADRESH;                    	// Retornem el resultat llegit
}

 

 

Licencia de Creative Commons
Esta obra de Oriol Boix está licenciada bajo una licencia no importada Creative Commons Reconocimiento-NoComercial-SinObraDerivada 3.0.