Você está na página 1de 15

Projeto 2

Jogo Genius no 8051.


Disciplina: EN2617 - Sistemas Microprocessados.

Discentes:
Fernando Henrique Gomes Zucatelli
Rafael Pires Franco Silva
Turma: A1/Diurno
Prof Dr. Carlos Eduardo Capovilla.

Santo Andr, 07 de Novembro 2012

1. INTRODUO
O jogo Genius era um jogo popular na dcada de 1980. O jogo consistia de 4
botes coloridos que acendiam e emitiam um som caracterstico conforme uma
sequncia gerada pelo jogo. O jogador deveria pressionar os botes conforme a
sequncia informada pelo jogo, sempre partindo do primeiro ponto da sequncia e
repetindo-a conforme ela crescia at o limite selecionado pelo jogador.
O jogo era reconhecido como forma de treino de memria e reconhecimento de
cores e sons por partes das crianas.

Na Figura 1 h 2 exemplos de modelos de jogos Genius.

Figura 1 Exemplos de jogos Genius.

2. LISTA DE MATERIAIS
2.1.

Fonte Alimentao

1x Transformador 110V para 15V

4x Diodos 1N4004

1x LM7805

2x LM7812

2.2.

Microcontrolador

1x microcontrolador 8051

1x MAX232

1x LM358

1x 74HC04

4x LEDs

4x resistores 470

1x resistor 3k3

1x resistor 1k

5x capacitor 1F

1x capacitor 10nF

1x alto falante

Figura 2 Fonte de alimentao DC.

Figura 3 - Amplificador da sada de som.

Figura 4 - Ligao dos Leds.

Figura 5 - Circuito de interface para a comunicao serial.

3. FLUXOGRAMAS PROGRAMA
Para

desenvolvimento

do

programa

foram

confeccionados

alguns

fluxogramas com as instrues principais para criar o jogo. Algumas sub-rotinas


sub
no
tm fluxogramas descritos por serem simples de programar e no interferir no
funcionamento
namento geral do jogo, como o caso das sub-rotinas VITORIA e DERROTA.

Figura 6 Fluxograma principal do programa.

Figura 7 Fluxograma da Sub-rotina JOGO.

Figura 8 Fluxograma da Sub-rotina EXBIR_SEQ.

Figura 9 Fluxograma da Sub-rotina DIFICULDADE.

Figura 10 Fluxograma da Interrupo da Serial S_0..

4. PROGRAMA ASSEMBLY
A verso final do Programa desenvolvido encontra-se
se abaixo.
A evoluo do programa est descrita na seo Histrico.
As principais definies de uso de variveis (posies de memria) so
descritas quando elas
las so inicialmente preparadas, por exemplo na seo ;

Inicializando os registradores e determinando suas funes.

