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 1

Els quatre polsadors de l'esquerra de la part inferior serveixen per moure el cursor: amunt, avall, esquerra i dreta. 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 _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
char Taulell[3][3];				// Variable que representa el taulell de 9 posicions
char color[3][2];				// matriu de color verd C1 i blau C2
char i;						// Variable que representa la posició
						// i de la fitxa actual en joc al Taulell
char j;						// Variable que representa la posició
						// j de la fitxa actual en joc al Taulell
bit Torn;					// Si val 0 serà el Torn del Jugador 1,
						// si val 1 serà el torn del Jugador 2
bit Premut;
char Polsat;					// mirem si s'ha polsat algun polsador
char compta=0;
						// Definició de les funcions que farem servir
void Envia3max(char Valor[6]);                  // Envia un joc de valors als tres MAX7221
void Ini3max(void);                             // Inicialitza els tres MAX7221
void Inici(void);                               // Apaga tots els LED
char Polsador(void);
char Atrapat(void);
char Fi_joc(void);;
char Final(void);
void Apaga1(void);                              // funcio que pinta la pantalla de color verd
void Apaga2(void);                              // funcio que pinta pantalla de color vermell
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) {
	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
	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
	PORTC = 0;                              // Inicialitza a 0 el port C
	PORTB = 0;                              // Inicialitza a 0 el port B
	Torn = 0;
	i = 2;
	j = 2;
	Ini3max();                              // Inicialitza els tres MAX7221
	Inici();                                // 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
	while (1) {
		Polsat = Polsador();		// Llegim els polsadors
		if(Fi_joc() == 1){		// tres en línia i no s'ha acabat el joc
			if(Torn == 0){
				do{
					Apaga2();
				} while(1);
			}
			else if (Torn == 1){
				do{
					Apaga1();
				} while(1);
			}
		}
		if(Final()==1){			// tot el taulell ple
			for (int a = 0; a < 3; a++){
				for (int b = 0; b < 3; b++){
					if(Taulell[i][j]!=Taulell[a][b]){
						i=a;
						j=b;
						a=3;
						b=3;
					}
				}
			}
			if (Fi_joc()==3){ //taulell ple i 3 en linia
				if (Torn==0){
					do{
						Apaga1();
					} while(1);
				}
				else if(Torn==1){
					do{
						Apaga2();
					} while(1);
				}
			} else if(Fi_joc()==2){
				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
				RCSTAbits.SPEN = 1;			// Activa comunicació sèrie
				TXSTAbits.TXEN = 1;
				do{
					Esborra();
					EnviaL('E');			// Lletra
					EnviaL('M');			// Lletra
					EnviaL('P');			// Lletra
					EnviaL('A');			// Lletra
					EnviaL('T');			// Lletra
					EnviaL('E');
					_delay(10000);
				} while(1);
			}
		} else if (Atrapat() == 4){
			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
			RCSTAbits.SPEN = 1;	// Activa comunicació sèrie
			TXSTAbits.TXEN = 1;	// Activa comunicació
			Esborra();		// Esborra la pantalla i posa el cursor a l'inici
			EnviaL('P');		// Lletra
			EnviaL('1');		// Lletra
			EnviaL('-');		// Lletra
			EnviaL('T');		// Lletra
			EnviaL('O');		// Lletra
			EnviaL('-');
			EnviaL('E');		// Lletra
			EnviaL('X');		// Lletra
			EnviaL('I');
			EnviaL('T');
			Cursor(2,1);		// saltem de línia a la pantalla
			EnviaL('P');		// Lletra
			EnviaL('5');		// Lletra
			EnviaL('-');
			EnviaL('O');		// Lletra
			EnviaL('K');		// Lletra
			_delay(50000);
			do{			// Fem un bucle perqué es quedi aqui
						// mentre no es pitja cap polsador
				Polsat = Polsador();
			} while(Polsador() != 1 | Polsador() != 5);	// Condició, si es pitja el polsador 1
									// o 5 sortirà del bucle
			Esborra();
			if (Polsat == 1){	// S'hi s'ha pitjat 1, el canviarà de posició
						// a la més propera que estigui buida
				PORTC = 0b00000001;
				_delay(100000);
				PORTC = 0b00000000;
				for(int a = 0;a < 3;a++){		// bucle que recorre totes
									// les fitxes de la partida
					for (int b = 0; b<3 ;b++){
						if (Taulell[2-a][2-b] == 0){	// es comprova si
									// alguna està buida
							Taulell[i][j]=0;
							if (Torn == 0){
								Taulell[2-a][2-b] = 1;
							} else if (Torn == 1){
								Taulell[2-a][2-b] = 2;
							}
							i = 2-a;
							j = 2-b;
							a=3;
							b=3;
						} else{
							;
						}
					}
				}
			} else if(Polsat == 5){	// i s'ha pitjat el polsador 5, col·locarà
									// la fitxa en aquella casella
				compta++;
				PORTC = 0b00001111;			// i posarà la nova fitxa de l'altre
									// jugador en la primera casella buida
				_delay(100000);
				PORTC = 0b00000000;			// que trobi seguint l'ordre: comença
									// per la casella inferior dreta
				Torn = ~Torn;				// en l'ordre invers dels índexs:
									// (2,2), (2,1), (2,0), (1,2),
									// (1,1), (1,0), (0,2), (0,1) i (0,0)
				for (int a = 0; a < 3; a++){
					for (int b = 0; b < 3; b++){
						if (Taulell[2-a][2-b] == 0){
							i = 2-a;
							j = 2-b;
							a=3;
							b=3;
						} else{
							;
						}
					}
				}
				if (Torn == 0){				// si es torn dels verdes
									// posem fitxa verda
					Taulell[i][j] = 1;
				} else if(Torn == 1){			// si es torn del blaus
									// posem fitxa blava
					Taulell[i][j] = 2;
				}
			}
		} else{
			if(Polsat == 0){
				;
			} else if (Polsat == 1){
				PORTC = 0b00000001;
				_delay(100000);
				PORTC = 0b00000000;
				if( i==0 ){	// si la fitxa està a la filera 1
					if(Taulell[i+2][j] == 0){	// si la pos 13 està buida
						Taulell[i+2][j] = Taulell[i][j];	// la posem
						Taulell[i][j] = 0;	// la posició anterior la posem buida
						i = i + 2;		// actualitzem posició fitxa actual
					} else{				// si la pos 13 està ocupada
						if(Taulell[i+1][j] == 0){		// miro si pos 12
											// està buida
							Taulell[i+1][j] = Taulell[i][j];	// la posem
							Taulell[i][j] = 0;		// l'anterior la
											// posem buida
							i = i+1;	// actualitzem posició fitxa actual
						} else{
							;		// si 12 està ocupada no fem res.
						}
					}
				} else if(i==1){			// si estic a la filera 2
					if (Taulell[i-1][j] == 0){	// si la pos 11 està buida
						Taulell[i-1][j] = Taulell[i][j];	// la posem
						Taulell[i][j] = 0;	// la posició anterior la posem buida
						i = i-1;		// actualitzem posició fitxa actual
					} else{	// si la pos 11 està ocupada, miro la 13
						if(Taulell[i+1][j] == 0){			// si està buida
							Taulell[i+1][j] = Taulell[i][j];	// la posem
							Taulell[i][j] = 0;			// l'anterior la
												// posem buida
							i = i+1;	// actualitzem posició fitxa actual
						} else{	// si no està buida no fem res.
							;
						}
					}
				} else if( i==2){			// si estem a la filera 3
					if (Taulell[i-1][j] == 0){	// si la pos 12 està buida
						Taulell[i-1][j] = Taulell[i][j];	// la posem
						Taulell[i][j] = 0;	// la posició anterior la posem buida
						i = i-1;		// actualitzem posició fitxa actual
					} else{		// si la pos 12 està ocupada, mirem la 11
						if(Taulell[i-2][j] == 0){		// si està buida
							Taulell[i-2][j] = Taulell[i][j];	// la posem
							Taulell[i][j] = 0;		// l'anterior la
											// posem buida
							i = i-2;	// actualitzem posició fitxa actual
						} else{
							;		// si 2 per sota ocupada no fem res.
						}
					}
				}
			} else if(Polsat == 2){
				PORTC = 0b00000010;
				_delay(100000);
				PORTC = 0b00000000;
				if( i== 0){		// si la fitxa està a la filera 1
					if (Taulell[i+1][j] == 0){	// si la pos 12 buida
						Taulell[i+1][j] = Taulell[i][j];	// la posem
						Taulell[i][j] = 0;	// la posició anterior la posem buida
						i = i+1;		// actualitzem posició fitxa actual
					} else{		// si la pos 12 està ocupada
						if(Taulell[i+2][j] == 0){     		// si la pos 13
											// està buida
							Taulell[i+2][j] = Taulell[i][j];	// la posem
							Taulell[i][j] = 0;		// l'anterior la
											// posem buida
							i = i+2;	// actualitzem posició fitxa actual
						} else{
							;		// si 13 ocupada no fem res.
						}
					}
				} else if( i==1 ){	// si estic a la filera 2
					if (Taulell[i+1][j] == 0){	// si la pos 13 buida
						Taulell[i+1][j]= Taulell[i][j];		// la posem
						Taulell[i][j] = 0;	// la posició anterior la posem buida
						i = i+1;		// actualitzem posició fitxa actual
					} else{		// si la pos 13 està ocupada, miro la 11
						if(Taulell[i-1][j] == 0){		// si està buida
							Taulell[i-1][j] = Taulell[i][j];	// la posem
							Taulell[i][j] = 0;		// l'anterior la
											// posem buida
							i = i-1;	// actualitzem posició fitxa actual
						} else{	// si no està buida no fem res.
							;
						}
					}
				} else if (i==2){	// si estem a la filera 3
					if (Taulell[i-2][j] == 0){	// si la pos 11 està buida
						Taulell[i-2][j] = Taulell[i][j];	// la posem
						Taulell[i][j] = 0;	// la posició anterior la posem buida
						i = i - 2;		// actualitzem posició fitxa actual
					} else{		// si la pos 11 està ocupada, mirem 12 per sota
						if(Taulell[i-1][j] == 0){		// si la de 12
											// està buida
							Taulell[i-1][j] = Taulell[i][j];	// la posem
							Taulell[i][j] = 0;		// l'anterior la
											// posem buida
							i = i-1;	// actualitzem posició fitxa actual
						} else{
							;		// si 2 per sota ocupada no fem res.
						}
					}
				}
			} else if(Polsat == 3){
				PORTC = 0b00000100;
				_delay(100000);
				PORTC = 0b00000000;
				if( j==0 ){	// si estic a la columna 1
					if (Taulell[i][j+2] == 0){	// si la pos de la dreta del tot buida
						Taulell[i][j+2] = Taulell[i][j];	//la posem
						Taulell[i][j] = 0;	// la posició anterior la posem buida
						j = j + 2;		// actualitzem posició fitxa actual
					} else{	// si la pos de dreta del tot està ocupada, miro la del mig
						if(Taulell[i][j+1] == 0){		// si està buida
							Taulell[i][j+1] = Taulell[i][j];	// la posem
							Taulell[i][j] = 0;		// l'anterior la
											// posem buida
							j = j+1;	// actualitzem posició fitxa actual
						} else{			// si no està buida no fem res.
							;
						}
					}
				} else if( j==1 ){			// si estic a la columna 2
					if (Taulell[i][j-1] == 0){	// si la pos de l'esquerra buida
						Taulell[i][j-1] = Taulell[i][j];	// la posem
						Taulell[i][j] = 0;	// la posició anterior la posem buida
						j = j - 1;		// actualitzem posició fitxa actual
					} else{	// si la pos de l'esquerra està ocupada, miro la de la dreta
						if(Taulell[i][j+1] == 0){		// si està buida
							Taulell[i][j+1] = Taulell[i][j];	// la posem
							Taulell[i][j] = 0;		// l'anterior la
											// posem buida
							j = j+1;	// actualitzem posició fitxa actual
						} else{			// si no està buida no fem res.
							;
						}
					}
				} else if( j==2 ){			// si estic a la columna 3
					if (Taulell[i][j-1] == 0){	// si la pos de l'esquerra buida
						Taulell[i][j-1] = Taulell[i][j];	// la posem
						Taulell[i][j] = 0;	// la posició anterior la posem buida
						j = j-1;		// actualitzem posició fitxa actual
					} else{	// si la pos de l'esquerra està ocupada,
						// miro la de l'esquerra del tot
						if(Taulell[i][j-2] == 0){		// si està buida
							Taulell[i][j-2] = Taulell[i][j];	// la posem
							Taulell[i][j] = 0;		// l'anterior la
											// posem buida
							j = j-2;	// actualitzem posició fitxa actual
						} else{			// si no està buida no fem res.
							;
						}
					}
				}
			} else if(Polsat == 4){
				PORTC = 0b00001000;
				_delay(100000);
				PORTC = 0b00000000;
				if( j==0 ){	// si estic a la columna 1
					if (Taulell[i][j+1] == 0){	// si la pos de la dreta està buida
						Taulell[i][j+1] = Taulell[i][j];	// la posem
						Taulell[i][j] = 0;	// la posició anterior la posem buida
						j = j+1;		// actualitzem posició fitxa actual
					} else{	// si la pos de dreta està ocupada, miro la de la dreta del tot
						if(Taulell[i][j+2] == 0){		// si està buida
							Taulell[i][j+2] = Taulell[i][j];	// la posem
							Taulell[i][j] = 0;		// l'anterior la
											// posem buida
							j = j+2;	// actualitzem posició fitxa actual
						} else{			// si no està buida no fem res.
							;
						}
					}
				} else if( j==1 ){	// si estic a la columna 2
					if (Taulell[i][j+1] == 0){	// si la pos de la dreta està buida
						Taulell[i][j+1] = Taulell[i][j];	// la posem
						Taulell[i][j] = 0;	// la posició anterior la posem buida
						j = j+1;		// actualitzem posició fitxa actual
					} else{	// si la pos la dreta està ocupada, miro la de l'esquerra
						if(Taulell[i][j-1] == 0){	// si està buida
							Taulell[i][j-1] = Taulell[i][j];	// la posem
							Taulell[i][j] = 0;	// l'anterior la posem buida
							j = j-1;	// actualitzem posició fitxa actual
						} else{	// si no està buida no fem res.
							;
						}
					}
				} else if( j==2 ){	// si estic a la columna 3
					if (Taulell[i][j-2] == 0){	// si la pos de l'esquerra
									// del tot està buida
						Taulell[i][j-2] = Taulell[i][j];		// la posem
						Taulell[i][j] = 0;	// la posició anterior la posem buida
						j = j-2;		// actualitzem posició fitxa actual
					} else{		// si la pos de l'esquerra del tot està
							// ocupada, miro la del mig
						if(Taulell[i][j-1] == 0){	// si està buida
							Taulell[i][j-1] = Taulell[i][j];	// la posem
							Taulell[i][j] = 0;	// l'anterior la
										// posem buida
							j = j-1;	// actualitzem posició fitxa actual
						} else{	// si no està buida no fem res.
							;
						}
					}
				}
			} else if(Polsat == 5){		// si s'ha pitjat el polsador 5
				compta++;
				PORTC = 0b00001111;
				_delay(100000);
				PORTC = 0b00000000;
				Torn = ~Torn;
				for (int a = 0; a < 3; a++){
					for (int b = 0; b < 3; b++){
						if (Taulell[2-a][2-b] == 0){
							i = 2-a;
							j = 2-b;
							a=3;
							b=3;
						} else{
							;
						}
					}
				}
				if (Torn == 0){		// si es torn dels verdes posem fitxa verda
					Taulell[i][j] = 1;
					if(compta == 8 && Fi_joc()==3){
						do{
							Apaga2();
						} while(1);
					}
				} else{			// si es torn del blaus posem fitxa blava
					Taulell[i][j] = 2;
					if (compta==8 && Fi_joc()==3){
						do{
							Apaga1();
						} while(1);
					}
				}
			}
		}
		for (int f = 0; f < 3; f++){
			for (int c = 0; c <: 3; c++){
				int a = 3*(c+1) - 3;
				int b = 8 - a;
				if(Taulell[f][c] == 1){  // si el color és verd
					color[f][0] = color[f][0] | (0b11000000 >> a);
							// activo els bits que toquen del color verd
					color[f][1] = color[f][1] & ((0b00111111 >> a) | (0b00111111 << b));
							// apago el color blau
				} else if(Taulell[f][c] == 2){	// si el color és blau
					color[f][0] = color[f][0] & ((0b00111111 >> a) | (0b00111111 << b));
							// apago el color verd
					color[f][1] = color[f][1] | (0b11000000 >> a);
							// activo els bits que toquen del color blau
				} else{	// si està buida la posició, és a dir, LED apagats
					color[f][0] = color[f][0] & ((0b00111111 >> a) | (0b00111111 << b));
							// apago color verd
					color[f][1] = color[f][1] & ((0b00111111 >> a) | (0b00111111 << b));
							// apago color blau
				}
			}
		}
		Sortida[1] = 0x01;	// Enviem els bytes de la matriu color que correspon a l'estat dels LED
		Sortida[3] = 0x01;	// en la matriu en funció de les fitxes que hi ha col·locades al Taulell.
		Sortida[5] = 0x01;
		Sortida[0] = 0b00100100;
		Sortida[2] = color[0][0];
		Sortida[4] = color[0][1];
		Envia3max(Sortida);
		Sortida[1] = 0x02;
		Sortida[3] = 0x02;
		Sortida[5] = 0x02;
		Sortida[0] = 0b00100100;
		Sortida[2] = color[0][0];
		Sortida[4] = color[0][1];
		Envia3max(Sortida);
		Sortida[1] = 0x04;
		Sortida[3] = 0x04;
		Sortida[5] = 0x04;
		Sortida[0] = 0b00100100;
		Sortida[2] = color[1][0];
		Sortida[4] = color[1][1];
		Envia3max(Sortida);
		Sortida[1] = 0x05;
		Sortida[3] = 0x05;
		Sortida[5] = 0x05;
		Sortida[0] = 0b00100100;
		Sortida[2] = color[1][0];
		Sortida[4] = color[1][1];
		Envia3max(Sortida);
		Sortida[1] = 0x07;
		Sortida[3] = 0x07;
		Sortida[5] = 0x07;
		Sortida[0] = 0b00100100;
		Sortida[2] = color[2][0];
		Sortida[4] = color[2][1];
		Envia3max(Sortida);
		Sortida[1] = 0x08;
		Sortida[3] = 0x08;
		Sortida[5] = 0x08;
		Sortida[0] = 0b00100100;
		Sortida[2] = color[2][0];
		Sortida[4] = color[2][1];
		Envia3max(Sortida);
		_delay(1000);
		if (Fi_joc() == 0){	// no tres en línia ni empat, segueix el joc
			;
		}
	}
}
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
	}
}
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 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 d = 5; d >= 0; d--){	// Hem d'enviar 6 bytes
		for (int k = 1; k < 9; k++){		// De 8 bits
			Temp = Valor[d] & 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[d] = Valor[d] << 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
}
char Final(void){
	for(int a = 0;a < 3;a++){	// bucle que recorre totes les fitxes de la partida
		for (int b = 0; b<3 ;b++){
			if (Taulell[a][b] == 0){
				return 0;
			}
		}
	}
	return 1;
}
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 Apaga1(void) {			// ENCEN tots els LED de color verd
	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;	// Vermells
		Bytes[2] = 0b11111111;	// Verds
		Bytes[4] = 0x00;	// Blaus
		Envia3max(Bytes);	// Els envia
	}
}
void Apaga2(void) {			// ENCEN tots els LED de color blau
	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;	// Vermells
		Bytes[2] = 0x00;	// Verds
		Bytes[4] = 0b11111111;	// Blaus
		Envia3max(Bytes);	// Els envia
	}
}
void Inici(void) {			// Apaga tots els LED
	Taulell[2][2] = 1;
	char Bytes[6];			// Els sis bytes que cal enviar
	for (int r = 0; r <= 8; r++){ 	// Hem d'enviar 8 fileres
		if (r == 0){		// si és la filera 3 pintals tots de vermell
			Bytes[1] = r;	// Filera
			Bytes[3] = r;
			Bytes[5] = r;
			Bytes[0] = 0b11111111;		// Vermells
			Bytes[2] = 0b00000011;		// Verds
			Bytes[4] = 0x00;		// Blaus
			Envia3max(Bytes);
		}
		if (r == 1){		// si és la filera 3 pintals tots de vermell
			Bytes[1] = r;	// Filera
			Bytes[3] = r;
			Bytes[5] = r;
			Bytes[0] = 0b11111111;		// Vermells
			Bytes[2] = 0b00000011;		// Verds
			Bytes[4] = 0x00;		// Blaus
			Envia3max(Bytes);
		}
		if (r == 3){		// si és la filera 3 pintals tots de vermell
			Bytes[1] = r;	// Filera
			Bytes[3] = r;
			Bytes[5] = r;
			Bytes[0] = 0b11111111;		// Vermells
			Bytes[2] = 0x00;		// Verds
			Bytes[4] = 0x00;		// Blaus
			Envia3max(Bytes);
		} else if (r == 6){	// si és la filera 6 pintals tots de vermell
			Bytes[1] = r;	// Filera
			Bytes[3] = r;
			Bytes[5] = r;
			Bytes[0] = 0b11111111;		// Vermells
			Bytes[2] = 0x00;		// Verds
			Bytes[4] = 0x00;		// Blaus
			Envia3max(Bytes);
		} else if (r==7){	// inicialment apareix fitxa verda avall dreta
			Bytes[1] = r;	// Filera
			Bytes[3] = r;
			Bytes[5] = r;
			Bytes[0] = 0b00100100;		// Vermells
			Bytes[2] = 0b00000011;		// Verds
			Bytes[4] = 0x00;		// Blaus
			Envia3max(Bytes);
		} else if (r==8){	// inicialment apareix fitxa verda avall dreta
			Bytes[1] = r;	// Filera
			Bytes[3] = r;
			Bytes[5] = r;
			Bytes[0] = 0b00100100;		// Vermells
			Bytes[2] = 0b00000011;		// Verds
			Bytes[4] = 0x00;		// Blaus
			Envia3max(Bytes);
		} else{			// si és cap filera de les altres
			Bytes[1] = r;	// Filera
			Bytes[3] = r;
			Bytes[5] = r;
			Bytes[0] = 0b00100100;		// Vermells
			Bytes[2] = 0x00;		// Verds
			Bytes[4] = 0x00;		// Blaus
			Envia3max(Bytes);
		}
	}
}
char Polsador(void) {			//detecta quin pulsador està premut
	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;
}
char Atrapat(void){			// detecta si alguna de les fitxes esta atrapada en el taulell
	unsigned char compta = 0;	// si aquest comptador arriba 4, la fitxa estarà atrapada (2 posicions
	for (int b = 0;b < 3;b++){	// ocupades de la seva filera i 2 més de la seva columna).
		if (b!=j){		// Miro les posicions de la filera
			if (Taulell[i][b] != 0){
				compta++;		// si està ocupada sumo 1 a compta
			}
		}
		if (b!=i){		// Miro les posicions de la columna
			if (Taulell[b][j] != 0){
				compta++;		// si està ocupada sumo 1 a compta
			}
		}
	}
	return compta;			// retorno compta
}
char Fi_joc(){	// funcio que detecta en quin moment de la partida ens trobem
	unsigned char compta;
	compta = 0;
	for(int a=0;a<3;a++){
		if(Taulell[a][0] == Taulell[a][1] && Taulell[a][1] == Taulell[a][2] && Taulell[a][0] != 0 && compta == 0 && a!=i){
			compta++;	// Si hi ha tres en línia  en fileres sumo 1 a compta
		} else if(Taulell[0][a] == Taulell[1][a] && Taulell[1][a] == Taulell[2][a] && Taulell[0][a] != 0 && compta == 0 && a!=j){
			compta++;	// si hi ha tres en línia en columna sumo 1 a compta
		}
	}
	if(Taulell[0][0] == Taulell[1][1] && Taulell[1][1]== Taulell[2][2] && Taulell[0][0] != 0 && compta ==0 && i!=j){
		compta++;		// Si hi ha tres en línia en una diagonal sumo 1 a compta
	} else if(Taulell[2][0] == Taulell[1][1] && Taulell[1][1] == Taulell[0][2] && Taulell[2][0] != 0 && compta == 0){
		if (i == 1 && j == 1){
			;
		} else if(i==0 && j == 2){
			;
		} else if(i == 2 && j == 0){
			;
		} else{
			compta++;	// si hi ha tres en línia en l'altra diagonal sumo 1 a compta
		}
	} else{
		compta = compta;	// si no hi ha 3 en línia no sumis res a compta
		//Taules (empat)!!
	}
	for (int a=0; a<3; a++){	// recorrem taulell per veure estat de la matriu
		for (int b=0; b<3; b++){
			if (Taulell[a][b] == 0){
				return compta;
			} else if(Taulell[a][b] != 0){
				;
			}
		}
	}
	compta=compta+2;
	return compta;
}

 

 

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