Programació en C del PIC 16F690

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

Tres en línia electrònic

Programa del grup 4

Els quatre polsadors de l'esquerra de la part inferior serveixen per moure el cursor: esquerra, dreta, avall i amunt. L'altre polsador de la part inferior serveix per acceptar la posició.

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 boto   RA3			// Li assigna un nom a l'adreça del polsador
#define _XTAL_FREQ  4000000			// La freqüència del rellotge és 4 MHz
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
int k = 1;					// Variable que ens manté en el bucle de joc mentre sigui 1
int j;						// Variable que utilitzarem per indicar si algu ha guanyat
int Guanyador(char Ocupao[3][3]);		// Funció que ens mira la matriu 3x3 i ens comprova si
						// algu ha guanyat
char V[8]= {0,0b00000000,0,0,0b00000000,0,0,0b00000000};	// Vector on guardem les posicions
								// enceses del jugador 1 (verd)
char B[8]= {0,0b00000000,0,0,0b00000000,0,0,0b00000000}; 	// El mateix però pel jugador 2 (blau)
char Ocupao[3][3] = {{0,0,0},{0,0,0},{0,0,0}};			// Matriu que utilitzem per saber si esta
								// ocupada o no una posició i per
								// comprovar si s'ha guanyat o no
char Polsad; 					// Variable que utilitzem per assignar el valor de la
						// funció Polsador()
char torn = 2; 					// Variable que serveix per saber a quin jugador li toca
						// cada vegada
unsigned char Valor = 0b11000000;	 	// Variable que utilitzem per saber la columna en que
						// hem d'encendre els LED
unsigned char Filera =1; 			// Variable que ens situa a la filera corresponent 
char Polsador(void);    			// Funció que ens indica quin polsador BTN estem pulsant
						// retornant-nos un valor entre 1 i 5
char Estaocupat(char o[3][3],char v, char f); 	// Funció que ens retorna 1 o 0 si esta ocupada o no
						// una posició del taulell
void Ocupat( char va, char fi);			// Aquesta funció escriu el número de la casella on es
						// superposen dos fitxes, la ja col·locada i la que
						// s'esta movent
void Transcriu1( unsigned char fil, unsigned char val, char v[8], char b[8], char Sortida[6]);
						// Aquestes dos funcions dibuixen la fitxa que 
						// esta movent el jugador que li toca
void Transcriu2( unsigned char fil, unsigned char val, char v[8], char b[8], char Sortida[6]); 
void Copa(void); 				// Funció que dibuixa una copa a la matriu
						// de LED quan hi ha un guanyador
void Estatpartida(char t, char p, char q, char r[3][3]);	//Funció que guarda la posició que ens diu
						// Filera i Valor a la matriu 3x3 com a ocupat i
						// indicant el jugador
void Guarda(char x,char y, char z[8]); 		// Aquesta funció ens guarda al vector[8] la posició
						// dels LED encesos