; Programa Projeto_2_Main_5
; Rotina principal do projeto 3.
; Jogo Genius
; Deve conter:
; Rotina de gerar aleatoriamente nmero entre #01, #02, #04, e #08 que acende o
respectivo LED e guarda na memria
;
baseada num ciclo que roda um bit enquanto o programa aguarda o boto ser
precisado
;
quando pressionado ele estoca aquele bit na pilha para a prxima posio na
sequncia
; Usar uma pilha prpria para guardar a sequncia
; Usar ponteiro da pilha prpria e um ponteiro da sequencia no jogo
; criar jogo usando a serial por ser verificado que o comportamento melhor
; criar opo de nvel de dificuldade, i.e., nmero total na sequncia, cujo limite
ser dado pela pilha
;
penso em limitar de 0 a 15 para exibir o valor em um nico display indo at
F, assim no precisa fazer rotinas
;
de trocas
;================================== Histrico ==========================
; Verso 1: Criada definies sobre o jogo, uso de Registradores e memria
;
Configurao bsica da serial
; Verso 2: Criada saidas para o subrotina JOGO, DIFICULDADE, EXIBIR_SEQ, DERROTA,
VITORIA
;
VITORIA e DERROTA no tem procedimento definidos, apenas existem
;
DIFICULDADE precisa testar os '+' e o '-'
;
EXIBIR_SEQ testada com tamanho 1 apenas
;
JOGO em desenvolvimento
;
Criado Timer0 para verificar se o jogador no est demorando muito,
porm est sendo usada
;
apenas a base de tempo de 1 ciclo, i.e., 65535 ms o que pouco para
tomar deciso
;
precisa calcular para algum tempo conveniente de espera, e.g.~=5
segundos
;
usemos R6 ou outra posio de memria entre 08h e 0Fh para guardar
quantas vezes o T_0 estourou
; Verso 3: Criado o tempo de espera condizente
;
R0 e R1 comeam em 10h e no precisam incrementar no inicio do jogo,
estava redundante
;
Programada uma rotina de VITORIA e uma de DERROTA provisrias
;
Surgiu um problema com o valor que liga na P1 e ele d errado mesmo
quando eu acerto. Descobrir o porqu.
; Verso 4: Criado a lgica para seguir o jogo at o valor de R3
;
testar mais vezes usando mais vezes o "Run" do edsim51
; Verso 5: Criado tempo de LED apagado entre as exibies
;
exibir o bot]ao quando ele apertado
;
uso de 0Bh para guardar o valor do acumulador caso a interrupo da
serial ocorra
;
no meio do ciclo "rl R2"
;
mudanas dos delays
;
acerto do display da difuculdade para o jogo
;
exibe a dificuldade na P1 enquanto ajustada (de zero a F)
;
tentando adicionar o display para mostrar sequencia do jogo
; Verso 5_2: Continuando o mostrador da etapa no display
;
Criando os sons.
; Verso 5_3: rotina de sons criada
;
Troca da subrotina delay em JOGO e EXIBIR_SEQ pela subrotina som,
;
e as frequncias posiveis so 1, 2, 4, 8 que so os valores
apontados por R1 e o valor de R4
; Verso 5_4: tempo de durao dos sons corrigido
; Verso 5_5: Corrigida posio para delay durante execuo de som. Removendo
trecho de comentrio auxiliares.
; Verso 5_6: Testadas as correes da 5_5. Corrigido velocidade de acendimento.
Criados sons para DERROTA e VITORIA
; Verso 5_7: Corrigido exibio do Display na ltima jogada com "F."
;================================== Comandos ==========================
;
;
;
;

p
o
i
u

-->
-->
-->
-->

LED:
LED:
LED:
LED:

P1.0
P1.1
P1.2
P1.3

<=>
<=>
<=>
<=>

#01
#02
#04
#08

; d --> dificuldade
; + --> inc dificuldade
; - --> dec dificuldade

; s --> start
; r --> reset game
; As posies de memria usadas alm dos registradores
; Pilha do jogo: 10h 11h ... 1Fh
;==============================
; Inicio do programa
org 0000h
Ljmp inicio
;org 0003h
;Ljmp Int_0 ; ativa atrves de P3.2
org 000Bh
Ljmp T_0 ;

; TO

