Programació en C del PIC 16F690

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

Marcador esportiu

Programa del grup 1

En aquest cas el marcador anava destinat al futbol americà. La funció dels LED és:

1 2 3 4 Significat
X X X X Escalfament
X Primer quart
X Segon quart
X Tercer quart
X Darrer quart

La funció dels polsadors és la següent:

Polsador Funció
0 Canvi de part
1 Fa sonar l'himne
2 Selecciona l'equip
3 Suma un punt
4 Suma dos punts
5 Suma sis punts

El programa és el següent:

#pragma config FOSC = INTRCIO, WDTE = OFF, PWRTE = OFF, MCLRE = OFF, CP = OFF
#pragma config CPD = OFF, BOREN = OFF, IESO = OFF, FCMEN = OFF
#include "pic16f690.h"				// Carrega el fitxer d'adreces i paràmetres del PIC 16F690
#include <xc.h>					// Carrega el fitxer de funcions necessari per al compilador XC8
#define Polsador6 RA3			// Li assigna un nom a l'adreça del polsador de dalt
#define _XTAL_FREQ  4000000			// La freqüència del rellotge és 4 MHz
#define FiTimer1 PIR1bits.TMR1IF		// Li assigna un nom al bit que indica el final del Timer 1
char Polsad;					// Polsador que s'ha premut
unsigned char Valor;  				// Variable de 8 bits sense signe (0 a 255), pels LED
char Sortida[6];				// Valors a enviar al MAX7221 (48 bits)
char Actiu; 					// Variable que diu quin color està actiu
						// Actiu = 0		Apagat
						// Actiu = 1		Vermell
						// Actiu = 2		Verd
						// Actiu = 3		Blau
unsigned char Compta;  				// Variable de 8 bits sense signe (0 a 255)
unsigned char Compta2;				// Variable de 8 bits sense signe (0 a 255)
char nom[10] = {'0','1','2','3','4','5','6','7','8','9'};
						// Imatge logotip NFL
char verms1[8] = {0b11110000, 0b11110110, 0b11110110, 0b11111100, 
	0b00011100, 0b01111111, 0b01111111, 0b0000111}; 
char verds1[8] = {0b01100000, 0b00100110, 0b01000110, 0b01100000, 
	0b00000100, 0b01101011, 0b01101011, 0b00000000}; 
char blaus1[8] = {0b01101111, 0b00101111, 0b01001111, 0b01100011, 
	0b11100111, 0b11101011, 0b11101011, 0b11111000};
						// Imatge del número 1
char verms2[8] = {0b00000000, 0b00000000, 0b00000000, 0b00000000,
	0b00000000, 0b00000000, 0b00000000, 0b00000000}; 
char verds2[8] = {0b00011000, 0b00111000, 0b01111000, 0b11111000,
	0b00011000, 0b00011000, 0b00011000, 0b00011000}; 
char blaus2[8] = {0b00000000, 0b00000000, 0b00000000, 0b00000000,
	0b00000000, 0b00000000, 0b00000000, 0b00000000};
						// Imatge del número 2
char verms3[8] = {0b00000000, 0b00000000, 0b00000000, 0b00000000,
	0b00000000, 0b00000000, 0b00000000, 0b00000000}; 
char verds3[8] = {0b00000000, 0b01111000, 0b00000100, 0b00000100,
	0b00111000, 0b01000000, 0b01111100, 0b00000000}; 
char blaus3[8] = {0b00000000, 0b00000000, 0b00000000, 0b00000000,
	0b00000000, 0b00000000, 0b00000000, 0b00000000};  
						// Imatge del número 6
char verms4[8] = {0b00000000, 0b00000000, 0b00000000, 0b00000000,
	0b00000000, 0b00000000, 0b00000000, 0b00000000}; 
char verds4[8] = {0b00000000, 0b00111100, 0b01000000, 0b01000000,
	0b01111100, 0b01000100, 0b01111100, 0b00000000}; 