void Envia3max(char Valor[6]);             	// Envia un joc de valors als tres MAX7221
void Ini3max(void);                        	// Inicialitza els tres MAX7221
void Apaga(void);                          	// Apaga tots els LED
void Tauler(char V[8], char B[8]);         	// Dibuixa l'estat de la partida amb les fitxes ja col·locades
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)
void main (void) {				// Programa principal
	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)
	TRISC = 0;				// Tot el port C és de sortida
	TRISB = 0;				// Tot el port B és de sortida
	TRISA = 0xFF;				// Tot el port A és d'entrada
	ANSEL = 0b00000101;			// Configura AN0 i AN2 com entrada analògica
	ANSELH = 0;				// Desactiva les altres entrades analògiques
	PORTC = 0;				// Inicialitza a 0 el port C
	PORTB = 0;				// Inicialitza a 0 el port B
	ADCON1 = 0b00010000;
	ADCON0 = 0b00001001;
	Ini3max();				// Inicialitza els tres MAX7221
	Apaga();				// Apaga tots els LED
	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 = 0b10100000;			// Activem GIE i T0IE
	j=0;
	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
	while(1){    
		_delay(500000);			// Donem temps en cas de que boto, el RA3,
						// estigui bloquejat perquè no ens dongui error
		while (boto == 1){		// Mentre no s'apreti correctament el boto RA3 estarem
						// dins el bucle
			Apaga(); 		// Apaguem la matriu LED per si carregant el programa
						// anterior se'ns ha quedat algun LED obert
			PORTC = 0b00001111;	// En les següents 4 linies fem que els LED vermells
						// facin pampallugues
			_delay(100000);		// estaran més temps encessos que apagats
			PORTC = 0b00000000;
			_delay(50000);
			Esborra();		// Esborra la pantalla i posa el cursor a l'inici
			EnviaL('P');		// Escrivim a la pantalla en sèrie LCD 'PREM START'	
			EnviaL('R');		// a la primera linia i 'PREM' i a la segona 'START'		
			EnviaL('E');				
			EnviaL('M');
			Cursor(2, 1);		// Amb Cursor fem el canvi de linia		
			EnviaL('S');				
			EnviaL('T');				
			EnviaL('A');
			EnviaL('R');
			EnviaL('T');
			_delay(800000);
			Esborra();		// Esborrem perquè faci l'efecte de pampallugues però
						// a destemps que els LED
		}
		Tauler(V,B);			// Dibuixem el taulell i la fitxa del jugador 1 en la casella 1
		Sortida[1] = Filera;		// perquè pugui començar a jugar sabent on està                           
		Sortida[3] = Filera;                               
		Sortida[5] = Filera;
		Sortida[0] = 0b00100100 | V[Filera] | B[Filera];	
		Sortida[2] = Valor | V[Filera];
		Sortida[4] = B[Filera];
		Envia3max(Sortida);        
		Sortida[1] = Filera + 1;	
		Sortida[3] = Filera + 1;
		Sortida[5] = Filera + 1;
		Sortida[0] = 0b00100100 | V[Filera] | B[Filera];	
		Sortida[2] = Valor | V[Filera];
		Sortida[4] = B[Filera];
		Envia3max(Sortida);
		while (k == 1) {
			Polsad = Polsador();	// Llegim els polsadors
			if (torn%2==0){		// Indiquem a la pantalla sèrie LCD el torn del jugador
				Esborra();	// quan la variable torn és parell juga 1 i 2 quan no
				EnviaL('J');        
				EnviaL('U');
				EnviaL('G');
				EnviaL('A');
				EnviaL('D');
				EnviaL('O');
				EnviaL('R');
				EnviaL(' ');
				EnviaL('1');
				EnviaL(' ');
				if (Estaocupat(Ocupao, Valor, Filera) == 1){
						// Si la posició de la fitxa ja està ocupada
					Cursor(2,1);		// indiquem a la pantalla LCD la posició
								// on està perquè
					EnviaL('E');		// el jugador no es confongui en
								// superposar-se les fitxes
					EnviaL('S');
					EnviaL('T');
					EnviaL('A');
					EnviaL('S');
					EnviaL(' ');
					EnviaL('A');
					EnviaL(' ');
					Ocupat(Valor, Filera);
				}
				if (Polsad == 5) {		// Es prem el botó BTN5 'OK'
					if (Estaocupat(Ocupao, Valor, Filera) == 0){
								// Comprovem si la posició està buida
						Estatpartida(torn, Valor, Filera, Ocupao);
								// Guardem a la matriu 3x3 el valor del
								// jugador 1 en aquest
								// cas com a senyal de que s'omple la posició
						Guarda(Valor,Filera,V);	// Guardem la fitxa en el vector[8]
									// amb la seva posició
						PORTC= 0b00001111;	// Encenem els LED vermells com a
									// senyal que s'ha premut correctament
						j=Guanyador(Ocupao);	// Donem valor a la variable j en cas
									// d'haver-hi un guanyador
						_delay(100000);		// Donem temps perquè tot vagi
									// correctament i no es polsi més d'una
									// vegada el BTN5
						torn = torn +1;		// Passem el torn al següent jugador
					}
				}
				if (Polsad == 4) {		// Premem BTN4
					Tauler(V,B);		// Pintem la partida tal i com estava fins
								// al moment 
					_delay(200);		// Donem temps perquè no s'apreti més d'un cop
					if(Filera ==1){		// Si la filera ja està a 1 és que ens hem,
								// passat per tant tornarem 
						Filera=10;	// a la fila 10 que al restar-li 3 a
								// continuació passarem a la fila 7 del taulell
					}
					Filera = Filera -3;	// Restant 3 a filera movem la fitxa cap amunt
					Transcriu1( Filera, Valor, V, B, Sortida);
								// Pintem la fitxa que hem desplaçat           
				}				// Aquesta funció només mou les verdes,
								// les de jugador 1
				if (Polsad == 3) {		// Premem BTN3
					Tauler(V,B);		// Les següents dos línies són igual que
								// en l'anterior
					_delay(200);
					if (Filera == 7){	// En aquest cas si arribem a 7 és que ens
								// estem a punt de sortir del taulell
						Filera = -2;	// així que el tornem a posar a -2 que al
								// sumar-li 3 ens posem a dalt de nou
					}
					Filera = Filera +3;	// Sumem 3 per anar en direcció cap aVall
					Transcriu1( Filera, Valor, V, B, Sortida);
								// Pintem la fitxa que hem desplaçat 
				}
				if (Polsad == 2) {		// Premem BTN2
					Tauler(V,B);		// Les següents dos línies són
								// igual que en l'anterior
					_delay(200);
					Valor = (Valor>>3) |(Valor<<6);
								// En aquest cas rotem els bits de la
								// variable Valor cap a la dreta
					Transcriu1( Filera, Valor, V, B, Sortida);
								// Així la fitxa que pintem sortirà
								// desplaçada a la dreta
				}
				if (Polsad == 1) {		// Premem BTN1
					Tauler(V,B);		// Les següents dos línies són igual que
								// en l'anterior
					_delay(200);
					Valor = (Valor<<3) |(Valor>>6);
								// En aquest cas rotem els bits de la variable
								// Valor cap a l'esquerra
					Transcriu1( Filera, Valor, V, B, Sortida);
								// Pintem la fitxa que hem desplaçat
				}
				if (Polsad == 0) {		// Si no s'ha premut cap polsador (o dos
								// a la vegada)
					PORTC=0b00000000;
								// Fem que els LED encesos en apretar BTN5
								// s'apaguin
					if (j==1){		// Comprovem j si al premer BTN5 la funció
								// Guanyador li ha donat algun valor
						Esborra();
						EnviaL('G');	// 1 en el cas de que guanyi el jugador 1
						EnviaL('U');	// indiquem el guanyador a la pantalla sèrie
						EnviaL('A');
						EnviaL('N');
						EnviaL('Y');
						EnviaL('A');
						EnviaL(' ');
						EnviaL('1');
						EnviaL(' ');
						Copa();		// Dibuixem la copa
						_delay(2500000);	// Donem temps abans de que es reinici
									// la partida
						k=2;		// canviem el valor de k per sortir del bucle
								// i tornar a començar
					} else if (j==2){
						Esborra();	// En el cas de guanyar el jugador 2 j
								// pren el valor 2
						EnviaL('G');	// indiquem el guanyador a la pantalla sèrie
						EnviaL('U');
						EnviaL('A');
						EnviaL('N');
						EnviaL('Y');
						EnviaL('A');
						EnviaL(' ');
						EnviaL('2');
						EnviaL(' ');
						Copa();		// Dibuixem la copa
						_delay(2500000);	// Donem temps abans de que es reinici
									// la partida
						k=2;		// canviem el valor de k per sortir del bucle
								// i tornar a començar
					} else if (torn>=11) {	// Quan torn arriba al valor 11 és que
								// el taulell està completament pintat
						Esborra();	// per tant, la partida dona empat
								// i s'ha acabat
						EnviaL('E'); 	// indiquem l'empat a la pantalla sèrie
						EnviaL('M');
						EnviaL('P');
						EnviaL('A');
						EnviaL('T');
						_delay(2500000);	// Donem temps
						k=2;		// Sortim del bucle
					}
				}
				_delay(200000);			// Retard per permetre la visualització
			} else{					// Si el torn és senar juga 2 
				Esborra();
				EnviaL('J');			// ho indiquem a la pantalla sèrie
				EnviaL('U');			// a partir d'aqui tot és el mateix que
								// en el jugador 1
				EnviaL('G');			// en aquest cas però la funció
								// Transcriu1 és Transcriu2 
				EnviaL('A');			// una funció que només mou les blaves
				EnviaL('D');
				EnviaL('O');
				EnviaL('R');
				EnviaL(' ');
				EnviaL('2');
				EnviaL(' ');
				if (Estaocupat(Ocupao, Valor, Filera) == 1){
					Cursor(2,1);
					EnviaL('E');
					EnviaL('S');
					EnviaL('T');
					EnviaL('A');
					EnviaL('S');
					EnviaL(' ');
					EnviaL('A');
					EnviaL(' ');
					Ocupat(Valor, Filera);
				}
				if (Polsad == 5) {
					if (Estaocupat(Ocupao, Valor, Filera) == 0){
						Estatpartida(torn,Valor, Filera, Ocupao);
						Guarda(Valor,Filera,B);
						PORTC= 0b00001111;
						j=Guanyador(Ocupao);
						_delay(100000);
						torn = torn +1;
					}
				}
				if (Polsad == 4) {		
					Tauler(V,B);
					_delay(200);
					if(Filera==1){
						Filera=10;
					}
					Filera = Filera -3;
					Transcriu2( Filera, Valor, V, B, Sortida);
				}
				if (Polsad == 3) {		
					Tauler(V,B);
					_delay(200);
					if (Filera == 7){
						Filera = -2;
					}
					Filera = Filera +3;
					Transcriu2( Filera, Valor, V, B, Sortida);
				}
				if (Polsad == 2) {		
					Tauler(V,B);
					_delay(200);
					Valor = (Valor>>3) |(Valor<<6);	
					Transcriu2( Filera, Valor, V, B, Sortida);
				}
				if (Polsad == 1) {		
					Tauler(V,B);
					_delay(200);
					Valor = (Valor<<3) |(Valor>>6);
					Transcriu2( Filera, Valor, V, B, Sortida);
				}
				if (Polsad == 0) {
					PORTC=0b00000000;
					if (j==1){		// Indiquem la victoria del Jugador 1 
						Esborra();	// amb la variable j que ens retorna
						EnviaL('G');	// la funció Guanyador
						EnviaL('U');
						EnviaL('A');
						EnviaL('N');
						EnviaL('Y');
						EnviaL('A');
						EnviaL(' ');
						EnviaL('1');
						EnviaL(' ');
						Copa();
						_delay(2500000);
						k=2;
					} else if (j==2){	// Indiquem la victoria del Jugador 2
						Esborra();	// amb la variable j que ens la retorna
						EnviaL('G');	// la funció Guanyador
						EnviaL('U');
						EnviaL('A');
						EnviaL('N');
						EnviaL('Y');
						EnviaL('A');
						EnviaL(' ');
						EnviaL('2');
						EnviaL(' ');
						Copa();
						_delay(2500000);
						k=2;
					} else if (torn>=11){	// Si la partida arriba a les 9 tirades
						Esborra();	// la partida no pot avançar més i per tant
						EnviaL('E');	// s'indicara a la pantalla LED que els 
						EnviaL('M');	// jugadors han empatat
						EnviaL('P');
						EnviaL('A');
						EnviaL('T');
						_delay(2500000);
						k=2;
					}  
				}
				_delay(200000);			// Retard per permetre la visualització
			}
		}
		V[0]=0;				// Al sortir del bucle de joc reinicialitzem totes les 
		V[1]=0b00000000;		// variables i el bucle while (1) torna a començar de nou 
		V[2]=0;             
		V[3]=0;
		V[4]=0b00000000;
		V[5]=0;
		V[6]=0;
		V[7]=0b00000000;
		B[0]=0;
		B[1]=0b00000000;
		B[2]=0;
		B[3]=0;
		B[4]=0b00000000;
		B[5]=0;
		B[6]=0;
		B[7]=0b00000000;
		Ocupao[0][0] = 0;
		Ocupao[0][1] = 0;
		Ocupao[0][2] = 0;
		Ocupao[1][0] = 0;
		Ocupao[1][1] = 0;
		Ocupao[1][2] = 0;
		Ocupao[2][0] = 0;
		Ocupao[2][1] = 0;
		Ocupao[2][2] = 0;
		torn = 2;
		Valor = 0b11000000;
		Filera = 1;
		k = 1;
		j = 0;
	}
}
void interrupt temporit(void) {
	INTCONbits.GIE = 0;			// Desactiva les interrupcions momentàniament
	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
		Envia3max(Sortida);		// Ho envia al MAX7221
	}
	INTCONbits.GIE = 1;			// Reactiva les interrupcions a l'acabar
}
void Envia3max(char Valor[6]) {			// Envia un joc de valors als tres MAX7221
	INTCONbits.GIE = 0;			// Desactiva les interrupcions momentàniament
	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 = Valor[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)
			}
			Valor[j] = Valor[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
	INTCONbits.GIE = 1;			// Reactiva les interrupcions a l'acabar
}
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;
	Envia3max(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;
	Envia3max(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;
	Envia3max(Bytes);			// Els envia
}
void Tauler(char V[8], char B[8]) {
	_delay(10000);
	Sortida[1] = 0x01;			// Aquesta funció ens representa
	Sortida[3] = 0x01;			// cada vegada la situació de la
	Sortida[5] = 0x01;			// partida a cada tirada
	Sortida[0] = 0b00100100 | V[1] | B[1];	// pintant el taulell i les fitxes
	Sortida[2] = V[1];			// ja col·locades
	Sortida[4] = B[1];                      
	Envia3max(Sortida);                     
	Sortida[1] = 0x02;                      
	Sortida[3] = 0x02;
	Sortida[5] = 0x02;
	Sortida[0] = 0b00100100 | V[1] | B[1];	
	Sortida[2] = V[1];	
	Sortida[4] = B[1];	
	Envia3max(Sortida);                     
	Sortida[1] = 0x03;                      
	Sortida[3] = 0x03;
	Sortida[5] = 0x03;
	Sortida[0] = 0b11111111;	
	Sortida[2] = 0b00000000;	
	Sortida[4] = 0b00000000;	
	Envia3max(Sortida);                     
	Sortida[1] = 0x04;                      
	Sortida[3] = 0x04;
	Sortida[5] = 0x04;
	Sortida[0] = 0b00100100 | V[4] | B[4];	
	Sortida[2] = V[4];
	Sortida[4] = B[4];	
	Envia3max(Sortida);                     
	Sortida[1] = 0x05;                      
	Sortida[3] = 0x05;
	Sortida[5] = 0x05;
	Sortida[0] = 0b00100100 | V[4] | B[4];	
	Sortida[2] = V[4];	
	Sortida[4] = B[4];	
	Envia3max(Sortida);                     
	Sortida[1] = 0x06;                      
	Sortida[3] = 0x06;
	Sortida[5] = 0x06;
	Sortida[0] = 0b11111111;	
	Sortida[2] = 0b00000000;	
	Sortida[4] = 0b00000000;	
	Envia3max(Sortida);		
	Sortida[1] = 0x07;		
	Sortida[3] = 0x07;
	Sortida[5] = 0x07;
	Sortida[0] = 0b00100100 | V[7] | B[7];	
	Sortida[2] = V[7];	
	Sortida[4] = B[7];	
	Envia3max(Sortida);		
	Sortida[1] = 0x08;		
	Sortida[3] = 0x08;
	Sortida[5] = 0x08;
	Sortida[0] = 0b00100100 | V[7] | B[7];	
	Sortida[2] = V[7];	
	Sortida[4] = B[7];
	Envia3max(Sortida);		
	__delay_ms(50);		
}
void Apaga(void) {				// Apaga tots els LED
	char Bytes[6];				// Els sis bytes que cal enviar
	for (int j = 0; j <= 8; j++){		// Hem d'enviar 8 fileres
		Bytes[1] = j;			// Filera
		Bytes[3] = j;
		Bytes[5] = j;
		Bytes[0] = 0x00;		
		Bytes[2] = 0x00;		
		Bytes[4] = 0x00;		
		Envia3max(Bytes);		
	}
}
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 Guarda(char x,char y, char z[8]){		// En aquesta funció guardem la posició de la fitxa
	if (x == 0b11000000){			// indicada amb Valor per les columnes i Filera per les files
		if (y == 1) z[1]= z[1] | 0b11000000;	// (x i y en aquest cas) en un vector de 8 posicions
		if (y == 4) z[4]= z[4] | 0b11000000;	// una posició per cada fila però com per
							// mourens només utilitzem
		if (y == 7) z[7]= z[7] | 0b11000000;	// les files 1, 4 i 7 així que només
							// omplirem aquestes posicions
	}						// Així doncs per cada Jugador tindrem un vector[8]
							// on hi haurà en [1],[4]i[7]
	if (x == 0b00011000){				// 0b00000000, amb 0 on estiguin apagats els LED i 
		if (y == 1) z[1]=z[1] | 0b00011000;	// un 1 on hi hagi una fitxa
		if (y == 4) z[4]=z[4] | 0b00011000;
		if (y == 7) z[7]=z[7] | 0b00011000;
	}
	if (x == 0b00000011){
		if (y == 1) z[1]=z[1] | 0b00000011;
		if (y == 4) z[4]=z[4] | 0b00000011;
		if (y == 7) z[7]=z[7] | 0b00000011;
	}
}
void Estatpartida(char t, char p, char q, char r[3][3]){	// Amb aquesta funció guardem
	if (t%2==0){						// la fitxa del jugador a la matriu 3x3
		if (p == 0b11000000){				// amb 1 o 2 diferenciant el jugador i 
			if (q == 1) r[0][0] = 1;		// que utilitzarem després per comprovar
			if (q == 4) r[1][0] = 1;		// si algu ha guanyat o no
			if (q == 7) r[2][0] = 1;
		}
		if (p == 0b00011000){
			if (q == 1) r[0][1] = 1;
			if (q == 4) r[1][1] = 1;
			if (q == 7) r[2][1] = 1;
		}
		if (p == 0b00000011){
			if (q == 1) r[0][2] = 1;
			if (q == 4) r[1][2] = 1;
			if (q == 7) r[2][2] = 1;
		}
	} else {
		if (p == 0b11000000){
			if (q == 1) r[0][0] = 2;
			if (q == 4) r[1][0] = 2;
			if (q == 7) r[2][0] = 2;
		}
		if (p == 0b00011000){
			if (q == 1) r[0][1] = 2;
			if (q == 4) r[1][1] = 2;
			if (q == 7) r[2][1] = 2;
		}
		if (p == 0b00000011){
			if (q == 1) r[0][2] = 2;
			if (q == 4) r[1][2] = 2;
			if (q == 7) r[2][2] = 2;
		}
	}
}
char Estaocupat(char o[3][3],char v, char f){		// En aquesta funció cridem
	if (v == 0b11000000){				// la matriu 3x3 que hem creat
		if (f == 1){				// i Filera i Valor per comprovar
			if (o[0][0] != 0) return 1;	// l'estat de la partida si la
				else return 0;		// casella esta ocupada o no
			}
		if (f == 4){
			if (o[1][0] != 0) return 1;
				else return 0;
			}
			if (f == 7){
				if (o[2][0] != 0) return 1;
				else return 0;
			}
		}
		if (v == 0b00011000){
		if (f == 1){
			if (o[0][1] != 0) return 1;
			else return 0;
		}
		if (f == 4){
			if (o[1][1] != 0) return 1;
			else return 0;
		}
		if (f == 7){
			if (o[2][1] != 0) return 1;
			else return 0;
		}
	}
	if (v == 0b00000011){
		if (f == 1){
			if (o[0][2] != 0) return 1;
			else return 0;
		}
		if (f == 4){
			if (o[1][2] != 0) return 1;
			else return 0;
		}
		if (f == 7){
			if (o[2][2] != 0) return 1;
			else return 0;
		}
	}
}
int Guanyador(char c[3][3]){
	if (c[0][0]==1 | c[0][0]==2){
		if (c[0][0]==c[0][1] & c[0][0]==c[0][2]){		// Cas horitzontal 1,2,3
			if (c[0][0]==1){
				return  1;
			} else{
				return 2;
			}
		}
		if (c[0][0]==c[1][0] & c[0][0]==c[2][0]){		// Cas vertical 1,4,7
			if (c[0][0]==1){
				return 1;
			} else{
				return 2;
			}
		}
	}
	if (c[1][1]==1 | c[1][1]==2){					// Pasem al mig
		if (c[1][1]==c[0][0] & c[1][1]==c[2][2]){		// Cas diagonal 1,5,9
			if (c[1][1]==1){
				return  1;
			} else{
				return 2;
			}
		}
		if (c[1][1]==c[1][0] & c[1][1]==c[1][2]){		// Cas horitzontal 4,5,6
			if (c[1][1]==1){
				return  1;
			} else{
				return 2;
			}
		}
		if (c[1][1]==c[0][1] & c[1][1]==c[2][1]){		// Cas vertical 2,5,7
			if (c[1][1]==1){
				return  1;
			} else{
				return 2;
			}
		}
		if (c[1][1]==c[0][2] & c[1][1]==c[2][0]){		// Cas diagonal 3,5,7
			if (c[1][1]==1){        
				return  1;
			} else{
				return 2;
			}
		}
		if (c[2][2]==1 | c[2][2]==2){				// Passem a baix
			if (c[2][2]==c[2][0] & c[2][2]==c[2][1]){	// Cas horitzontal 7,8,9
				if (c[2][2]==1){
					return 1;
				} else{
					return 2;
				}
			}
			if (c[2][2]==c[0][2] & c[2][2]==c[1][2]){	// Cas vertical 3,6,9
				if (c[2][2]==1){
					return 1;
				} else{
					return 2;
				}
			}
		}
		return 0;
	}
}
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
}
void Copa(void) {				// La funció serveix per dibuixar una copa
	Apaga();				// a la matriu LED un cop algu hagi guanyat
	_delay(10000);				// la partidque s'està jugant
	Sortida[1] = 0x02;              
	Sortida[3] = 0x02;
	Sortida[5] = 0x02;
	Sortida[0] = 0b01111110;        
	Sortida[2] = 0b01111110;        
	Sortida[4] = 0b00000000;        
	Envia3max(Sortida);             
	Sortida[1] = 0x03;              
	Sortida[3] = 0x03;
	Sortida[5] = 0x03;
	Sortida[0] = 0b01111110;        
	Sortida[2] = 0b01111110;       
	Sortida[4] = 0b00000000;        
	Envia3max(Sortida);            
	Sortida[1] = 0x04;              
	Sortida[3] = 0x04;
	Sortida[5] = 0x04;
	Sortida[0] = 0b00111100;        
	Sortida[2] = 0b00111100;        
	Sortida[4] = 0b00000000;        
	Envia3max(Sortida);             
	Sortida[1] = 0x05;             
	Sortida[3] = 0x05;
	Sortida[5] = 0x05;
	Sortida[0] = 0b00011000;        
	Sortida[2] = 0b00011000;        
	Sortida[4] = 0b00000000;        
	Envia3max(Sortida);             
	Sortida[1] = 0x06;             
	Sortida[3] = 0x06;
	Sortida[5] = 0x06;
	Sortida[0] = 0b00011000;        
	Sortida[2] = 0b00011000;        
	Sortida[4] = 0b00000000;        
	Envia3max(Sortida);             
	Sortida[1] = 0x07;              
	Sortida[3] = 0x07;
	Sortida[5] = 0x07;
	Sortida[0] = 0b00111100;        
	Sortida[2] = 0b00111100;       
	Sortida[4] = 0b00000000;
	Envia3max(Sortida);             
	__delay_ms(50);				// Retard de 5 milisegons teorics
}
void Transcriu1( unsigned char fil, unsigned char val, char v[8], char b[8], char Sortida[6]){
	Sortida[1] = fil;					// En aquesta funció enviem les dos files de
	Sortida[3] = fil;					// de la matriu LED on està la fitxa agafant 
	Sortida[5] = fil;					// filera i valor segons en quina fila i 
	Sortida[0] = 0b00100100 | v[fil] | b[fil];		// columna hem de pintar la fitxa 
	Sortida[2] = val | v[fil];				// que estem movent 
	Sortida[4] = b[fil];
	Envia3max(Sortida);        
	Sortida[1] = fil + 1;	
	Sortida[3] = fil + 1;
	Sortida[5] = fil + 1;
	Sortida[0] = 0b00100100 | v[fil] | b[fil];	
	Sortida[2] = val | v[fil];
	Sortida[4] = b[fil];
	Envia3max(Sortida);
}
void Transcriu2( unsigned char fil, unsigned char val, char v[8], char b[8], char Sortida[6]){
	Sortida[1] = fil;					// En aquesta funció fa el mateix que l'anterior
	Sortida[3] = fil;					// que l'anterior però pel Jugador 2
	Sortida[5] = fil;
	Sortida[0] = 0b00100100 | v[fil] | b[fil];	
	Sortida[2] = v[fil];
	Sortida[4] = val | b[fil];
	Envia3max(Sortida);        
	Sortida[1] = fil + 1;	
	Sortida[3] = fil + 1;
	Sortida[5] = fil + 1;
	Sortida[0] = 0b00100100 | v[fil] | b[fil];	
	Sortida[2] = v[fil];
	Sortida[4] = val | b[fil];
	Envia3max(Sortida);
}
void Ocupat( char va, char fi){          
	Cursor(2, 9);				// Utilitzem Cursor(2,9) per escriure sota d'on indiquem 
						// En aquesta funció enviem a la placa el número 
	if (va == 0b11000000){			// De la posició on esta la fitxa que no podem visualitzar
		if (fi == 1){			// El tauler esta numerat del 1-9 com un mòbil                   
			EnviaL('1');		// 'OCUPAT' que escrivim abans d'entrar a la funció
		}
		if (fi == 4) {            				
			EnviaL('4');
		}
		if (fi == 7) {				
			EnviaL('7');
		}
	}
	if (va == 0b00011000){
		if (fi == 1) {				
			EnviaL('2');				
		}
		if (fi == 4){				
			EnviaL('5');		
		}
		if (fi == 7){				
			EnviaL('8');
		}
	}
	if (va == 0b00000011){
		if (fi == 1){				
			EnviaL('3');
		}
		if (fi == 4){				
			EnviaL('6');
		}
		if (fi == 7) {				
			EnviaL('9');
		}
		_delay(800);   
	}
}

 

 

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