;org 0013h
; ; INT1barrado ativa atravs de P3.3
;org 001Bh
;Ljmp T_1 ; ; T1
org 0023h
Ljmp S_0; ; S0
;org 002Bh
; ; T2, apenas no 805
;==============================
org 0033h
inicio:
mov SP, #2Fh; Prepara o ponteiro da Pilha fora da regio de memria que pode dar
erro
; Configurando as Interrupes
mov IE,
#10010010b ; EA _ _ ES0 ET1 EX1 ET0 EX0
mov IP,
#00000000b ; __ _ _ PS P1 PX1 P0 P0 ;1 prioridade forada
mov TMOD, #00100001b ; G1 C/T1' M11 M10 | G0 C/T0' M01 M00
;Modo 0 : 00 => 13 bits, no usado
;Modo 1 : 01 => 16 bits sem autoreload
;Modo 2 : 10 => 8 bits com autoreload
;Modo 3 : 11 => 2 contadores 8 bits sem autoreload
; Valor dos temporizadores 0
mov TH1, #0FDh ; Tprog = Ttotal - Tdesejado;
; #FDh para obter o clock de 11,059 MHz
mov TL1, #0FDh ; Quebrar o resultado em hexadecimal (16bits=65535 microseg,
8bits=255 microseg)
; TH guarda o autoreload no Modo 2
; TH1 = TL1 = #0FDh <=> Uso de serial para 11.059MHz
; Valor dos temporizadores 0
;mov TH0, #0FBh ; Tprog = Ttotal - Tdesejado
;mov TL0, #0FBh ; Quebrar o resultado em hexadecimal (16bits=65535 microseg,
8bits=255 microseg)
; TH guarda o autoreload no Modo 2
mov TCON, #01000000b ; TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0
;acionamento nivel baixo = 0; acionamento borda = 1
mov SCON, #01010000b; SM0 SM1 SM2 REN TB8 RB8 Ti Ri
;Modo x: SM0 SM1
;Modo 0 : 00 => Sinc. 8 Bits com LSB primeiro, transmitido e recebido atravs de
RxD. O TxD envia o clock
;Modo 1 : 01 => AsSinc. 10 Bits, transmitidos (via TxD) ou recebidos (viaRxD) : 1
StartBit, 8 Bits de dados com LSB primeiro e um StopBit
;Modo 2 : 10 => AsSinc. 11 Bits so transmitidos (via TxD) ou recebidos (viaRxD) :
;Modo 3 : 11 => AsSinc. 11 Bits so transmitidos (via TxD) ou recebidos (viaRxD)
mov PCON, #00h; #80h => SMOD = 1; #00h => SMOD = 0, not bit-adressable
; Inicializando o registradores e determinando suas funes
mov R0, #10h ; Ponteiro da pilha do jogo, inc a cada novo boto e guarda at aonde
o jogo j foi
mov R1, #10h ; Ponteiro da pilha do jogo, inc a cada vez que o boto pressionado,
reinicia quando igual a R7 e retorna para #0Fh

mov R2, #01h ; rl R2 continamente enquanto aguarda boto ser apertado, espero gerar
aleatoriedade com isso
mov R3, #14h ; Seletor de dificuldade, default=#14h, indica a pos do tamanho mximo
da pilha do jogo
mov R4, #00h ; Valor convertido do que foi lido no teclado pela serial
mov R5, #00h ; Controlador de caminhos, (START/RESET) JOGO, INC DIFICULDADE, DEC
DIFICULDADE,
mov R6, #00h ; usado no delay
mov R7, #00h ; usado no delay; e tambm usado para contar o tempo de espera para
apertar um boto
mov 08h, #00 ; indica que o tempo de espera estourou 08h =~ R8
mov 09h, #00 ; usado para contar os loopins em VITORIA e DERROTA
mov 0Ah, #00 ; setado antes do delay
mov 0Bh, #00 ; guarda o valor do acumulador ao entrar na interrupo da serial
mov 0Ch, #00 ; ponteiro da etapa no display
mov 0Dh, #00 ; usado na subrotina som
mov 0Eh, #00 ; usado para escolher a frequencia do som (ajusta o tamanho do delay)
mov 0Fh, #00 ; define a durao do som
; Desliga os display
mov A, #01h; seleciona display X _ _ _
mov DPTR, #0FFC1h ; Seleciona o Display ligado
movx @DPTR, A
mov A, #00h; joga zero nos displays selecionados
mov DPTR, #0FFC0h; posio da memria onde est o Display 7 seg
movx @DPTR, A
mov P1, #000h
;==============================
loop_main:
;Liga a posio do display
mov A, 0Ch; R6 guarda a posio a ser exibida da tab_dead_hell
mov dptr, #tab_led; aponta para a tabela
movc A, @A+DPTR
mov DPTR, #0FFC0h; posio da memria onde est o Display 7 seg
movx @DPTR, A
Lcall roda_left_Reg2
cjne R5, #10h, nao_jogo
mov 0Ah,#10
Lcall delay
inc 0Ch
Lcall JOGO
nao_jogo:
cjne R5, #01h, nao_DIFICULDADE
Lcall DIFICULDADE
nao_DIFICULDADE:
sjmp loop_main
;==============================
;subrotinas principais
JOGO:
cjne R5, #0ffh , continua_JOGO
ljmp saida_JOGO
continua_JOGO:
mov @R0, 02h ; R2 := 02h
;Liga a posio do display
mov A, 0Ch; R6 guarda a posio a ser exibida da tab_dead_hell
mov dptr, #tab_led; aponta para a tabela
movc A, @A+DPTR
mov DPTR, #0FFC0h; posio da memria onde est o Display 7 seg
movx @DPTR, A
;mov A, #06h
;movx @DPTR, A ; visualizando 1 no display X _ _ _ do kit
mov 0Ah, #3 ;prepra delay com 0,8 segundo
Lcall delay
Lcall EXIBIR_SEQ
mov R4, #00h
mov TH0, #00h