char blaus4[8] = {0b00000000, 0b00000000, 0b00000000, 0b00000000,
	0b00000000, 0b00000000, 0b00000000, 0b00000000};   
						// Definició de les funcions que farem servir
void EnviaL(char Caracter);			// Envia un caràcter
void Esborra(void);				// Esborra la pantalla i posa el cursor a l'inici
void Cursor(char Filera, char Columna);		// Posiciona el cursor
						// (filera 1 a 2 i columna 1 a 32, segons pantalla)
char Polsador(void);				// Funció de lectura dels polsadors
void Envia3max(char Val[]);			// Envia un joc de valors als tres MAX7221 desactivant interrupcions
void Envia_max(char Valor2[]);			// Envia un joc de valors als tres MAX7221
void Ini3max(void);				// Inicialitza els tres MAX7221
void Apaga(void);				// Apaga tots els LED
void TocaNota(char ValPR2, char ValCCPR1L, char ValDC1B);
void main (void) {
						// PANTALLA
	ANSEL = 0b00000101;			// Configura AN0 i AN2 com entrada analògica
	ANSELH = 0;				// Desactiva les altres entrades analògiques
	TRISC = 0b00100000;			// Configuració del port C
	TRISB = 0;				// Tot el port B és de sortida
	TXSTAbits.BRGH = 1;			// Configuració de velocitat
	BAUDCTLbits.BRG16 = 0;			// Paràmetre de velocitat de 8 bits
	SPBRG = 25;				// Velocitat de 9600 baud
	TXSTAbits.SYNC = 0;			// Comunicació asíncrona
	TXSTAbits.TX9 = 0;			// Comunicació de 8 bits
						// POLSADORS DE BAIX
	TRISA = 0xFF;				// Tot el port A és d'entrada
	ADCON1 = 0b00010000;			// Posa el conversor a 1/8 de la freqüència
	ADCON0 = 0b00001001;			// Activa el conversor A/D connectat a AN2
						// amb el resultat justificat per l'esquerra
						// MATRIU LED
	OPTION_REG = 0b10000101;	 	// Configuració de Timer0
						// Com a temporitzador basat en rellotge
						// 101 - Factor d'escala de 64
						// I resistències de pull-up desactivades (valor per defecte)
	PORTC = 0;				// Inicialitza a 0 el port C
	PORTB = 0;				// Inicialitza a 0 el port B
	Ini3max();				// Inicialitza els tres MAX7221
	Actiu = 1;				// Activa el color vermell
	TMR0 = 139;				// Presselecció de 139, que són 117 iteracions
						// Correspon a una interrupció cada 7,5 ms
	INTCON = 0b01100000;			// Activem PEIE, T0IE
						// TEMPS
	Compta = 0;				// Inicialitzem a 0 el nombre de cops que ha acabat el Timer 1
	Compta2 = 0;				// Inicialitzem a 0 el nombre de cops que ha acabat el Timer 1
						// Configuració d'entrades i sortides
						// Configuració del Timer 1
	FiTimer1 = 0;	 			// Aquest bit es posarà a 1 quan el temporitzador acabi
						// cal desactivar-lo des del programa
	T1CON = 0b00110001;	 		// Configuració de Timer1
						// Com a temporitzador basat en rellotge
						// 11 - Factor d'escala de 8
						// I resistències de pull-up desactivades (valor per defecte)
	TMR1 = 3036;				// Inicialitza el Timer1
	PIE1 = 0b00000001; 			// Habilitem la interrupció per Timer1
	INTCONbits.GIE = 1;			// Habilitem les interrupcions a nivell general
						// BRUNZIDOR
	CCP1CON = 0b00001100;			// Configura el PWM, bits P1M (bits 7-6) a 00 mode senzill
						// DC1B = 11 (bits 5-4) els dos bits de menys pes són 0
						// CCP1M = 11xx en mode senzill els bit 0 i 1 no afecten
						// Ho posa com a configuració del PWM
	CCPR1L = 49;				// Valor que correspon a un cicle del 35 % a 440 Hz
						// Registre que ens dona l'amplada de tON
	PIR1bits.TMR2IF = 0;			// Desactiva el bit d'interrupció del Timer 2
	T2CON = 0b00000011;			// Configura el Timer 2
						// bits T2KCPS (bits 1-0) a 11 prescalat de 16
						// bit 2 (TMR2ON) a 0, Timer aturat
						// Postscaler TOUTPS (bits 6-3) no afecten al PWM
						// PANTALLA
	Esborra();				// Esborra la pantalla i posa el cursor a l'inici
	EnviaL('K');
	EnviaL('C');
	Cursor(2,1);	
	EnviaL('S');
	EnviaL('F');
	Cursor(1, 4);				
	EnviaL(nom[0]);
	EnviaL(nom[0]);
	Cursor(2,4);
	EnviaL(nom[0]);
	EnviaL(nom[0]);
	Cursor(1,6);
	EnviaL('*');
	Cursor(1,12);
	EnviaL(nom[0]);
	EnviaL(nom[0]);
	EnviaL(':');
	EnviaL(nom[1]);
	EnviaL(nom[0]);
						// VARIABLES PANTALLA+POLSADOR
	int a = 0;				// Fa referència a les desenes de punts de la 2a fila
	int b = 0;				// Fa referència a les desenes de punts de la 1a fila
	int x = 0;				// Fa referència a les unitats de punts de la 2a fila
	int y = 0;				// Fa referència a les unitats de punts de la 1a fila
	int c1 = 1;				// Fa referència a quina fila es sumaran els punts.
						// Val 1 per a la 1a fila i 2 per a la 2a
						// VARIABLE POLSADOR DE DALT
	Valor = 0;			 	// Fa referència a quin/quins LED s'encenen.
						// Inicialment el posem a 0 (cap LED encès)
						// MATRIU LEDS
	Apaga();				// Apaga tots els LED
						// VARIABLES TEMPS
	char r = 0;				// Fa referència a les desenes de minut
	char s = 0;				// Fa referència a les unitats de minut
	char t = 1;				// Fa referència a les desenes de segon
	char u = 0;				// Fa referència a les unitats de minut
						// VARIABLE LOGO NFL
	char nfl = 1;				// Fa referència a si es projecta el logotip
						// de la NFL a la matriu LED o no.
						// Quan val 1 apareix el logotip, quant val 0 apareix
						// la imatge del número 1, 2 o 6,
						// depenent de quin polsador s'ha premut
	__delay_ms(100);			// Delay per garantir un bon funcionament
	while (1) {				// Mentre el contingut del parèntesi sigui 1
						// POLSADORS BAIX
		Polsad = Polsador();		// Llegim els polsadors
		if (Polsad == 5) {		// Si s'ha premut el polsador 5
						// Fem apareixer el número 6 a la matriu LED
			nfl = 0;		// No apareix el logotip a la matriu LED
			Compta2 = 0;		// Inicialitzem a 0 el nombre de cops que acabarà el Timer1
			for (int k = 0; k < 8; k++){
				Sortida[1] = k+1;		// Filera 1
				Sortida[3] = k+1;
				Sortida[5] = k+1;
				Sortida[0] = verms4[k];		// Vermells
				Sortida[2] = verds4[k];		// Verds
				Sortida[4] = blaus4[k];		// Blaus
				Envia3max(Sortida);		// Ho envia al MAX7221
				__delay_ms(1);
			}
						// Control dels punts
			if (c1 == 1) {
				y = y+6;
				if (y >= 10) {
					y = y-10;
					b = b+1;
					if (b == 10) {
						b = 0;
						y = 0;
					}
				}
				Cursor(c1,5);
				EnviaL(nom[y]);
				Cursor(c1,4);
				EnviaL(nom[b]);
			} else {
				x = x+6;
				if (x >= 10) {
					x = x-10;
					a = a+1;
					if (a == 10) {
						a = 0;
						x = 0;
					}
				}
				Cursor(c1,5);
				EnviaL(nom[x]);
				Cursor(c1,4);
				EnviaL(nom[a]);
			}
			_delay(100000);
		}
		if (Polsad == 4) {		// Si s'ha premut el polsador 4
			nfl = 0;		// No apareix el logotip a la matriu LED
			Compta2 = 0;		// Inicialitzem a 0 el nombre de cops que acabarà el Timer1
						// Fem apareixer un 2 a la matriu LED
			for (int k = 0; k < 8; k++){
				Sortida[1] = k+1;		// Filera 1
				Sortida[3] = k+1;
				Sortida[5] = k+1;
				Sortida[0] = verms3[k];		// Vermells
				Sortida[2] = verds3[k];		// Verds
				Sortida[4] = blaus3[k];		// Blaus
				Envia3max(Sortida);		// Ho envia al MAX7221
				__delay_ms(1);
			}
						// Control dels punts
			if (c1 == 1) {
				y = y+2;
				if (y >= 10) {
					y = y-10;
					b = b+1;
					if (b == 10) {
						b = 0;
						y = 0;
					}
				}
				Cursor(c1,5);
				EnviaL(nom[y]);
				Cursor(c1,4);
				EnviaL(nom[b]);
			} else {
				x = x+2;
				if (x >= 10) {
					x = x-10;
					a = a+1;
					if (a == 10) {
						a = 0;
						x = 0;
					}
				}
				Cursor(c1,5);
				EnviaL(nom[x]);
				Cursor(c1,4);
				EnviaL(nom[a]);
			}
			_delay(100000);
		}
		if (Polsad == 3) {		// Si s'ha premut el polsador 3
			nfl = 0;		// No apareix el logotip a la matriu LED
			Compta2 = 0;		// Inicialitzem a 0 el nombre de cops que acabarà el Timer1
						// Fem apareixer un 1 a la matriu LED
			for (int k = 0; k < 8; k++){
				Sortida[1] = k+1;		// Filera 1
				Sortida[3] = k+1;
				Sortida[5] = k+1;
				Sortida[0] = verms2[k];		// Vermells
				Sortida[2] = verds2[k];		// Verds
				Sortida[4] = blaus2[k];		// Blaus
				Envia3max(Sortida);		// Ho envia al MAX7221
				__delay_ms(1);
			}
						// Control dels punts
			if (c1 == 1) {
				y = y+1;
				if (y >= 10) {
					y = y-10;
					b = b+1;
					if (b == 10) {
						b = 0;
						y = 0;
					}
				}
				Cursor(c1,5);
				EnviaL(nom[y]);
				Cursor(c1,4);
				EnviaL(nom[b]);
			} else {
				x = x+1;
				if (x >= 10) {
					x = x-10;
					a = a+1;
					if (a == 10) {
						a = 0;
						x = 0;
					}
				}
				Cursor(c1,5);
				EnviaL(nom[x]);
				Cursor(c1,4);
				EnviaL(nom[a]);
			}
			_delay(100000);
		}
		if (Polsad == 2) {		// Si s'ha premut el polsador 2
						// Control de la fila on apareix l'asterisc
						// que marca a quin equip es sumaran els punts
			if (c1 == 1){
				c1 = 2;
				Cursor(1,6);
				EnviaL(' ');
				Cursor(2,6);
				EnviaL('*');
			} else {
				c1 = 1;
				Cursor(2,6);
				EnviaL(' ');
				Cursor(1,6);
				EnviaL('*');
			}
			_delay(100000);
		}
		if (Polsad == 1) {		// Si s'ha premut el polsador 1
		}
		if (Polsad == 0) {		// Si no s'ha premut cap polsador (o dos a la vegada)
		}
		if (Compta2 == 4) {	 	// Quan han passat 2 segons, deixa d'aparèixer
						// la imatge del número 1, 2 o 6
						// i torna a aparèixer el logotip
			nfl = 1;
		}
						// POLSADOR DE DALT
		if (Polsador6 == 0) {
			if (Valor == 1 || Valor == 15)		// Si ja estem al LED 1, no podem rodar més
				Valor = 8;			// tornem al LED 4
			else					// Si no estem al LED 1
				Valor = Valor/2; 		// Dividim per 2 i passem al LED següent
			PORTC = Valor;
			
						// Reinciem el temps a 15 minuts
			r = 1;
			s = 5;
			t = 0;
			u = 1;
		}
		while (Polsador6 == 0) 		// Mentre el polsador estigui premut
			;			// No fa res
		// MATRIU LED
		// Logotip NFL
		if (nfl == 1) {
			for (int k = 0; k < 8; k++){
				Sortida[1] = k+1;		// Filera 1
				Sortida[3] = k+1;
				Sortida[5] = k+1;
				Sortida[0] = verms1[k];		// Vermells
				Sortida[2] = verds1[k];		// Verds
				Sortida[4] = blaus1[k];		// Blaus
				Envia3max(Sortida);		// Ho envia al MAX7221
				__delay_ms(1);
			}
		}
						// TEMPS
						// Control de les desenes i unitats de minut i de segon
		if (Compta == 2) {		// Si ha acabat vint vegades
			if (u == 0) {
				if (t == 0) {
					if (s == 0) {
						if (r == 0) {
							r = 0;
							u = 0;
							t = 0;
							s = 0;
						} else {
							u = 9;
							t = 5;
							s = 9;
							r = r-1;
						}
					} else {
						s = s-1;
						u = 9;
						t = 5;
					}
				} else {
					t = t-1;
					u = 9;
				}
			} else {
				u = u-1;
			}
			Cursor(1,16);
			EnviaL(nom[u]);
			Cursor(1,15);
			EnviaL(nom[t]);
			Cursor(1,13);
			EnviaL(nom[s]);
			Cursor(1,12);
			EnviaL(nom[r]);
			Compta = 0;		// Reinicialitza Compta
		}
						// HIMNE
		if (Valor == 0 && r == 0 && s == 0 && t == 0 && u == 0) {
						// Si no hi ha cap LED encès i el temps està a 0
			Valor = 15;	
			PORTC = Valor;		// Encenem els quatre LED
			TocaNota(158, 79, 2); 	// Valor que correspon aproximadament a mi3
			TocaNota(189, 95, 0);
			TocaNota(238, 119, 2);
			TocaNota(189, 95, 0);
			TocaNota(158, 79, 2);
			TocaNota(118, 59, 2);
		}
	}
}		
void __interrupt() temporit(void){		// INTERRUPCIONS PEL TIMER0 I TIMER1
	INTCONbits.T0IE = 0;			// Desactiva les interrupcions momentàniament (del Timer0)
	if (PIR1bits.TMR1IF) {			// Comprovem que hi ha interrupció per Timer1
		FiTimer1 = 0;		 	// Tornem a posar el bit a zero
		TMR1 = 3036;			// Inicialitza el Timer1
		Compta++;			// Incrementa Compta 
		Compta2++;		 	// Incrementa Compta2
	}
	INTCONbits.T0IE = 1;			// Reactiva les interrupcions a l'acabar (del Timer0)
	if (INTCONbits.T0IF) {			// Comprovem que hi ha interrupció per Timer 0
		TMR0 = 139;			// Preselecció de Timer0
		INTCONbits.T0IF = 0;		// Desactiva el bit que indica interrupció pel Timer0
		if (Actiu != 0) {		// Si la matriu no està apagada
			Actiu--;		// Passem a activar un altre color
			if (Actiu == 0) {	// Si hem arribat a zero
				Actiu = 3;	// Torna a posar el 3
			}
		}
						// D'entrada els desactivem els tres
		Sortida[0] = 0x00;		// Vermell
		Sortida[2] = 0x00;		// Verd
		Sortida[4] = 0x00;		// Blau
		if (Actiu == 1) {		// Si és vermell
			Sortida[0] = 0x01;	// Vermell activat
		}
		if (Actiu == 2) {		// Si és verd
			Sortida[2] = 0x01;	// Verd activat
		}
		if (Actiu == 3) {		// Si és blau
			Sortida[4] = 0x01;	// Blau activat
		}
		Sortida[1] = 0x0C;		// Shutdown mode
		Sortida[3] = 0x0C;		// Shutdown mode
		Sortida[5] = 0x0C;		// Shutdown mode
		Envia_max(Sortida);		// Ho envia al MAX7221	 
	}
}
void EnviaL(char Caracter) {
	INTCONbits.GIE = 0;			// Desactiva les interrupcions momentàniament
	RCSTAbits.SPEN = 1;			// Activa comunicació sèrie
	TXSTAbits.TXEN = 1;			// Activa comunicació
	TXREG = Caracter;			// Agafa el caràcter i l'envia
	__delay_ms(1);				// Donem temps
	while (PIR1bits.TXIF == 0)		// Esperem que s'acabi d'enviar
		;				// No fem res
	RCSTAbits.SPEN = 0;			// Desactiva comunicació sèrie
	TXSTAbits.TXEN = 0;			// Desactiva comunicació
	INTCONbits.GIE = 1;			// Activa les interrupcions
}
void Esborra(void) {
	EnviaL(254);				// Caràcter de control
	EnviaL(1);				// Esborra la pantalla i posa el cursor a l'inici
}
void Cursor(char Filera, char Columna) {
	char Posicio = 0;			// Variable per a calcular la posició
	if (Filera == 2) {
		Posicio = 64;			// La primera columna de la segona fila és 64;
	}
	if (Columna > 0 && Columna < 33) {	// Comprovem que sigui un valor raonable
		Posicio = Posicio + Columna;	// Sumem les adreces
		Posicio = Posicio - 1;		// Restem 1 perquè numera des de 0
	}
	Posicio = Posicio + 128;		// Posa el bit de posicionat a 1
	EnviaL(254);				// Control de la posició del cursor
	EnviaL(Posicio);			// Canvia el cursor de lloc
}

						// FUNCIÓ POLSADORS BAIX
