Jogo de Memória (Memorex v. 3.0) José Wilson Lima Nerys Universidade Federal de Goiás jwlnerys@gmail.com Abstract No presente projeto uma sequência de Leds é criada pelo microcontrolador, e deve ser repetida pelo usuário. O objetivo é que o usuário repita sem erros a sequência criada. Essa sequência tem 1 dígito a mais a cada nova etapa, com limite máximo de 20 dígitos. 1 I. Introdução Oprojeto apresenta três níveis de dificuldade: fácil, médio e difícil. No modo fácil tem-se uma sequência inalterada de números variando de 1 a 20 dígitos. No nível médio a sequência anterior é repetida e acrescida de 1 dígito, até o limite de 20 dígitos. No nível difícil, cada nova etapa é constituída de uma nova sequência aleatória, até o limite de 20 dígitos. A Fig.1 mostra o circuito do projeto Memorex. Um driver CD4511 é usado para os dois displays de 7-segmentos, acionados usando multiplexação, e dois drivers ULN2803 são usados para acionar os 11 Leds e para selecionar os displays de 7-segmentos. Fez-se a escolha de colocar em nível lógico alto cada um dos pinos ligados às chaves de escolha da sequência, quando as chaves são pressionadas. No entanto, as chaves de escolha do nível do jogo, quando pressionadas, levam o pino correspondente ao nível lógico baixo. II. Fluxograma e Programa em Assembly do 8051 O fluxograma do Memorex foi dividido em partes, para facilitar o entendemimento e por razões de adequação ao tamanho da página. Inicialmente faz-se a definição de variáveis e as configurações dos temporizadores 0 e 1, usados, respectivamente, para gerar atraso para o display de 7-segmentos e para a geração aleatória de números para os níveis médio e difícil. Os dois temporizadores operam com interrupção habilitada e o temporizador 0 opera no modo 1 com prioridade alta, uma vez que o display deve ser atualizado perioridamente. Nas definições tem-se ainda a atribuição dos valores iniciais das variáveis. A seguir os Leds de saída são rotacionados (ligados e desligados em sequência) antes do programa entrar em um laço de espera. No laço de espera os Leds que indicam os níveis disponíveis ficam piscando, aguardando a escolha do usuário. Uma vez feita a escolha do nível do jogo, o programa desvia para o programa escolhido, e mantém ligado o Led correspondente. Com o intuito de reduzir as informações no corpo do programa Memorex, foi feita a definição de variáveis fora da tabela principal. Essas variáveis são: unidade bit 00h ; flag usada para alternar entre os displays de dezenas e de unidades. acertos equ 08h ; registrador que guarda a quantidade de acertos. sequencia equ 09h ; registrador que guarda a sequência gerada pelo microcontrolador. contador equ 05h ; registrador R5 - guarda a contagem da quantidade de valores da tabela. 1 Esse projeto foi, originalmente, criado de forma separada, por autores diferentes. Eles foram montados juntos e acrescentou-se o display para mostrar a quantidade de acertos. 1
Figure 1: Circuito do Jogo de Memória auxiliar equ 02h ; registrador R2 - usado para decrementar a quantidade da tabela, sem alterar R5. ch_facil equ P3.0 ; chave seletora modo fácil; se ch_facil=0, o processamento desvia para jogo fácil. ch_medio equ P3.1 ; chave seletora do modo médio. ch_dificil equ P3.2 ; chave seletora do modo difícil. Ledfacil equ P3.3 ; Led que indica modo fácil ativado. Ledmedio equ P3.4 ; Led que indica modo médio ativado. Leddificil equ P3.5 ; Led que indica modo difícil ativado. O jogo fácil consiste na leitura de uma tabela pré-gravada e na comparação dessa tabela com os valores digitados pelo usuário. Assim, no início do jogo, o programa faz a leitura do primeiro elemento da tabela e mostra nos Leds (esse primeiro valor é 01h em todos os níveis). No passo seguinte o programa faz a leitura da tecla digitada pelo usuário e, ainda dentro dessa subrotina, faz a comparação do valor digitado com o valor lido da tabela. Caso os valores não sejam iguais, A = B, o programa desvia para a rotina errou ; nessa rotina, após um período de Leds piscando, o programa volta para o início. Caso A = B, o registrador auxiliar é comparado com o registrador contador ; caso eles sejam diferentes, significa que a sequência ainda não acabou; então o programa volta para o início da subrotina leitura_facil para ler o próximo valor digitado pelo usuário. Caso os registradores auxiliar e contador sejam iguais, significa que aquela sequência já se encerrou e o número de acertos deve ser incrementado, antes do orno para a rotina principal do jogo fácil. Ao ornar da subrotina leitura_facil o registrador contador é comparado com 21 decimal; caso contador = 21, desvia para a rotina completou, onde o efeito previsto é a rotação ininterrupta dos Leds da porta P2. No jogo médio, ao contrário do jogo fácil, a tabela a ser lida é construída ao longo do jogo. No início do jogo o valor 01h é colocado na tabela, no endereço 70h da RAM. Em seguida, o programa chama a subrotina usada para mostrar o jogo nos Leds, buscando o jogo na memória RAM, a partir do endereço 70h (Os próximos valores serão guardados nos endereços 71h, 72h,... à medida que o usuário vai acertando as sequências mostradas. A nova sequência repete a sequência anterior, adicionando mais um dígito aleatório). Após esse procedimento, o programa chama a 2
Figure 2: Memorex - Definições e Escolha subrotina leitura_medio, onde o usuário digita a sequência mostrada, que é comparada com a sequência da tabela. No início dessa subrotina o Timer 1 é disparado, iniciando o processo de geração aleatória do próximo dígito da sequência. Ao final dessa subrotina o Timer 1 é parado. A continuação do programa é similar ao jogo fácil. A tabela do jogo difícil também é gerada ao longo do jogo, mas segue uma dinâmica um pouco diferente daquela do jogo médio. Primeiro, cada nova etapa no jogo difícil tem uma nova sequência, com um dígito a mais; segundo, no jogo médio o valor 01h (primeiro valor de todos os jogos) é sempre colocado no endereço 70h e os demais valores são colocados nos endereços subsequentes; no jogo difícil o valor 01h também é o primeiro valor mostrado, mas esse valor será sempre o último valor alocado na tabela. O processo de criação da tabela no jogo difícil segue a seguinte lógica: na primeira sequência, de apenas um dígito, o valor 01h é colocado no endereço 71h (70h + contador). Quando o usuário acerta esse dígito, um número aleatório (gerado usando o Timer 1) é alocado nesse endereço (71h) e o valor 01h é colocado no endereço 72h. Na próxima sequência, de 3 dígitos, o primeiro número aleatório gerado é gravado no endereço 72h; o segundo, no endereço 71h e o número 01h, no endereço 73h. Assim, após cada novo acerto, um novo número aleatório é gerado e armazenado na posição do número do último acerto (o armazenamento de novos números aleatórios no jogo difícil ocorre depois da comparação A = B?, na subrotina leitura_dificil ). Terminada a sequência atual, o último valor armazenado é 01h, na posição correspondente ao novo valor do contador adicionado de 70h. Dessa forma, a criação da tabela começa no maior endereço atual e termina com o valor 01h, no novo maior valor de endereço (contador + 1). A leitura da tabela é feita de forma decrescente,a partir do endereço 70h + contador. 3
Table 1: Programa Memorex - Definições e Escolha do Jogo Rótulo Mnemônico Rótulo Mnemônico Rótulo Mnemônico org 00H mov acertos,#00h escolha: cpl Ledfacil ljmp inicio mov sequencia,#01h cpl Ledmedio clr unidade cpl Leddificil org 0Bh mov dptr,#tabela_facil ljmp display mov P2, #00h jnb ch_facil,jogo_facil mov P1, #00h jnb ch_medio,segundo org 1Bh clr Ledfacil jnb ch_dificil,terceiro ljmp aleatorio clr Ledmedio reduzido clr Leddificil sjmp escolha org 30h mov a,#01h inicio: mov sp, #2Fh segundo: ljmp jogo_medio mov tmod,#01h testaleds: mov P2,A terceiro: ljmp jogo_dificil mov ie,#8ah rl a mov ip,#02h reduzido mov th0,#0d8h cjne a,#01h,testaleds mov tl0,#0efh mov P2,#00H setb tr0 Figure 3: Memorex - Jogo Fácil Finalizando o programa do projeto Memorex, tem-se a rotina que é executada quando o usuário erra a sequência e a rotina executada quando o usuário completa o jogo, ou seja, acerta todas as sequências até a última, que contém 20 dígitos. A subrotina display é chamada a cada 10 ms, ao final de cada contagem do temporizador 0. Essa subrotina mostra o dígito de unidade e de dezena no display de 7-segmentos, indicando o número de acertos do jogador. A subrotina aleatório é chamada a cada final de contagem do temporizador 1; ela rotaciona para a direita o valor presente no registrador sequencia, gerando um novo dígito a ser usado nos níveis médio ou difícil. 4
Figure 4: Memorex - Jogo Fácil: escolha do usuário Table 2: Programa Memorex - Jogo Fácil Rótulo Mnemônico Rótulo Mnemônico jogo_facil: setb Ledfacil leitura_facil: mov auxiliar,#00 clr Ledmedio volta_facil: mov P2,#00h clr Leddificil espera_facil: mov a,p1 mov contador,#01 cjne a,#00h,segue_facil sjmp espera_facil segue_facil: mov b,a processo_facil: mov P2,#00 mov P2,a pressionado_facil: mov a,p1 lcall mostra_facil cjne a,#00h,pressionado_facil lcall leitura_facil cjne R5,#21,processo_facil mov P2,#00h ljmp completou compara_facil: mov a,auxiliar movc a,@a+dptr mostra_facil: mov a,#00 cjne a,b,errado_facil continua: push acc sjmp certo_facil movc a,@a+dptr errado_facil: ljmp errou mov P2,a certo_facil: inc auxiliar mov a,auxiliar pop acc cjne a,05h,volta_facil inc a mov a,acertos cjne a,05h,continua add a,#01 da a mov acertos,a inc contador tabela_facil: db 01h, 40h, 20h, 80h, 10h, 02h, 08h, 04h, 80h, 01h db 40h, 02h, 20h, 10h, 80h, 08h, 20h, 04h, 40h, 10h 5
Figure 5: Memorex - Jogo Médio Figure 6: Memorex - Jogo Médio: Escolha do usuário 6
Table 3: Programa Memorex - Jogo Médio Rótulo Mnemônico Rótulo Mnemônico jogo_medio: setb Ledmedio leitura_medio: mov auxiliar,#00h clr Ledfacil clr Leddificil volta_medio: setb tr1 mov contador, #01h mov P2,#00h mov auxiliar, #00h mov sequencia,#01h espera_medio: mov a,p1 cjne a, #00h,segue_medio processo_medio: lcall tabela_medio sjmp espera_medio lcall mostra_medio lcall leitura_medio segue_medio: mov b,a cjne R5,#21,processo_medio mov P2,a ljmp completou pressionado_medio: mov a,p1 tabela_medio: mov a, auxiliar cjne a,#00h,pressionado_medio mov P2,#00h mov @r0,sequencia compara_medio: mov a,auxiliar mostra_medio: mov auxiliar,#00h mov a,@r0 mostra2_medio: mov P2,#00h cjne a,b,errou_medio inc auxiliar mov a,auxiliar mov a,auxiliar cjne a,05h,volta_medio mov a,acertos add a,#01 mov a,@r0 da a mov P2,a mov acertos,a inc contador inc auxiliar clr tr1 mov a,auxiliar cjne a,05h,mostra2_medio errou_medio: ljmp errou Figure 7: Memorex - Jogo Difícil 7
Figure 8: Memorex - Jogo Difícil: Escolha do usuário Table 4: Programa Memorex - Jogo Dificil Rótulo Mnemônico Rótulo Mnemônico jogo_dificil: clr Ledmedio leitura_dificil: mov auxiliar,contador clr Ledfacil volta: setb tr1 setb Leddificil mov P2,#00h mov contador, #01h espera: mov a,p1 cjne a, #00h,segue processo_dificil: lcall tabela_dificil segue: sjmp espera lcall mostra_dificil mov b,a lcall leitura_dificil mov P2,a cjne R5,#21,processo_dificil pressionado: mov a,p1 ljmp completou cjne a,#00h,pressionado tabela_dificil: mov a, contador mov P2,#00h compara: mov a,auxiliar mov @r0,#01h mov a,@r0 cjne a,b,errou mostra_dificil: mov auxiliar,contador clr tr1 mostra2: mov P2,#00h mov a,auxiliar mov a,auxiliar mov @r0,sequencia djnz auxiliar, volta mov a,@r0 mov a,acertos mov P2,a add a,#01 da a djnz auxiliar,mostra2 mov acertos,a inc contador 8
Figure 9: Memorex - Atrasos de tempo Table 5: Programa Memorex - Atrasos de Tempo Rótulo Mnemônico Rótulo Mnemônico Rótulo Mnemônico atraso: mov r1,#40 atrasoreduzido: mov r1,#10 atrasocurto: mov r1,#2 repete: mov r6,#100 repete1: mov r6,#100 repete2: mov r6,#50 rep: mov r4,#100 rep1: mov r4,#100 rep2: mov r4,#50 djnz r4,$ djnz r4,$ djnz r4,$ djnz r6,rep djnz r6,rep1 djnz r6,rep2 djnz r1,repete djnz r1,repete1 djnz r1,repete2 Figure 10: Memorex - Efeito para Erro e para Jogo Completo Table 6: Programa Memorex - Erros, Acertos e Tabela Aleatória Rótulo Mnemônico Rótulo Mnemônico Rótulo Mnemônico errou: clr tr1 display: push acc dezena: swap a mov a,#0ffh clr tr0 anl a,#0fh MOV R7,#30 mov th0,#0d8h orl a,#20h mov tl0,#0efh mov P0,a errou1: mov P2,a mov a,acertos clr unidade reduzido pop acc subb a,#0fh jb unidade,dezena setb tr0 djnz r7,errou1 anl a,#0fh i ljmp inicio orl a,#10h mov P0,a aleatorio: clr tr1 completou: mov a,#01h setb unidade push acc rotaciona: mov P2,a pop acc mov a,sequencia reduzido setb tr0 rr a rl a i mov sequencia,a sjmp rotaciona pop acc setb tr1 i end 9
III. Montagem do Memorex A montagem apresentada na Fig.11 é alimentada com quatro baterias de 1,5 V cada. Para reduzir a tensão de alimentação para aproximadamente 5 V foi utilizado um diodo 1N4001. Figure 11: Montagem do Jogo de Memória 10