10

mov TL0, #00h


setb TR0 ; ligar o temporizador para esperar a pessoa apertar
Aguardo_jogador_jogar:
Lcall roda_left_Reg2; enquanto aguarda o jogador vai rodando R2
mov A, #01
cjne A, 08h, nao_estourou_tempo_de_jogo; se estourar o tempo sai do
jogo
clr TR0
clr TF0
mov 08h, #00
Lcall DERROTA
sjmp saida_JOGO
nao_estourou_tempo_de_jogo:
cjne R4, #00h, jogou ; alguma tecla foi apertada
sjmp Aguardo_jogador_jogar; se nenhuma foi apertada
R4=#00 e volta a aguardar
jogou:
; MOSTRE o que foi jogado
mov P1, R4
;===========================================================================
toca_som:
mov A, #8
mov B, R4
div AB
mov B, #30
mul AB
mov 0Fh, A
loop_som:
mov 0Eh, R4 ;a frequncia do som o valor de R4
lcall som
mov A, 0Fh
dec 0Fh
cjne A, #00h, loop_som ;compara o tempo execuo do toque
;===========================================================================
mov P1, #00h ;apague para o prximo
; AQUI DEVE DECIDIR QUAL A TECLA FOI APERTADA E SE ELA EST CERTA
clr TR0
clr TF0
mov R7, #00h; zera o contador do T_0 ~5seg
;cjne @R1, R4, errou ;esta sintaxe no existe, mas a ideia do
que feito
mov A, @R1
cjne A, 04h, errou
;acertou
;cjne R1, R0, errou ;esta sintaxe no existe, mas a
ideia do que feito
mov R4, #00 ; se no faz isso fico #04 ateo cara apertar
de novo, s que ser tarde demais!
mov A, R1
cjne A, 00h, nao_fim_subseq
mov A, R3
cjne A, 00h, nao_fim_do_jogo
Lcall VITORIA
sjmp saida_JOGO
nao_fim_do_jogo:
mov 0Ah, #1 ;prepra delay com 0,8 segundo
Lcall delay
inc R0
inc 0Ch
mov R1, #10h
ljmp JOGO
nao_fim_subseq:
inc R1
sjmp Aguardo_jogador_jogar
errou:
clr TR0
clr TF0
Lcall DERROTA
mov R1, #10h; coloca o apontador da pilha do jogo para
ver a sequencia toda
mov 0Ch, #00h
Lcall EXIBIR_SEQ

11

