Pagine

lunedì 3 dicembre 2012

Gioco simile al Simon con PIC12

publico un esercizietto che ho fatto qualche giorno fa per imparare ad usare un compilatore per PIC che è per me nuovo.

Per chi non lo sapesse, il gioco del simon è questo:

wikipedia-simon-game

credo sia un bel pogetto per chiunque voglia iniziare:


ecco cosa ho fatto.


Me lo sono riproposto usando due led e due pushbutton.

il circuito è molto semplice e nemmeno "sbattuto" ero troppo pigro per mettere i dovuti condensatori ecc.


eccolo:








come potete vedere, potevo evitare di metterlo perchè è veramente semplice:

le due resistenze R1 e R2 sono messe così per permettere la programmazione in circuit dato che ho fatto pure il pcb perchè si stava ossidando troppo una delle mie piastre ramate e non la volevo buttare.Ovviamente non vale la pena di fare un PCB per questo progetto, va benissimo in breadboard.


Per generare il random seed uso una resistenza termica collegata all'ADC senza pulldown.

Per il resto i due interruttori hanno pullup interno nel PIC quindi sono collegati senza pull-up come mamma li ha fatti.



questa era la parte noiosa che non credo interessi a molti: alla fine sono due led e due interruttori!


veniamo al codice:


è scritto per HITECH-C




non sono un bravissimo coder, ci sarà sicuramente un modo migliore di scriverlo ma almeno sono riuscito a farlo stare in quella bestiola!:)


chiedo scusa per l'indentazione ORRIBILE  ma io sti blog non li capisco!


#include<htc.h>
#include<time.h>
#include<stdlib.h>
//#include "../libs/softuart.h" //debugging
#include "../libs/12f6xADC.h"
#undef _XTAL_FREQ
#define _XTAL_FREQ 4000000

__CONFIG(0x31c4);

char h = 0; //variabile globale riciclabile per funzioni dei led ecc
char y = 0; //variabile per i contatori
char seq[22]; //sequenza random
//char userinput[10]; // sequenza input scartata da nuovo metodo di risparmio memoria
char suxess = 1; //variabile di vincita o perdita
void sorter(){ // separiamoli in pari e dispari
__delay_us(40);
for (char x = 0; x<22;x++){ //riempiamo l'array di numeri random
ADC_Init();
ANS2 = 1;
ADC_ReadAll(2); //presi dal canale 2 dell'ADC (il terzo pin di destra partendo dall'alto)
srand(ADRESL); //diamo il bit basso della misurazione in pasto al seed
seq[x] = (rand()%2)&1; //separiamo numeri pari e dispari, ci interessano solo loro.
}
}


void delaylong(){ //aspettiamo qualche millesimo di secondo
__delay_ms(100);
__delay_ms(100);
__delay_ms(100);


}


void pins(char x){ //blinkiamo i led per far vedere la siquenza
if(seq[x] == 0){ GPIO0 = 1; __delay_ms(100);__delay_ms(100);GPIO0 = 0;  __delay_ms(100);__delay_ms(100);} //prende come argomento 0 o 1 dal contatore che lo chiama nel main
if(seq[x] == 1){ GPIO1 = 1; __delay_ms(100);__delay_ms(100); GPIO1 = 0;  __delay_ms(100);__delay_ms(100);}

}


void gameover(){ //"animazione" per mostrare che si è perso
for(h = 0; h<2; h++){ GPIO |= 3; sorter(); delaylong(); GPIO = 0; delaylong();}
}

void win(){//"animazione" per la vittoria
for(h = 0; h<2; h++){ GPIO = 1; sorter();  delaylong(); GPIO = 2; delaylong();}
}

