En aquest cas hi ha un jugador que intenta enfonsar els vaixells que ha situat la màquina. La posició dels vaixells es determina aleatòriament per a cada partida. Hi ha set vaixells:
| Mida | Nombre de vaixells |
| 4 caselles | 1 |
| 3 caselles | 1 |
| 2 caselles | 2 |
| 1 casella | 3 |
Els colors dels LED de la matriu representen:
| Color | Significat |
| Apagat | Casella sobre la que no s'ha disparat |
| Blau | Aigua |
| Groc | Tocat |
| Vermell | Enfonsat |
| Verd | Posició del cursor |
Els polsadors de la part inferior serveixen per moure el cursor i per disparar sobre la casella actual, segons el següent ordre:
| Polsador | Funció |
| 1 | Esquerra |
| 2 | Dreta |
| 3 | Amunt |
| 4 | Avall |
| 5 | Disparar |
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 <xc.h> // Carrega el fitxer de funcions necessari per al compilador XC8 #include <stdlib.h> #define _XTAL_FREQ 4000000 // La freqüència del rellotge és 4 MHz #define cic_int 5 // Nombre de cicles per a la intermitència #define setbit(var, bit) ((var) |= (1 << (bit))) #define testbit(var, bit) ((var) & (1 <<(bit)))
char d=0; // 0 és Vaixell vertical
char Port; // Gestió del port a la funció Envia_max
char Compta; // Comptador de bits a la funció Envia_max
char Sortida[6]; // Valors a enviar al MAX7221 (48 bits)
char Sorti[6]; // Valors a enviar al MAX7221 des de la interrupció
char Actiu; // Variable que diu quin color està actiu:
// Actiu = 0 Apagat
// Actiu = 1 Vermell
// Actiu = 2 Verd
// Actiu = 3 Blau
char Polsad; // Polsador que s'ha premut
char x = 0; // Coordenada X del cursor (0 a 7)
// X = 0 és la columna de la dreta
char y = 0; // Coordenada Y del cursor (0 a 7)
char mirar = 1; // Espera que es deixi anar el polsador
char compt_int = 0; // Comptador de cicles per a la intermitència
char cur_on = 1; // Controla l'estat del cursor
unsigned short adressa; // Variable de 16 bits per a l'adreça
char Vaixells[7][4] = {{0,0,0,1},{0,0,0,1},{0,0,0,1},{0,0,0,2},
{0,0,0,2},{0,0,0,3},{0,0,0,4}}; // Posició dels vaixells
char Barquitos[8][8]={0}; // Matriu 8x8 que representa el mapa dels vaixells
// Cada posició és 0b00000000,
// Bit [0]: 1 si el color ences es VERMELL
// Bit [1]: 1 si el color ences es GROC
// Bit [2]: 1 si el color ences es BLAU
// Bit [3]: 1 si hi ha algun color ENCÈS
// 0 si no hi ha cap encès (no s'ha disparat)
// Bit [4]: 1 si la posició és AIGUA
// Bit [5]: 1 si la posicio és VAIXELL
// Bit [6]: 1 si la posició és VOLTANT DE VAIXELL
void Envia3max(char Valor[]); // Envia un joc de valors als tres MAX7221
void Envia_max(void); // Envia un joc de valors als tres MAX7221
void Ini3max(void); // Inicialitza els tres MAX7221
void Apaga(void); // Apaga tots els LED
char Polsador(void); // Funció de lectura dels polsadors
int figura2(int x, int y); // Traducció als codis de colors
void TocaNota(char ValPR2, char ValCCPR1L, char ValDC1B); // Funció per fer sonar el brunzidor
void EnviaL(char Caracter); // Envia un caràcter a la pantall de text
void Esborra(void); // Esborra la pantalla i posa el cursor a l'inici
void Creabarcos(void);
void Cursor(char Filera, char Columna); // Posiciona el cursor de la pantalla de text
// Filera d'1 a 2
// Columna d'1 a 32
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
PORTC = 0; // Inicialitza a 0 el port C
PORTB = 0; // Inicialitza a 0 el port B
ADCON1 = 0b00010000; // Posa el conversor a 1/8 de la freqüència
ADCON0 = 0b00001001; // Activa el conversor A/D connectat a AN2
CCP1CON = 0b00001100; // Configura el PWM, bits P1M (bits 7-6) a 00 mode senzill
PIR1bits.TMR2IF = 0; // Desactiva el bit d'interrupció del Timer 2
T2CON = 0b00000011; // Configura el Timer 2
Ini3max(); // Inicialitza els tres MAX7221
Actiu = 1; // Activa el color vermell
TMR0 = 100; // Presselecció de 100, que són 156 iteracions
// Correspon a una interrupció cada 7,5 ms
INTCON = 0b10100000; // Activem GIE i T0IE
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){ // Bucle infinit pel joc
//----------- MENÚ PRINCIPAL -----------
for (signed char j=7;j>=0;j--){ // Posem matriu tota de aigua
for (signed char i=7;i>=0;i--){
Barquitos[i][j]=16;
}
}
char fin=0; // Cambiara a 1 quan s'acabi la partida
char Tirs=40; // Núm. de tirs permesos
char contavaixells=0; // Núm. de vaixelles enfonsats
char a=0;
Esborra(); // Esborra la pantalla i posa el cursor a l'inici
Apaga(); // Apaga tots els LED
EnviaL('T');
EnviaL('R');
EnviaL('I');
EnviaL('A');
Cursor(1,6);
EnviaL('U');
EnviaL('N');
Cursor(1,9);
EnviaL('N');
EnviaL('I');
EnviaL('V');
EnviaL('E');
EnviaL('L');
EnviaL('L');
while (a==0){ // Ens quedem esperant i llegint els polsadors fins que es prem algun
Polsad=Polsador();
if (Polsad==1){ // Si es prem algun...
a=1; // ... surt del bucle...
Tirs=45;
} else if (Polsad==2){
a=1;
Tirs=40;
} else if (Polsad==3){
a=1;
Tirs=35;
}
}
srand(TMR0); // ... i crea la llavor de nombres aleatoris
Esborra(); // Esborra la pantalla i posa el cursor a l'inici
//----------- VAIXELLS ALEATORIS -----------
char index=6; // Per les posicions en Vaixells[][]
for (unsigned char k = 4; k > 0; k--){ // k = llargaria del vaixell
char f=0;
char w=1;
while (f<=4){
char z=0; // Bucle
w++;
f=k+w;
while (z==0){ // Fins que el vaixell no es col.loqui correctament
char p=0; // Contador a 0
char d=rand()%2; // 0 Vertical, 1 horizontall (aleatori)
char m=1-d;
char xo=rand()%(9-k*d-1*(1-d)); // Columna aleatoria
char yo=rand()%(9-k*(1-d)-1*d); // Fila aleatoria
// (xo,yo)
for (signed char j = (k-1); j >= 0; j--){ // Per cada posició del vaixell
if (Barquitos[yo+j*m][xo+j*d] != 16) // Si posicio vaixell incorrecta...
p++; // ...p deixa de ser 0
}
if (p==0){ // Si la posicio (xo, yo) escollida es corecte
char arriba=1; // -> Sera 0 quan estigui adalt
char abajo=1; // -> Sera 0 quan estigui abaix
char izquierda=1; // -> Sera 0 quan estigui a l'esquerra
char derecha=1; // -> Sera 0 quan estigui a la dreta
if (xo==0)
izquierda=0;
if (xo==(8-k)*d+7*m)
derecha=0; // A l'hora de determinar els voltants del vaixell, necessitem diferenciar
if (yo==0) // els casos de les cantonades de la matriu de LED
arriba=0;
if (yo==(8-k)*m+7*d)
abajo=0;
char ad=arriba*derecha;
char ai=arriba*izquierda;
char abd=abajo*derecha;
char abiz=abajo*izquierda;
for (signed char j = (k-1); j >= 0; j--){
// Canvien valor a 64 (Voltant de vaixell)...
Barquitos[yo-1*arriba*d+j*derecha*m][xo+j*arriba*d+1*derecha*m]=64;
// ...la part de dalt i...
Barquitos[yo+1*abajo*d+j*izquierda*m][xo+j*abajo*d-1*izquierda*m]=64;
// ... la part de baix. (Sempre ques es pugui)
}
// Ara hem de posar a 64 els casos de les cantonades i els laterals (sempre que sigui posible):
Barquitos[yo-1*ad*d+k*abd*m][xo+k*ad*d+1*abd*m]=64; // A dalt a la dreta
Barquitos[yo-1*ai*d+k*abiz*m][xo-1*ai*d-1*abiz*m]=64; // A dalt a l'esquerra
Barquitos[yo+1*abiz*d-1*ad*m][xo-1*abiz*d+1*ad*m]=64; // A baix a l'esquerra
Barquitos[yo+1*abd*d-1*ai*m][xo+k*abd*d-1*ai*m]=64; // A baix a la dreta
Barquitos[yo-1*arriba*m][xo+k*derecha*d]=64; // Dreta
Barquitos[yo+k*abajo*m][xo-1*izquierda*d]=64; // Esquerra
for (signed char j = (k-1); j >= 0; j--){ // Cambiem el valor a 32 en les caselles
// que ocupa el vaixell
Barquitos[yo+j*m][xo+j*d]=32;
}
z=1; // Surtim del bucle perque la posicio (xo, yo) es correcte
Vaixells[index][0]=xo; // Apuntem la xo del vaixell
Vaixells[index][1]=yo; // Apuntem la yo del vaixell
Vaixells[index][2]=d; // Apuntem si es vertical o horitzontal
index--;
}
}
}
}
//----------- POLSADORS -----------
while (fin==0) { // Mentre la partida no s'acabi
// Mirem els polsadors
// Un cop s'ha fet l'acció del polsador, no es tornarà
// a fer fins que es detecti que s'han deixat anar
Polsad = Polsador(); // Llegim els polsadors
if (mirar == 1){
if (Polsad == 1) { // Si s'ha premut el polsador 1 // ESQUERRA
x = (x + 1) % 8; // Incrementa x però la manté entre 0 i 7
mirar = 0;
}
if (Polsad == 2) { // Si s'ha premut el polsador 2 // DRETA
x = (x - 1) % 8; // Disminuiex x però la manté entre 0 i 7 Dreta
mirar = 0;
}
if (Polsad == 3) { // Si s'ha premut el polsador 3 // AMUNT
y = (y - 1) % 8; // Disminuiex x però la manté entre 0 i 7 Dreta
mirar = 0;
}
if (Polsad == 4) { // Si s'ha premut el polsador 4 // AVALL
y = (y + 1) % 8; // Disminuiex x però la manté entre 0 i 7 Dreta
mirar = 0;
}
if ((Polsad == 5) && (testbit(Barquitos[y][x], 3)==0)){ // Si s'ha premut el polsador 5 y LED apagat
// DISPARAR
Tirs--;
if ((testbit(Barquitos[y][x], 4)!=0) || (testbit(Barquitos[y][x], 6)!=0)){ // Si es AIGUA
setbit(Barquitos[y][x],2); // Pintem de BLAU ------> AIGUA
setbit(Barquitos[y][x],3); // Marca LED com a ences
TocaNota(212, 106, 2); // Valor que correspon aproximadament a re3
TocaNota(238, 119, 2); // Valor que correspon aproximadament a do3
} else if (testbit(Barquitos[y][x],5)){ // Si es VAIXELL
setbit(Barquitos[y][x], 1); // Pinta de GROC ------> TOCAT (Després comprovem si es ENFONSAT)
setbit(Barquitos[y][x],3); // Marca LED com a ences
TocaNota(238, 119, 2); // Valor que correspon aproximadament a do3
}
for (signed char i = 0; i < 7; i++){ // Per cada vaixell (n'hi ha 7) Comprovem si esta enfonsat
char longitud=Vaixells[i][3];
char t=0; // Contador de posicions tocades per vaixell
d=Vaixells[i][2]; // d=0 Vertical, d=1 Horizontal
a=1-d;
for (signed char j = 0; j < longitud; j++){ // Per cada casella del vaixell
if (testbit(Barquitos[Vaixells[i][1]+j*a][Vaixells[i][0]+j*d],1)!=0){
t++; // Suma un si posicio del vaixell tocada
}
}
if (t==longitud){ // Si tot el vaixell tocat --> ENFONSAT
for (signed char j = 0; j < longitud; j++){
// Pintem de vermell totes les seves caselles
setbit(Barquitos[Vaixells[i][1]+j*a][Vaixells[i][0]+j*d],0);
// Posa a 0 el bit 1
((Barquitos[Vaixells[i][1]+j*a][Vaixells[i][0]+j*d]) &= ~(1 << (1)));
}
TocaNota(212, 106, 2); // Valor que correspon aproximadament a re3
TocaNota(189, 95, 0); // Valor que correspon aproximadament a mi3
contavaixells++; // Hem enfonsat un vaixell més
}
}
mirar = 0;
} // Final Polsador == 5 (Disparar)
Esborra(); // Esborrem la pantalla de text (per tornar a escriure)
EnviaL('T'); // i escrivim els Trets que queden per acabar
EnviaL('R');
EnviaL('E');
EnviaL('T');
EnviaL('S');
Cursor(1,8);
EnviaL((Tirs/10)+'0'); // Les decenes de Tirs
EnviaL((Tirs%10)+'0'); // Les unitats de Tirs
} else { // Mirar = 0
if (Polsad == 0) // Si no s'ha premut cap polsador (o dos a la vegada)
mirar = 1;
}
//----------- MOSTRAR FIGURA A LA MATRIU DE LED -----------
for (signed char j = 0; j < 8; j++){ // Fileres
char mascara;
char col;
char color=2; // Color verd
Sortida[0] = 0; // Vermells
Sortida[2] = 0; // Verds
Sortida[4] = 0; // Blaus
for (signed char k = 0; k < 8; k++){ // Caselles de la filera
if ((y == j) && (x == k)){ // Si estem a la casella del cursor
// El cursor es mostra en el color actual però si coincideix
// amb el color de la casella el mostrem blanc
// figura2[y][x]=0b00000001 --> vermell (R)
// figura2[y][x]=0b00000010 --> verd (G)
// figura2[y][x]=0b00000110 --> blau (B)
// figura2[y][x]=0b00000011 --> groc (RG)
if (cur_on == 1){ // Si toca el cursor encès
col = color; // Color actual
} else {
col = figura2(x,y); // Color de la posició actual
}
} else { // Si no hi estem, és una casella normal
col = figura2(k,j); // Color de la posició actual
}
// Posem els bits a la columna corresponent
mascara = (col & 0b0000001); // Serà 1 si hi ha vermell
Sortida[0] = Sortida[0] | (mascara << k);
mascara = (col & 0b0000010) >> 1; // Serà 1 si hi ha verd
Sortida[2] = Sortida[2] | (mascara << k);
mascara = (col & 0b0000100) >> 2; // Serà 1 si hi ha blau
Sortida[4] = Sortida[4] | (mascara << k);
}
Sortida[1] = j+1; // Filera
Sortida[3] = j+1;
Sortida[5] = j+1;
Envia3max(Sortida); // Ho envia al MAX7221
}
__delay_ms(1);
compt_int++;
if (compt_int == cic_int){ // Si toca intermitència
compt_int = 0;
cur_on = (cur_on + 1) % 2; // Canvia el cursor
}
//----------- COMPROVAR FINAL DE PARTIDA -----------
if (contavaixells==7){ // Has enfonsat tots els vaixells
Cursor(2,1); //
EnviaL(':'); // VICTORIA
EnviaL(')');
__delay_ms(5000);
fin=1; // Torna a començar
} else if (Tirs==0){ // T'has quedat sense tirs
Cursor(2,1); //
EnviaL(':'); // DERROTA
EnviaL('(');
__delay_ms(5000);
fin=1; // Torna a començar
}
}
}
}
void __interrupt() temporit(void){
if (INTCONbits.T0IF) { // Comprovem que hi ha interrupció per Timer 0
TMR0 = 100; // 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
Sorti[0] = 0x00; // Vermell
Sorti[2] = 0x00; // Verd
Sorti[4] = 0x00; // Blau
if (Actiu == 1) { // Si és vermell
Sorti[0] = 0x01; // Vermell activat
}
if (Actiu == 2) { // Si és verd
Sorti[2] = 0x01; // Verd activat
}
if (Actiu == 3) { // Si és blau
Sorti[4] = 0x01; // Blau activat
}
Sorti[1] = 0x0C; // Shutdown mode
Sorti[3] = 0x0C; // Shutdown mode
Sorti[5] = 0x0C; // Shutdown mode
Envia_max(); // Ho envia al MAX7221
}
}
// 1. PANTALLA DE TEXT
void EnviaL(char Caracter) { // Escriure un caràcter
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) { // Esborra text
EnviaL(254); // Caràcter de control
EnviaL(1); // Esborra la pantalla i posa el cursor a l'inici
}
void Cursor(char Filera, char Columna) { // Cursor del text
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
}
// 2. 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(100); // Retard de 0,2 s
TRISC = 0b00100000; // Posem RC5 (sortida del PWM) com a entrada
// O sigui, silenci
__delay_ms(100); // Retard de 0,2 s
}
// 3. MATRIU DE LED
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 Envia_max(void) { // Envia un joc de valors als tres MAX7221
asm("banksel _Port");
asm("bcf (_Port&7fh),5"); // S'assegura que Clock està desactivat
asm("bcf (_Port&7fh),6"); // S'assegura que Latch està desactivat
asm("movf (_Port&7fh),w"); // Agafa el valor de Port
asm("movwf PORTB"); // I el posa al port B
asm("banksel _Compta");
asm("movlw 48"); // Número de bits a enviar
asm("movwf (_Compta&7fh)"); // Variable per comptar els bits
asm("Bucle:");
asm("banksel _Port");
asm("bcf (_Port&7fh),4"); // Desactiva Data. Si toca activar-ho, ja ho farem
asm("banksel _Sorti");
asm("rlf (_Sorti&7fh),f"); // Fa sortir el bit de més a l'esquerra cap a C
asm("rlf ((_Sorti+1)&7fh),f"); // i roda els altres a l'esquerra
asm("rlf ((_Sorti+2)&7fh),f");
asm("rlf ((_Sorti+3)&7fh),f");
asm("rlf ((_Sorti+4)&7fh),f");
asm("rlf ((_Sorti+5)&7fh),f");
asm("banksel _Port");
asm("btfsc STATUS,0"); // Mira si el bit de l'esquerra era un 1
asm("bsf (_Port&7fh),4"); // Si era 1, activa Data
asm("movf (_Port&7fh),w"); // Agafa el valor de Port. El valor que ha canviat és Data
asm("movwf PORTB"); // I el posa al port B
asm("bsf (_Port&7fh),5"); // Activa Clock, forçant a llegir el bit
asm("movf (_Port&7fh),w"); // Agafa el valor de Port. El valor que ha canviat és Clock
asm("movwf PORTB"); // I el posa al port B
asm("bcf (_Port&7fh),5"); // Desactiva Clock
asm("movf (_Port&7fh),w"); // Agafa el valor de Port. El valor que ha canviat és Clock
asm("movwf PORTB"); // I el posa al port B
asm("banksel _Compta");
asm("decfsz (_Compta&7fh),f"); // Decrementa Compta
asm("goto Bucle"); // Si Compta no és zero, repeteix el bucle
asm("banksel (_Port&7fh)");
asm("bsf (_Port&7fh),6"); // Torna a activar Latch
// Els valors es copiaran a la sortida del registre
asm("movf (_Port&7fh),w"); // Agafa el valor de Port. El valor que ha canviat és Latch
asm("movwf PORTB"); // I el posa al port B
}
void Apaga(void) { // Apaga tots els LED
char Bytes[6]; // Els sis bytes que cal enviar
for (unsigned char 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
}
}
void Envia3max(char Valor[]) { // Envia un joc de valors als tres MAX7221
INTCONbits.T0IE = 0; // Desactiva les interrupcions momentàniament
char Port = 0; // Variable on guardem l'estat del port B
char Temp; // Variable temporal
for (signed char j = 5; j >= 0; j--){ // Hem d'enviar 6 bytes
for (signed char 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.T0IE = 1; // Reactiva les interrupcions a l'acabar
}
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;
}
// 4. PINTAR VAIXELLS
int figura2(int x, int y){
if (testbit(Barquitos[y][x],0)!=0){
return 0b00000001; // Retorna color VERMELL
} else if (testbit(Barquitos[y][x],1)!=0){
return 0b00000011; // Retorna color GROC
} else if (testbit(Barquitos[y][x],2)!=0){
return 0b00000110; // Retorna color BLAU
} else
return 0b00000000; // Retorn apagat
}

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