;sjmp saida_JOGO
;sjmp JOGO
saida_JOGO:
;reseta R0, R1, R5, etc
mov R0, #10h
mov R1, #10h
mov R4, #00h
mov R5, #00h
mov R7, #00h
mov 08h, #00h
mov 09h, #00h
mov 0Ch, #00h
clr TR0
RET
;=============
EXIBIR_SEQ:
mov P1, @R1 ; mostra valor guardado na posio apontado por R1 em P1
; faz barulhinho
;==========================================================================
toca_som_1:
mov A, #8
mov B, @R1
div AB
mov B, #30
mul AB
mov 0Fh, A
loop_som_1:
mov 0Eh, @R1 ;a frequncia do som o valor guardado na posio
apontado por R1
lcall som
mov A, 0Fh
dec 0Fh
cjne A, #00h, loop_som_1 ;compara o tempo execuo do toque
;=========================================================================
mov P1, #00h; apague os leds
; pare o barulhinho
mov 0Ah, #10 ;prepra delay com 1 segundo
Lcall delay
; cjne R1, R0, nao_fim_seq
mov A, R1
cjne A, 00h, nao_fim_seq
mov R1, #10h ;j retorna a pos inicial da Pilha do Jogo e no uma
antes conforme ele setado, que pode at ser refeito
sjmp saida_EXIBIR_SEQ
nao_fim_seq:
inc R1
sjmp EXIBIR_SEQ
saida_EXIBIR_SEQ:
RET
;=============
DIFICULDADE:
mov A, #02h; seleciona _ X _ _
mov DPTR, #0FFC1h ; Seleciona o Display ligado
movx @DPTR, A
mov A, #5Eh; joga d no display _ X _ _
mov DPTR, #0FFC0h; posio da memria onde est o Display 7 seg
movx @DPTR, A
cjne R5, #02h , nao_dificulta
inc R3
cjne R3, #20h, nao_DIFICULDADE_16
mov R3, #01fh
nao_DIFICULDADE_16:
mov R5, #00h ; se no faz isso fico #02 para sempre!
nao_dificulta:
cjne R5, #03h , nao_facilita
dec R3
cjne R3, #0fh, nao_DIFICULDADE_zero
mov R3, #010h

12

nao_DIFICULDADE_zero:
mov R5, #00h ; se no faz isso fico #03 para sempre!
nao_facilita:
mov P1, R3
cjne R5, #010h , nao_sai_DIFICULDADE
sjmp saida_DIFICULDADE
nao_sai_DIFICULDADE:
sjmp DIFICULDADE
saida_DIFICULDADE:
;mov R5, #00h ; se no faz isso fico #05 para sempre e reseta o JOGO!
mov A, #01h; seleciona X _ _ _
mov DPTR, #0FFC1h ; Seleciona o Display ligado
movx @DPTR, A
mov A, #3fh; joga 0 no display X _ _ _
mov DPTR, #0FFC0h; posio da memria onde est o Display 7 seg
movx @DPTR, A
mov P1, #00
RET
;=============
DERROTA:
mov 09h, #00h
loop_DERROTA_pisca:
inc 09h
mov A, 09h
cjne A, #10, pisca_DERROTA
mov 09h, #00
mov P1, #000h
sjmp saida_DERROTA
pisca_DERROTA:
mov P1, #00fh
;======================
mov 0Fh, #15
loop_som_der:
mov 0Eh, #15 ;a frequncia do som o valor guardado na posio
apontado por R1
lcall som
mov A, 0Fh
dec 0Fh
cjne A, #00h, loop_som_der ;compara o tempo execuo do toque
;=========================
mov P1, #006h
mov 0Ah, #1 ;prepra delay com 0,1 segundo
Lcall delay
mov P1, #000h
mov 0Ah, #1 ;prepra delay com 0,1 segundo
Lcall delay
sjmp loop_DERROTA_pisca
saida_DERROTA:
RET
;=============
VITORIA:
mov 09h, #00h
loop_VITORIA_pisca:
inc 09h
mov A, 09h
cjne A, #10, pisca_VITORIA
mov 09h, #00
sjmp saida_VITORIA
pisca_VITORIA:
mov P1, #0fh ;
;============================
mov 0Fh, #50
loop_som_vit:
mov 0Eh, #03 ;a frequncia do som o valor guardado na posio
apontado por R1
lcall som
mov A, 0Fh
dec 0Fh
cjne A, #00h, loop_som_vit ;compara o tempo execuo do toque
;=============================
mov P1, #00h ;
mov 0Ah, #1 ;prepra delay
Lcall delay
sjmp loop_VITORIA_pisca