char Polsador(void) {
	char Pols = 0;
	ADCON0bits.GO = 1;			// Posa en marxa el conversor
	while (ADCON0bits.GO == 1)		// Mentre no acabi
		;    				// ens esperem
	if (ADRESH < 220 && ADRESH > 200) {
		Pols = 1;			// Comprova polsador 1
	}
	if (ADRESH < 194 && ADRESH > 174) {
		Pols = 2;			// Comprova polsador 2
	}
	if (ADRESH < 163 && ADRESH > 143) {
		Pols = 3;			// Comprova polsador 3
	}
	if (ADRESH < 90 && ADRESH > 70) {
		Pols = 4;			// Comprova polsador 4
	}
	if (ADRESH < 55 && ADRESH > 35) {
		Pols = 5;			// Comprova polsador 5
	}
	return Pols;
}
void Envia3max(char Val[]) {			// Envia un joc de valors als tres MAX7221
	INTCONbits.T0IE = 0;			// Desactiva les interrupcions momentàniament (del Timer 0)
	Envia_max(Val);
	INTCONbits.T0IE = 1;			// Reactiva les interrupcions a l'acabar (del Timer 0)
}
void Envia_max(char Valor2[]) {			// Envia un joc de valors als tres MAX7221
	char Port = 0;				// Variable on guardem l'estat del port B
	char Temp;				// Variable temporal
	for (int j = 5; j >= 0; j--){		// Hem d'enviar 6 bytes
		for (int k = 1; k < 9; k++){			// De 8 bits
			Temp = Valor2[j] & 0b10000000;		// Agafa el bit de més a l'esquerra
								// Temp només podrà valer 0 o 128
			if (Temp == 0) {			// Si val 0
				Port = Port & 0b11101111;	// Desactiva Data (bit 4)
			} else {				// Si val 128
				Port = Port | 0b00010000;	// Activa Data (bit 4)
			}
			Valor2[j] = Valor2[j] << 1;		// Rodem els bits per situar el següent
			PORTB = Port;				// Ho posa al port B
			Port = Port | 0b00100000;		// Activa Clock (bit 5) i força lectura
			PORTB = Port;				// Ho posa al port B
			Port = Port & 0b11011111;		// Desactiva Clock (bit 5)
			PORTB = Port;				// Ho posa al port B
		}
	}
	Port = Port | 0b01000000;		// Activa Latch (bit 6) per copiar a les sortides
	PORTB = Port;				// Ho posa al port B
}
void Ini3max(void) {				// Inicialitza els tres MAX7221
	char Bytes[6];				// Els sis bytes que cal enviar
	Bytes[0] = 0x00;			// Desactivat
	Bytes[1] = 0x0C;			// Shutdown mode
	Bytes[2] = 0x00;
	Bytes[3] = 0x0C;
	Bytes[4] = 0x00;
	Bytes[5] = 0x0C;
	Envia_max(Bytes);			// Els envia
	Bytes[0] = 0x00;			// No decode
	Bytes[1] = 0x09;			// Decode mode
	Bytes[2] = 0x00;
	Bytes[3] = 0x09;
	Bytes[4] = 0x00;
	Bytes[5] = 0x09;
	Envia_max(Bytes);			// Els envia
	Bytes[0] = 0x07;			// Vuit fileres
	Bytes[1] = 0x0B;			// Scan limit
	Bytes[2] = 0x07;
	Bytes[3] = 0x0B;
	Bytes[4] = 0x07;
	Bytes[5] = 0x0B;
	Envia_max(Bytes);			// Els envia
}
void Apaga(void) {				// Apaga tots els LED
	char Bytes[6];				// Els sis bytes que cal enviar
	for (int j = 1; j <= 8; j++){		// Hem d'enviar 8 fileres
		Bytes[1] = j;			// Filera
		Bytes[3] = j;
		Bytes[5] = j;
		Bytes[0] = 0x00;		// Vermells
		Bytes[2] = 0x00;		// Verds
		Bytes[4] = 0x00;		// Blaus
		Envia3max(Bytes);		// Els envia
	}
}

						// FUNCIÓ BRUNZIDOR
