Programació en C del PIC 16F690

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

Desenvolupament de jocs senzills

Enfonsar la flota

El joc vol imitar, amb les limitacions que imposa la pantalla, el jos d'enfonsar vaixells. L'ús dels polsadors és el següent:

Polsador Finalitat
0 Canvi de taulell
1 Desplaçament a l'esquerra
2 Desplaçament a la dreta
Pinta de verd (vaixells propis)
3 Desplaçament avall
Pinta de blau (aigua)
4 Desplaçament amunt
Pinta de vermell (tocat)
5 Canvi de mode

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>
#define _XTAL_FREQ  4000000
char Port;
char Compta;
char Sortida[6];
char Sorti[6];
char Actiu;
char Polsad;
char figura[8];
char figura_vermell[8];
char figura_verd[8];
// --- NUEVAS MATRICES PARA LA SEGUNDA PANTALLA ---
char figura2[8];
char figura2_vermell[8];
char figura2_verd[8];
char pantalla_actual = 1;  // 1 = primera pantalla, 2 = segunda
char x = 0;
char y = 0;
char mirar = 1;
// --- DECLARACIÓN DE FUNCIONES ---
void Envia3max(char Valor[]);
void Envia_max(void);
void Ini3max(void);
void Apaga(void);
char Polsador(void);
// --- PROGRAMA PRINCIPAL ---
void main (void) {
    OPTION_REG = 0b10000101;
    TRISC = 0;
    TRISB = 0;
    TRISA = 0xFF;
    ANSEL = 0b00000101;
    ANSELH = 0;
    PORTC = 0;
    PORTB = 0;
    ADCON1 = 0b00010000;
    ADCON0 = 0b00001001;
    Ini3max();
    Actiu = 1;
    TMR0 = 100;
    INTCON = 0b10100000;
    Apaga();
    // Inicialización de las dos pantallas
    for (signed char k = 0; k < 8; k++) {
        figura[k] = 0;
        figura_vermell[k] = 0;
        figura_verd[k] = 0;
        figura2[k] = 0;
        figura2_vermell[k] = 0;
        figura2_verd[k] = 0;
    }
    TRISAbits.TRISA3 = 1;  // RA3 com a entrada
    ANSELbits.ANS3 = 0;  
    // Desactiva el mode analògic per RA3
    while (1) {
        Polsad = Polsador();
        // --- Selecciona los arrays activos según la pantalla actual ---
        char *figura_activa_vermell;
        char *figura_activa_verd;
        char *figura_activa_blau;
        if (pantalla_actual == 1) {
            figura_activa_vermell = figura_vermell;
            figura_activa_verd = figura_verd;
            figura_activa_blau = figura;
        } else {
            figura_activa_vermell = figura2_vermell;
            figura_activa_verd = figura2_verd;
            figura_activa_blau = figura2;
        }
        // --- Control de pulsadores ---
        if (mirar == 1){
            if (Polsad == 1) {
                x = (x + 1) % 8;
                mirar = 0;
            }
            if (Polsad == 2) {
                x = (x - 1 + 8) % 8;
                mirar = 0;
            }
            if (Polsad == 3) {
                y = (y + 1) % 8;
                mirar = 0;
            }
            if (Polsad == 4) {
                y = (y - 1 + 8) % 8;
                mirar = 0;
            }
            if (Polsad == 5) {
                mirar = 2;  // Modo de edición de color
            }
            if (Polsad == 6) { // --- NUEVO: cambia de pantalla ---
                if (pantalla_actual == 1) pantalla_actual = 2;
                else pantalla_actual = 1;
                mirar = 0;
            }
        } else if (mirar == 2){
            if (Polsad == 1) {
                mirar = 0;
            }
            if (Polsad == 3) {
                figura_activa_vermell[y] &= ~(1 << x);
                figura_activa_verd[y] &= ~(1 << x);
                figura_activa_blau[y] = figura_activa_blau[y] ^ (1 << x);
                mirar = 0;
            }
            if (Polsad == 4) {
                figura_activa_blau[y] &= ~(1 << x);
                figura_activa_verd[y] &= ~(1 << x);
                figura_activa_vermell[y] = figura_activa_vermell[y] ^ (1 << x);
                mirar = 0;
            }
            if (Polsad == 2) {
                figura_activa_blau[y] &= ~(1 << x);
                figura_activa_vermell[y] &= ~(1 << x);
                figura_activa_verd[y] = figura_activa_verd[y] ^ (1 << x);
                mirar = 0;
            }
        } else {
            if (Polsad == 0) {
                mirar = 1;
            }
        }
        // --- Muestra la matriz activa ---
        for (unsigned char k = 0; k < 8; k++){
            char mascara;
            Sortida[0] = figura_activa_vermell[k];
            Sortida[2] = figura_activa_verd[k];
            Sortida[4] = figura_activa_blau[k];
            if (y == k){
                mascara = (1 << x);
                Sortida[0] |= mascara;  // Cursor en rojo
                Sortida[2] |= mascara;  // y verde
                Sortida[4] &= ~mascara; // sin azul
            }
            Sortida[1] = k+1;
            Sortida[3] = k+1;
            Sortida[5] = k+1;
            Envia3max(Sortida);
            __delay_ms(1);
        }
    }
}
// --- INTERRUPCIÓN DE TIMER ---
void __interrupt() temporit(void){
    if (INTCONbits.T0IF) {
        TMR0 = 100;
        INTCONbits.T0IF = 0;
        if (Actiu != 0) {
            Actiu--;
            if (Actiu == 0) {
                Actiu = 3;
            }
        }
        Sorti[0] = 0x00;
        Sorti[2] = 0x00;
        Sorti[4] = 0x00;
        if (Actiu == 1) Sorti[0] = 0x01;
        if (Actiu == 2) Sorti[2] = 0x01;
        if (Actiu == 3) Sorti[4] = 0x01;
        Sorti[1] = 0x0C;
        Sorti[3] = 0x0C;
        Sorti[5] = 0x0C;
        Envia_max();
    }
}
void Envia3max(char Valor[]) {
    INTCONbits.T0IE = 0;
    char Port = 0;
    char Temp;
    for (signed char j = 5; j >= 0; j--){
        for (signed char k = 1; k < 9; k++){
            Temp = Valor[j] & 0b10000000;
            if (Temp == 0)
                Port = Port & 0b11101111;
            else
                Port = Port | 0b00010000;
            Valor[j] = Valor[j] << 1;
            PORTB = Port;
            Port = Port | 0b00100000;
            PORTB = Port;
            Port = Port & 0b11011111;
            PORTB = Port;
        }
    }
    Port = Port | 0b01000000;
    PORTB = Port;
    INTCONbits.T0IE = 1;
}
void Envia_max(void) {
    asm("banksel _Port");
    asm("bcf (_Port&7fh),5");
    asm("bcf (_Port&7fh),6");
    asm("movf (_Port&7fh),w");
    asm("banksel PORTB");
    asm("movwf PORTB");
    asm("banksel _Compta");
    asm("movlw 48");
    asm("movwf (_Compta&7fh)");
    asm("Bucle:");
    asm("banksel _Port");
    asm("bcf (_Port&7fh),4");
    asm("banksel _Sorti");
    asm("rlf (_Sorti&7fh),f");
    asm("rlf ((_Sorti+1)&7fh),f");
    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");
    asm("bsf (_Port&7fh),4");
    asm("movf (_Port&7fh),w");
    asm("banksel PORTB");
    asm("movwf PORTB");
    asm("banksel _Port");
    asm("bsf (_Port&7fh),5");
    asm("movf (_Port&7fh),w");
    asm("banksel PORTB");
    asm("movwf PORTB");
    asm("banksel _Port");
    asm("bcf (_Port&7fh),5");
    asm("movf (_Port&7fh),w");
    asm("banksel PORTB");
    asm("movwf PORTB");
    asm("banksel _Compta");
    asm("decfsz (_Compta&7fh),f");
    asm("goto (Bucle&7ffh)");
    asm("banksel _Port");
    asm("bsf (_Port&7fh),6");
    asm("movf (_Port&7fh),w");
    asm("banksel PORTB");
    asm("movwf PORTB");
}
void Ini3max(void) {
    char Bytes[6];
    Bytes[0] = 0x00;
    Bytes[1] = 0x0C;
    Bytes[2] = 0x00;
    Bytes[3] = 0x0C;
    Bytes[4] = 0x00;
    Bytes[5] = 0x0C;
    Envia3max(Bytes);
    Bytes[0] = 0x00;
    Bytes[1] = 0x09;
    Bytes[2] = 0x00;
    Bytes[3] = 0x09;
    Bytes[4] = 0x00;
    Bytes[5] = 0x09;
    Envia3max(Bytes);
    Bytes[0] = 0x07;
    Bytes[1] = 0x0B;
    Bytes[2] = 0x07;
    Bytes[3] = 0x0B;
    Bytes[4] = 0x07;
    Bytes[5] = 0x0B;
    Envia3max(Bytes);
}
void Apaga(void) {
    char Bytes[6];
    for (unsigned char j = 1; j <= 8; j++){
        Bytes[1] = j;
        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;
    while (ADCON0bits.GO == 1);
    if (ADRESH < 220 && ADRESH > 200) Pols = 1;
    if (ADRESH < 194 && ADRESH > 174) Pols = 2;
    if (ADRESH < 163 && ADRESH > 143) Pols = 3;
    if (ADRESH < 90 && ADRESH > 70)   Pols = 4;
    if (ADRESH < 55 && ADRESH > 35)   Pols = 5;
    if (PORTAbits.RA3 == 0) {  // Si el botó està connectat a GND
        __delay_ms(30);  // Desrebot
        if (PORTAbits.RA3 == 0)
           Pols = 6;
    }
    return Pols;
}

 

 

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