PIC: Genius, Jogo da Memória
Neste post vamos criar o jogo Genius com o PIC16F628A e outro com PIC16F877A.
O Jogo é formado basicamente por 4 Leds ( Amarelo, Azul, Verde e Vermelho ), 5 botões e 1 buzzer.
O botões utiliza os resistores de pull-up internos do PIC. Também foi utilizado o oscilador interno de 4Mhz( para o PIC16F628A ). No caso do PIC16F877A necessita de um cristal oscilador externo.
Obs.:
- Habilitar as bibliotecas Sound e C_Stdlib.
CÓDIGO
MikroC PRO PIC
#define NOTE_A 440 #define NOTE_D 294 #define NOTE_B 523 #define NOTE_C 261 #define NOTE_F 349 #define NOTE_E 329 #define NOTE_G 392 #define NIVEIS 20 sbit Start at PORTB.B3; sbit Botao1 at PORTB.B4; sbit Botao2 at PORTB.B5; sbit Botao3 at PORTB.B6; sbit Botao4 at PORTB.B7; sbit Led1 at PORTB.B0; sbit Led2 at PORTB.B1; sbit Led3 at PORTB.B2; sbit Led4 at PORTA.B1; char level = 1; //Nivel inicial char Memoria1[NIVEIS]; //Memoria para armazanar a sequncia gerada pelo PIC char Memoria2[NIVEIS]; //Memoria para armazenar a sequencia de acordo com os cliques nos botões void Som_Botao1() { Led1 = 1; Sound_Play( NOTE_F, 300 ); Delay_ms( 300 ); Led1 = 0; } void Som_Botao2() { Led2 = 1; Sound_Play( NOTE_B, 300 ); Delay_ms( 300 ); Led2 = 0; } void Som_Botao3() { Led3 = 1; Sound_Play( NOTE_C, 300 ); Delay_ms( 300 ); Led3 = 0; } void Som_Botao4() { Led4 = 1; Sound_Play( NOTE_D, 300 ); Delay_ms( 300 ); Led4 = 0; } void Som_Inicial() { Led1 = 1; Led2 = 1; Led3 = 1; Led4 = 1; Sound_Play( 200, 100 ); Delay_ms( 100 ); Sound_Play( 400, 100 ); Delay_ms( 100 ); Sound_Play( 200, 100 ); Delay_ms( 500 ); Led1 = 0; Led2 = 0; Led3 = 0; Led4 = 0; } void Som_Perdeu() { Led1 = 1; Led2 = 1; Led3 = 1; Led4 = 1; Sound_Play( 200, 300 ); Delay_ms( 300 ); Sound_Play( 150, 300 ); Delay_ms( 300 ); Sound_Play( 100, 300 ); Delay_ms( 300 ); Led1 = 0; Led2 = 0; Led3 = 0; Led4 = 0; } void Som_Ganhou() { Led1 = 1; Led2 = 1; Led3 = 1; Led4 = 1; Sound_Play( 500, 100 ); Delay_ms( 300 ); Sound_Play( 700, 300 ); Delay_ms( 200 ); Sound_Play( 900, 500 ); Delay_ms( 500 ); Sound_Play( 800, 200 ); Delay_ms( 200 ); Sound_Play( 900, 500 ); Delay_ms( 500 ); Led1 = 0; Led2 = 0; Led3 = 0; Led4 = 0; } void GerarSequencia() { unsigned semente; char i, random; semente = (TMR1H << 8) + TMR1L; srand( semente ); for( i=0; i < level; i++) { random = (char)(rand() % 4); //Gera um número aleatório entre 0 e 3 Memoria1[i] = random; if(random == 0) Som_Botao1(); else if(random == 1) Som_Botao2(); else if(random == 2) Som_Botao3(); else Som_Botao4(); Delay_ms( 200 ); } } char VerificarSequencia() { char i; for( i=0; i < level; i++) { if( Memoria2[i] != Memoria1[i] ) return 0; } return 1; } void main() { char cnt = 0; char flags = 0; T1CON = 0x81; //Utilizado como semente para gerar os números aleatórios CMCON = 0x07; //Desliga o comparador NOT_RBPU_Bit = 0; //Habilita os Resistores de Pull-UP TRISB = 0b11111000; TRISA = 0; Sound_Init( &PORTA, 0 ); Som_Inicial(); Inicio: while(Start); //Espera o botão Start ser pressionado Delay_ms( 1000 ); while(1) { cnt = 0; GerarSequencia(); //Gera uma sequencia while(1) { if(!Botao1) flags.B0 = 1; else if(!Botao2) flags.B1 = 1; else if(!Botao3) flags.B2 = 1; else if(!Botao4) flags.B3 = 1; if(Botao1 && flags.B0) { flags.B0 = 0; Memoria2[cnt++] = 0; Som_Botao1(); } else if(Botao2 && flags.B1) { flags.B1 = 0; Memoria2[cnt++] = 1; Som_Botao2(); } else if(Botao3 && flags.B2) { flags.B2 = 0; Memoria2[cnt++] = 2; Som_Botao3(); } else if(Botao4 && flags.B3) { flags.B3 = 0; Memoria2[cnt++] = 3; Som_Botao4(); } if( cnt == level ) break; } if( VerificarSequencia() ) { level++; if(level == NIVEIS) { level = 1; Som_Ganhou(); goto Inicio; } } else { level = 1; Som_Perdeu(); goto Inicio; } Delay_ms ( 1000 ); } }
VERSÃO 2
Nesta outra versão com o PIC16F877A foi adicionado dois displays de 7 segmentos CC para fazer a contagem dos acertos.
Obs.:
- Habilitar as bibliotecas Sound e C_Stdlib.
- Não se esqueça de colocar os resistores na saída da PORTC.
CÓDIGO
MikroC PRO PIC
#define NOTE_A 440 #define NOTE_D 294 #define NOTE_B 523 #define NOTE_C 261 #define NOTE_F 349 #define NOTE_E 329 #define NOTE_G 392 #define NIVEIS 30 //Botoes sbit Start at PORTB.B3; sbit Botao1 at PORTB.B4; sbit Botao2 at PORTB.B5; sbit Botao3 at PORTB.B6; sbit Botao4 at PORTB.B7; //Leds sbit Led1 at PORTB.B0; sbit Led2 at PORTB.B1; sbit Led3 at PORTB.B2; sbit Led4 at PORTA.B1; //selecao do display sbit Disp1 at PORTD.B6; sbit Disp2 at PORTD.B7; //nivel atual do jogo char level = 1; //buffers char Memoria1[NIVEIS]; char Memoria2[NIVEIS]; //numeros para o display char Display[10] = { 63, 6, 91, 79, 102, 109, 125, 7, 127, 111 }; void Som_Botao1() { Led1 = 1; Sound_Play( NOTE_F, 300 ); Delay_ms( 300 ); Led1 = 0; } void Som_Botao2() { Led2 = 1; Sound_Play( NOTE_B, 300 ); Delay_ms( 300 ); Led2 = 0; } void Som_Botao3() { Led3 = 1; Sound_Play( NOTE_C, 300 ); Delay_ms( 300 ); Led3 = 0; } void Som_Botao4() { Led4 = 1; Sound_Play( NOTE_D, 300 ); Delay_ms( 300 ); Led4 = 0; } void Som_Inicial() { Led1 = 1; Led2 = 1; Led3 = 1; Led4 = 1; Sound_Play( 200, 100 ); Delay_ms( 100 ); Sound_Play( 400, 100 ); Delay_ms( 100 ); Sound_Play( 200, 100 ); Delay_ms( 500 ); Led1 = 0; Led2 = 0; Led3 = 0; Led4 = 0; } void Som_Perdeu() { Led1 = 1; Led2 = 1; Led3 = 1; Led4 = 1; Sound_Play( 200, 300 ); Delay_ms( 300 ); Sound_Play( 150, 300 ); Delay_ms( 300 ); Sound_Play( 100, 300 ); Delay_ms( 300 ); Led1 = 0; Led2 = 0; Led3 = 0; Led4 = 0; } void Som_Ganhou() { Led1 = 1; Led2 = 1; Led3 = 1; Led4 = 1; Sound_Play( 500, 100 ); Delay_ms( 300 ); Sound_Play( 700, 300 ); Delay_ms( 200 ); Sound_Play( 900, 500 ); Delay_ms( 500 ); Sound_Play( 800, 200 ); Delay_ms( 200 ); Sound_Play( 900, 500 ); Delay_ms( 500 ); Led1 = 0; Led2 = 0; Led3 = 0; Led4 = 0; } //Gera uma sequencia void GerarSequencia() { unsigned semente; char random; char i; semente = (TMR1H << 8) + TMR1L; srand( semente ); for( i=0; i < level; i++) { random = (char)(rand() % 4); Memoria1[i] = random; if(random == 0) Som_Botao1(); else if(random == 1) Som_Botao2(); else if(random == 2) Som_Botao3(); else Som_Botao4(); Delay_ms( 200 ); } } //Verifica a sequencia do usuário com a //sequencia gerado pelo pic char VerificarSequencia() { char i; for( i=0; i < level; i++) { if( Memoria2[i] != Memoria1[i] ) return 0; } return 1; } //Escreve os numeros no display static char flag = 1; void Write_Display() { char temp = level - 1; Disp1 = flag.B0; Disp2 = !flag.B0; if( flag.B0 ) { PORTC = Display[temp/10]; } else { PORTC = Display[temp%10]; } flag.B0 = ~flag.B0; } //Interrupção a cada 4ms para escreve no display void Interrupt() { TMR0IF_Bit = 0; Write_Display(); TMR0 = 6; } void main() { char cnt = 0; char flags = 0; T1CON = 0x81; //habilita o timer 1 CMCON = 0x07; //desliga os comparadores analogico ADCON1 = 0x06; //desliga o conversor AD TRISB = 0b11111000; TRISA = 0; TRISC = 0; TRISD = 0; PORTD = 0; PORTC = 0; Sound_Init( &PORTA, 0 ); //Configura timer0 para gerar interrupção a cada 4ms OPTION_REG = 0x04; TMR0 = 6; INTCON = 0xA0; Som_Inicial(); Inicio: while(Start); Delay_ms( 2000 ); while(1) { cnt = 0; GerarSequencia(); while(1) { if(!Botao1) flags.B0 = 1; else if(!Botao2) flags.B1 = 1; else if(!Botao3) flags.B2 = 1; else if(!Botao4) flags.B3 = 1; if(Botao1 && flags.B0) { flags.B0 = 0; Memoria2[cnt++] = 0; Som_Botao1(); } else if(Botao2 && flags.B1) { flags.B1 = 0; Memoria2[cnt++] = 1; Som_Botao2(); } else if(Botao3 && flags.B2) { flags.B2 = 0; Memoria2[cnt++] = 2; Som_Botao3(); } else if(Botao4 && flags.B3) { flags.B3 = 0; Memoria2[cnt++] = 3; Som_Botao4(); } if( cnt == level ) break; } if( VerificarSequencia() ) { level++; if(level == NIVEIS) { level = 1; Som_Ganhou(); goto Inicio; } } else { level = 1; Som_Perdeu(); goto Inicio; } Delay_ms(1000); } }
Bacana esse jogo do tempo que era menino.
ResponderExcluirUm Bom Dia para Você.
onde fica o positivo e o negativo
ResponderExcluirProcura no datasheet do CI.
ResponderExcluirqual o compilador que foi utilizado?
ResponderExcluirMikroC PRO PIC v6.0
Excluirobrigado
Excluirteria como eu habilitar as outras portas que não estão sendo usadas para outra coisa, mais especificamente 4 portas
ExcluirOi possivel de ter um codico em mikroC v.8 ?
ResponderExcluirOu deixar uma verçao pra download
ResponderExcluirObrigado
Eu compilo no mplabx e não consigo habilitar a biblioteca sound para fazer o Genius. Onde posso encontrar. Obrigado.
ResponderExcluirBoa tarde. Eu copiei e colei este código para o MikroC e fiz o teste no Proteus 8. Funcionou, exceto por uma desordem nos LED's. Exemplo: quando inicio o programa ele pisca o LED verde, daí pressiono o botão correspondente do LED. Até aí ok. Mas quando ele passa pro nível dois, em vez dele gerar a sequência com o primeiro LED, no caso o verde e algum outro, não, ele gera dois cores diferente da primeira sequência. Exemplo: azul e amarelo. Sendo que deveria ser verde, que doi o primeiro gerado e outra cor aleatória. Espero que entendam o problema. E gostaria muito de uma ajuda. Conto com vocês. E ótimo tutorial!!
ResponderExcluirOla onde coloco a alimentação 5v e gnd no PIC
ResponderExcluirSou iniciante em programação e microcontroladores pic! como faço para Habilitar as bibliotecas Sound e C_Stdlib, para o pic16f628a? Obrigado.
ResponderExcluir