void gamestart(){ for(h = 3; h > 0; h--){ GPIO |= 3; delaylong();GPIO = 0; delaylong();}}//animazione per cominciare a giocare
void main(){
TRIS0 = 0; //gpio0 è output, un led, precisamente corrisponde al bottone su GPIO4
TRIS1 = 0; //gpio1 è output, un led, precisamente corrisponde al bottone su GPIO5
TRIS4 = 1; //ecco qui, gpio4 è un input, appunto di un bottone
TRIS5 = 1;//anche gpio5 lo è, sempre di un bottone
ADON = 0x00;//spegnamo gli ADC
ANSEL = 0x00;//per sicurezza, vuotiamo tutto ciò che ne ha a che fare, gestisce tutto la mia lib ADC
WPU = 0xff;//attiviamo tutti i weak pull-up, voglio una scheda bella e pulita
GPPU = 0;//incredibile ma 0 significa attivati, si, sono i pullup.


while(1){//si comincia
sorter();//generiamo il nostro array
gamestart();//"twinkle twinkle little star"
char engine = 0;//contatore principale, quello dei livelli a 0: mr sulu, velocità warp!
while(engine<=22){//giochiamo tutti e 23 i livelli _\m/
y = 0; //azzeriamo il contatore riciclato, non inquiniamo la nostra EEPROM, ricicliamo!
for(y = 0; y <= engine; y++){//zuuun zuuuun ecco, parsiamo l'array a pins(), se è 0 accende GPIO0, se è 1 accende GPIO1
pins(y);
}
y = 0;//beh? volevi buttarlo via?
__delay_us(30);//aspetta...
GPIO = 11;//GPIO = 3!:D ci sono 10 tipi di persone: chi capisce il binario e chi no!
__delay_ms(100);
GPIO = 0; //spegni tutto
__delay_ms(100);
GPIO = 11; //di nuovo 3! che sarà?:O
__delay_ms(100);
GPIO = 0;
__delay_ms(100); //esatto è una animazione!
char voted = 0; //variabile per sapere se è stato premuto il tasto e confrontare con l'array
suxess = 1; //vinci o perdi? settiamo a 1 e lasciamo fare al prossimo while
char userinput = 0; //ecco, bottone di GPIO1 o GPIO0?
while(y <= engine){//finchè il nostro netturbinolox è minore o uguale a engine
if(voted == 1 && userinput != seq[y-1]){suxess = 0; break;} //se l'user ha fatto la sua mossa, guarda se è giusta, se è sbagliata condannalo ad un game over
if(GPIO5 == 0){ //se il bottone di GPIO5 è premuto (ha i pullup)
userinput = 1; //questo vale 1
voted = 1; //sbirciamo per i ballottaggi
GPIO1 = 1; //MARSHHHH MELLLLOOOOOOOOOOOOOOOWWW no.
delaylong();
GPIO1 = 0;
y++; //aumentiamo il contatore
}
if(GPIO4 == 0){ //uguale ma diverso valore
userinput = 0;//capiscitelo da solo, non ho voglia di ripetermi.
voted = 1;
GPIO0 = 1;
delaylong();
GPIO0 = 0;
y++;
}


    //suxess = 1;
    __delay_ms(100); //MISTERO
    __delay_ms(100); //questo invece è sicuramente un coprolita.

}

/* for(y = 0; y <= engine; y++){              //non ci serve ma lo tengo per bellezza

if(userinput[y] != seq[y]){ suxess = 0;}
*/
//}
if(suxess == 1){ engine++;} //se la combinazione era giusta aggiungi un livello!:D
else if(suxess == 0){ gameover(); gameover(); gameover(); gameover(); engine = 0;  }//ha fatto schifo. TAGLIATEGLI LA TESTA!!!!!


}

win(); //se sei uscito dal circolo vizioso vedrai questa animazione
win();
win();
win();
delaylong(); //aspetterai
delaylong();
delaylong();
//e... dall'inizio!
}



non badate troppo ai commenti un po' coloriti, erano le 4 del mattino e il sonno ha una cattiva influenza sui neuroni.

 
il codice non si fa capire come dovrebbe, ma se sapete cosa state leggendo lo capirete, altrimenti se non sapete il C e volete solo rubare beh, perderete del tempo!^^

quasi dimenticavo: la libreria "softuart.h" e l'altra "12f6xADC.h" le ho scritte io per comodità non cercatele invano in rete, ci saranno sicuramente di migliori ma avranno un nome forse diverso :)






byez!

Nessun commento:

Posta un commento