void TocaNota(char ValPR2, char ValCCPR1L, char ValDC1B) {
	TRISC = 0b00100000;			// Definim com volem les E/S del port C
						// RC5 (sortida del PWM), de moment, com a entrada
	PR2 = ValPR2;				// Carrega PR2
	CCP1CON = CCP1CON & 0b11001111;		// Posa a zero els bits que corresponen a DC1B
	ValDC1B = ValDC1B % 4;			// DC1B va de 0 a 3
	ValDC1B = ValDC1B * 16;			// Desplaça els bits a la posició que els correspon a CCP1CON
	CCP1CON = CCP1CON + ValDC1B;		// Coloca DC1B al seu lloc
	CCPR1L = ValCCPR1L;			// Carrega CCPR1L, registre que ens dona l'amplada de tON
	PIR1bits.TMR2IF = 0;			// Desactiva el bit d'interrupció del Timer 2
	T2CON = 0b00000111;			// Configura el Timer 2
						// bits T2KCPS (bits 1-0) a 11 prescalat de 16
						// bit 2 (TMR2ON) a 1, Timer activat
						// Postscaler TOUTPS (bits 6-3) no afecten al PWM
	while (PIR1bits.TMR2IF == 0)		// Espera l'activació del bit d'interrupció del Timer 2
		;				// Esperem
	TRISC = 0b00000000;			// Posem RC5 (sortida del PWM) com a sortida
	__delay_ms(102);	 	 	// Retard de 0,102 s
	TRISC = 0b00100000;			// Posem RC5 (sortida del PWM) com a entrada
						// O sigui, silenci
	__delay_ms(10);	 		 	// Retard de 0,01 s
}

 

 

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