13

saida_VITORIA:
RET
;==============================
;subrotinas auxiliares
roda_left_Reg2:
mov A, R2
rl A ;prepara o prximo visor a ser ligado
mov R2, A
cjne R2, #10h, continua_Reg2_1
mov R2, #01h
continua_Reg2_1:
RET
;===============================
som:
mov 0Dh, #00h ; aponta posio da tab_som
mov A, 0Dh; 0Dh guarda a posio a ser exibida da tab_som
mov dptr, #tab_som; aponta para a tabela
movc A, @A+DPTR
mov DPTR, #0FFC4h; posio da memria onde est o conversor D/A
movx @DPTR, A
lcall delay_rapido
inc 0Dh; prepara a prxima posio da tab-dead a ser exibida
mov A, 0Dh
cjne A, #02h, continua_Reg
mov 0Dh, #00; retorno para a primeira posio da tab_dead
continua_Reg:
RET
;====================================================
;subrotinas de tempo
delay:
;mov 0Ah, #valor ; antes de entrar no delay
loop2_delay:
mov R6, #200; 100 ms
loop1_delay:
mov R7, #250; 250 ciclo mquina
djnz R7, $; equivale 500 microsegundos
djnz R6, loop1_delay; djnz leva 2 ciclo mquina
djnz 0Ah, loop2_delay; djnz leva 2 ciclo mquina
RET
delay_rapido:
;mov R1, #200; 100 ms
loop1_rapido:
mov R7, #250; 250 ciclo mquina
djnz R7, $; equivale 500 microsegundos
djnz 0Eh, loop1_rapido; djnz leva 2 ciclo mquina
RET
;==============================
T_0:
inc R7
cjne R7, #76, diferente_T_0; conta 152 ciclos, total de 10 segundos
mov 08h, #01
mov R7, #00
diferente_T_0:
RETi
;==============================
;serial
S_0:
mov 0Bh, A
mov A, SBUF
cjne A, #'p', nao_LEDP10
mov R4, #01h
nao_LEDP10:
cjne A, #'o', nao_LEDP11
mov R4, #02h
nao_LEDP11:
cjne A, #'i', nao_LEDP12
mov R4, #04h
nao_LEDP12:
cjne A, #'u', nao_LEDP13
mov R4, #08h

14

nao_LEDP13:
cjne A, #'d', nao_ajuste_dificuldade
mov R5, #01h
nao_ajuste_dificuldade:
cjne A, #'+', nao_aumenta_difi
mov R5, #02h
nao_aumenta_difi:
cjne A, #'-', nao_diminui_difi
mov R5, #03h
nao_diminui_difi:
cjne A, #'s', nao_start
mov R5, #10h
nao_start:
cjne A, #'r', nao_reset
mov R5, #0ffh
nao_reset:
mov A, 0Bh
clr Ri; ltima coisa a ser feita para no receber uma em cima da outra
RETi
;====================================================
;tabelas
tab_led:
db 3fh, 06h, 5bh, 4fh, 66h, 6dh, 7dh, 07h, 7fh, 67h, 77h, 7ch, 39h, 5Eh, 79h, 71h,
0F1h
;
0
1
2
3
4
5
6
7
8
9
A
b
C
d
E
F
F.
tab_som:
db 00h, 0ffh
end

Você também pode gostar