Você está na página 1de 20

Projeto 3

Cofre de hotel com senha.


Disciplina: EN2617 - Sistemas Microprocessados.

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

Santo Andr, 26 de Novembro 2012

1. INTRODUO
Cofres so compartimentos prprios para armazenar dinheiro, bens ou
documentos de valor. Podem ser construdos com uma camada espessa de
concreto, ao ou madeira.
Para garantir sua inviolabilidade, possui um segredo e/ou chave, o que permite
que apenas o possuidor do segredo abra-o. Tal segredo pode ser mecnico (girando
um disco com marcaes de 00 a 99 direita e esquerda), eletrnico (digitando
uma senha em um teclado numrico) ou com uma chave.
Hoje o modelo eletrnico muito encontrado em quarto de hotis, pois de
fcil utilizao e a senha pode ser gravada no momento pelo hospede, diferente de
cofres mecnicos onde isso uma tarefa mais complicada.

Na Erro! Fonte de referncia no encontrada. podemos ver um exemplo de cofre


eletrnico.

Figura 1 Cofre eletrnico.

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

1x LCD 16 colunas por 4 linhas

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 Display LCD.

Figura 4 - Ligao dos Leds.

Figura 5 - Driver para o motor de passo.

Figura 6 - Circuito de interface para a comunicao serial.

3. FLUXOGRAMAS PROGRAMA
Para

desenvolvimento

do

programa

foram

confeccionados

alguns

fluxogramas com as instrues


strues principais para criar as rotinas de gravao de senha
e sua espera para abrir e as instrues exibidas na tela do LCD.
LCD Algumas subrotinas no tm fluxogramas descritos por serem similares a outras.
outras

Figura 7 Fluxograma principal do programa.

Figura 8 Fluxograma da Sub-rotina GRAVAR_SENHA.


GRAVAR_SENHA

Figura 9 Fluxograma da Sub-rotina CONFERIR_SENHA.

Figura 10 Fluxograma da Sub-rotina ESPERAR_SENHA


_SENHA.

4. PROGRAMA ASSEMBLY
A verso final do Programa desenvolvido encontra-se
encontra 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
so inicialmente preparadas, por exemplo na seo ;

Inicializando os registradores e determinando suas funes.


funes

; Programa Projeto_3_Main_6_1
; Rotina principal do projeto 3.
; Autores:
;
Fernando Henrique Gomes Zucatelli
;
Rafael Pires Franco Silva
;
;
;
;
;
;
;
;
;
;

Cofre de Hotel
Deve conter:
Uso: LCD, Motor de Passo, Serial
Chave e indicao de porta aberta
Digitar a senha com n letra e/ou nmeros no teclado do PC.
Usar ENTER para sair ou o limite de 16 caracteres
Guardar senha mestra de 10h a 1Fh
Guardar senha inserida de 20h a 2Fh
Guardar senha para abrir de 30h a 3Fh
mov SP, 3Fh; i.e., evita que a pilha suje a memria onde guardemos as senhas

;================================== Histrico ==========================


; Verso 1: Criada definies sobre o jogo, uso de Registradores e memria
;
Configurao bsica da serial
;
Criadas as subrotinas de acordo com Fluxograma_1
;
Colocado espao para a senha mestre.
;
Copiado blocos dos programas que manipulavam o LCD e o motor de passo
;
Testada passagem pelo fluxo do loop_main do programa
;
A sub-rotina CONFERIR_SENHA tem apenas os valores de R2 a serem setados para a
sequncia no loop_main
; Verso 2: Programadas as subrotinas: GRAVAR_SENHA, ESPERAR_SENHA
;
Acertando valores setados de R0 antes de entrar nas subrotinas
;
Detectado uso de R0 e R3 nas subrotians do MOTOR
;
Trocar varivel R0 e R3 nas subrortinas MOTOR por outras 2 prximas e no usadas ou
que no atrapalhem outra coisa
;
mov R3, #00 adicionado dentro da subrotina Resetar_Parte_Pilha
;
Adicionado mov R4, #00 nas saidas das leituras das senhas
;
Colocado tempo de estouro de ESPERA_SENHA com uso de 09h como Flag
;
Colocado cdigo ASCII do ENTER (Carriage Return - Retorno de Carro) = 0Dh
;
Colocando setb e clr na P1 para ver os passos da senha sem uso do LCD e do MOTOR
; Verso 3: Verso 2 Testada no kit sem LCD e sem MOTOR
;
Percebida a necessidade de um comando para reiniciar a entrada de senha caso erre
;
em GRAVAR_SENHA ou ESPERAR_SENHA
;
Usando o caracter / cujo ASCII = #2Fh
;
Adicionada a rotina para limpar as pilhas de escrita em GRAVAR_SENHA
;
e tambm a de leitura em ESPERAR_SENHA
;
Verso Testada e tudo ok.
; Verso 4: Criada subrotina LCD_ABERTO de forma funcional
;
Criada subrotina auxiliar LCD_clear para limpar o LCD antes de uma nova subrotina
LCD ser chamada
; Verso 4_1: Passando a usar R5 para evitar que o LCD seja escrito repetdamente em loops
;
Alterados os nmeros de quebra de linha nas tab_LCD, sendo o ltimo sempre em 00
;
e os anteriores maiores, isso facilita a lgica dos cjne para quebrar as linhas
;
Adicionadas nas subrotinas LCD_ as linhas para ler as suas tabelas, que uma cpia
com Labels trocados
;
As tab_LCD tem o nmero 5 para ser usado no simulador, deve ser trocado por cada
linha comentada abaixo do db
;
Corrigido equvoco do uso de 08h como ponteiro das tab_LCD, o correto sempre usar
o 0Bh, at daria certo,
;
porque 08h setado apenas antes do delay, mas melhor deixar as coisas separadas.
; Verso 4_2: Criada subrotina LCD_generico e uso da pos 0Dh
;
ODh setada em cada LCD_NOME, com um nmero, este nmero indicar a tabela
tab_LCD_NOME que ser usada
;
para escrever no LCD, assim economiza-se linhas e labels
; Verso 5: Trocado R0 por 0Eh nas subrotinas MOTOR, R3 mantido porque s um contador
do nmero de passos
; Verso 5_1: Trocado o 5 nas tab_LCD pelo texto correto.
;
Corrigido erro de mov P1, #00 para mov P1,#0F0h para que a chave continue sendo
chave
;
Corrigido uso de Ro em vez de 0Eh nas rotinas do motor.
;
Corrigida entrada de senha imediata quando a porta era fechada.
; Verso 5_2: Criada rotina que exibe "*" durante digitaes da senha e limpa a digitao
quando tecla "/"
;
Criada Senha Mestre

; Verso 6: Adicionado Opo de Backspace para retirar o ltimo valor digitado da pilha e
tambm remover o asterisco
;
do LCD
; Verso 6_1: Testado no kit, a senha est ok com o Backspace. S que o Visor do LCD
continus apagando
;
alm do ponto final para digitar a senha. Este problema da Verso 6 foi corrigido
na 6_1.
;
Usando 2 Subrotinas para definir se o LCD ser incrementado ou decrementado
;
Alterados LCd para informar sobre a velocidade de digitao e sobre o Teclado ser
Case Sensitive.
;
Removidas tabelas desnecessrias
;================================== Comandos ==========================
; ENTER
<=> ASCII = #0Dh--> Confirma a gravao e a entrada da senha
; /
<=> ASCII = #2Fh--> Reinicia a gravao e a entrada da senha
; BackSpace
<=> ASCII = #08h--> Apaga o ltimo valor digitado na gravao e na
entrada da senha
;==============================
; 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, #3Fh; 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 1
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

10

;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
;Parmetros LCD
; FFC2 Endereo para gravao de instruo WR
; FFD2 Endereo para gravao de dados no LCD WR
; FFE2 Endereo para leitura de instruo RD
; FFF2 Endereo para leitura de dados no LCD RD
lcall monitora_BF
mov DPTR, #0FFC2h
mov A, #38h
movx @DPTR, A ; function set
lcall LCD_incrementar_06
lcall monitora_BF
mov DPTR, #0FFC2h
mov A, #0Fh
movx @DPTR, A ; Display on/off control
Lcall LCD_clear
mov DPTR, #0FFC6h; Seleciona o Motor de Passo
mov A, #00h;
movx @DPTR, A; Desliga o Motor de Passo
; Inicializando o registradores e determinando suas funes
mov R0, #20h ; Ponteiro da pilha das senhas gravadas e inseridas
mov R1, #10h ; Ponteiro da pilha da senha na comparao
mov R2, #00h ; Indica que a senha est correta/incorreta/mestre
mov R3, #00h ; Garante que a limpeza da pilha seja de X0h a XFh, i.e, conta de 0 a F com
inc R3
; R3 nas subrortinas MOTOR conta o nmero de passos
mov R4, #00h ; Valor ASCII do que foi lido no teclado pela serial, R4 = 00, no veio nada
usvel
mov R5, #00h ; Monitora se j foi escrito no LCD quando este estiver usado em loops
mov R6, #00h ; usado no delay e setado antes do delay_rapido
mov R7, #00h ; usado no delay e do delay_rapido. Auxiliar para cjne 0Dh, #valor. em
LCD_generico. Contador de estouros de Timer0 em ESPERA_SENHA
mov 08h, #00 ; Setado antes do delay
mov 09h, #00 ; Indica que o tempo de espera estourou 09h =~ R9
mov 0Ah, #00 ; Guarda o valor do acumulador ao entrar na interrupo da serial
mov 0Bh, #00 ; Guarda valor de tabela para o LCD
mov 0Ch, #00 ; Auxiliar para comparar 2 posies apontadas @R0, @R1, cjne @R0, @R1
mov 0Dh, #00 ; Ponteiro do tipo Case, para cada tab a ser lida nos rotina LCD_genrico
mov 0Eh, #00 ; Guarda a posio do MOTOR de passo
;mov 0Fh, #00 ;
mov R1, #1Fh; prepara para limpar a pilha senha 20h -> 2Fh
Lcall Resetar_Parte_Pilha
mov R1, #2Fh; prepara para limpar a pilha senha 30h -> 3Fh
Lcall Resetar_Parte_Pilha
;Senha mestre:
mov 010h, #50h
mov 011h, #72h
mov 012h, #6Fh
mov 013h, #66h
mov 014h, #2Eh
mov 015h, #43h
mov 016h, #61h
mov 017h, #70h
mov 018h, #6Fh
mov 019h, #76h
mov 01Ah, #69h
mov 01Bh, #6Ch
mov 01Ch, #6Ch
mov 01Dh, #61h
mov 01Eh, #31h
mov 01Fh, #30h
; Desliga os display
mov A, #01h; seleciona display X _ _ _
mov DPTR, #0FFC1h ; Seleciona o Display ligado
movx @DPTR, A

11

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, #0F0h
;clr P1.4 ;Linha auxiliar para o simulador
;==============================
loop_main:
jb P1.4, chamar_LCD_ABERTO; P1.4=0 (porta aberta) ento pule; Linha no kit
;jnb P2.4, chamar_LCD_ABERTO; Linha da cima usada no simulador
clr P1.3
sjmp Continuar_loop_main
chamar_LCD_ABERTO:
setb P1.3
mov 0Bh, #00
Lcall LCD_ABERTO
sjmp loop_main
Continuar_loop_main:
Lcall LCD_clear
Lcall LCD_SENHA
mov R0, #20h; R0 apontar pra pos 20h da mem. onde a senha gravada
mov R4, #00h; Garante que uma senha digitada com a porta aberta no seja aceita
Lcall LCD_posiciona_asterisco_senha
Lcall GRAVAR_SENHA
Lcall LCD_clear
mov R5, #00
jb P1.4, loop_main; Linha no kit
;jnb P2.4, loop_main; Linha da cima usada no simulador
mov R3, #48
Lcall MOTOR_TRANCAR ;esta funcionando, comento para agilizar os testes
loop_esperar_senha:
Lcall LCD_clear
Lcall LCD_TRANCADO
mov R0, #30h; R0 apontar para a pos 30h da mem. onde a senha guardada para
conferncia
setb TR0
Lcall LCD_posiciona_asterisco_senha
mov R4, #00h; Garante que uma senha digitada com a porta aberta no seja aceita
Lcall ESPERAR_SENHA
clr TR0
mov TH0, #00
mov TL0, #00
mov R0, #1Fh; prepara para a pilha senha 20h -> 2Fh
mov R1, #2Fh; prepara para a pilha senha 30h -> 3Fh
mov R2, #00; valor antes de entrar em CONFERIR_SENHA
Lcall CONFERIR_SENHA
Lcall LCD_clear
cjne R2, #01h, Continua_Reg_2_CORRETA
Lcall LCD_SENHA_INCORRETA
mov R1, #02Fh; prepara para a pilha senha 30h -> 3Fh
Lcall Resetar_Parte_Pilha
mov R1, #01Fh
sjmp loop_esperar_senha
Continua_Reg_2_CORRETA:
cjne R2, #02h, Continua_Reg_2_CORRETA_MESTRE
Lcall LCD_SENHA_CORRETA
sjmp Continua_Reg_2
Continua_Reg_2_CORRETA_MESTRE:
Lcall LCD_SENHA_CORRETA_MESTRE
Continua_Reg_2:
mov R3, #48
Lcall MOTOR_ABRIR ;esta funcionando, comento para agilizar os testes
mov R1, #1Fh; prepara para limpar a pilha senha 20h -> 2Fh
Lcall Resetar_Parte_Pilha

12

mov R1, #2Fh; prepara para limpar a pilha senha 30h -> 3Fh
Lcall Resetar_Parte_Pilha
mov R5, #00; habilita escrita no loop que tem o LCD_ABERTO
Lcall LCD_clear
Ljmp loop_main
;==============================
;subrotinas principais
LCD_ABERTO:
cjne R5, #00, saida_LCD_ABERTO; se R5=#00 ento escreve
mov 0Bh, #00 ; Zera o ponteiro de tabelas
mov 0Dh, #01 ; Seleciona a tab_LCD_ABERTO
Lcall LCD_generico
saida_LCD_ABERTO:
mov R5, #01; j escreveu no LCD, s escreve quando R5=#00
RET
;=============
LCD_SENHA:
mov 0Bh, #00 ; Zera o ponteiro de tabelas
mov 0Dh, #02 ; Seleciona a tab_LCD_SENHA
Lcall LCD_generico
RET
;=============
LCD_TRANCADO:
mov 0Bh, #00 ; Zera o ponteiro de tabelas
mov 0Dh, #03 ; Seleciona a tab_LCD_TRANCADO
Lcall LCD_generico
RET
;=============
LCD_SENHA_CORRETA:
;teste no kit
mov P1, #12
;teste no kit
mov 0Bh, #00 ; Zera o ponteiro de tabelas
mov 0Dh, #04 ; Seleciona a tab_LCD_SENHA_CORRETA
Lcall LCD_generico
mov 08h, #15
Lcall delay
mov P1, #0F0h
RET
;=============
LCD_SENHA_CORRETA_MESTRE:
;teste no kit
mov P1, #0Fh
;teste no kit
mov 0Bh, #00 ; Zera o ponteiro de tabelas
mov 0Dh, #05 ; Seleciona a tab_LCD_SENHA_CORRETA_MESTRE
Lcall LCD_generico
mov 08h, #15
Lcall delay
mov P1, #0F0h
RET
;=============
LCD_SENHA_INCORRETA:
;teste no kit
mov P1, #10
;teste no kit
mov 0Bh, #00 ; Zera o ponteiro de tabelas
mov 0Dh, #06 ; Seleciona a tab_LCD_SENHA_INCORRETA
Lcall LCD_generico

13

mov 08h, #15


Lcall delay
mov P1, #0F0h
RET
;=============
MOTOR_ABRIR:
cpl P1.2
mov A, 0Eh;
mov dptr, #tab_meio_passo; aponta para a tabela
movc A, @A+DPTR
mov DPTR, #0FFC6h; Seleciona o Motor de Passo
movx @DPTR, A
dec 0Eh
mov A, 0Eh
;cjne 0Eh ,#0ffh, continua_AH ; instruo no existe
cjne A ,#0ffh, continua_AH
mov 0Eh, #07h
continua_AH:
mov R6, #100
Lcall delay_rapido
djnz R3, MOTOR_ABRIR
mov R3, #48
RET
;=============
MOTOR_TRANCAR:
cpl P1.3
mov A, 0Eh;
mov dptr, #tab_meio_passo; aponta para a tabela
movc A, @A+DPTR
mov DPTR, #0FFC6h; Seleciona o Motor de Passo
movx @DPTR, A
inc 0Eh
mov A, 0Eh
;cjne 0Eh ,#0ffh, continua_AH ; instruo no existe
cjne A ,#08h, continua_H
mov 0Eh, #00h
continua_H:
mov R6, #100
Lcall delay_rapido
djnz R3, MOTOR_TRANCAR
mov R3, #48
RET
;=============
GRAVAR_SENHA:
;mov R0, #20h; setado antes de entrar obrigatoriamente
; ENTER o cdigo ASCII #ODh
jb P1.4, saida_GRAVAR_SENHA_porta_aberta; se P1.4 = 0 sai; linha do kit
;jnb P2.4, saida_GRAVAR_SENHA_porta_aberta; Linha do Simulador
setb P1.0
cjne R4, #00, Continua_GRAVAR_SENHA_Reg4
sjmp GRAVAR_SENHA
Continua_GRAVAR_SENHA_Reg4:
cjne R4, #2Fh, Continua_nao_teclou_reiniciou
mov R1, #1Fh; Teclou / => Digitao Senha Reiniciar => voltar
GRAVAR_SENHA
Lcall Resetar_Parte_Pilha
mov R0, #20h
Lcall LCD_clear
Lcall LCD_SENHA
mov R4, #00
Lcall LCD_posiciona_asterisco_senha
sjmp GRAVAR_SENHA
Continua_nao_teclou_reiniciou:
cjne R4, #0Dh, Continua_nao_teclou_ENTER

14

sjmp saida_GRAVAR_SENHA; Teclou ENTER => Digitao Senha Finalizada =>


sair
Continua_nao_teclou_ENTER:
cjne R4, #08h, Continua_nao_teclou_backspace
cjne R0, #20h, nao_inicio_pilha
mov R0, #21h; esta pilha inicia em 20h, se est no 20h, o dec
R0, a sequncia garante estar no 20h
sjmp nao_limpe_um_asterisco
nao_inicio_pilha:
Lcall LCD_limpa_um_asterisco_senha
nao_limpe_um_asterisco:
dec R0
mov @R0, #00; garante que no ter nada errado na posio de memria
;rotina para o LCD ir para trs
mov R4, #00
sjmp GRAVAR_SENHA
Continua_nao_teclou_backspace:
mov @R0, 04h
inc R0
mov R4, #00
mov DPTR, #0FFD2h
mov A, #'*'
movx @DPTR, A;
cjne R0, #30h, GRAVAR_SENHA
sjmp saida_GRAVAR_SENHA; Encheu a pilha da senha => sair
saida_GRAVAR_SENHA_porta_aberta:
mov R1, #1Fh
Lcall Resetar_Parte_Pilha
saida_GRAVAR_SENHA:
mov R4, #00h
clr P1.0
RET
;=============
ESPERAR_SENHA:
;mov R0, #30h; setado antes de entrar obrigatoriamente
setb P1.1
mov A, 09h
cjne A, #00, estourou_tempo_ESPERAR_SENHA
cjne R4, #00, Continua_ESPERAR_SENHA_Reg4
sjmp ESPERAR_SENHA
Continua_ESPERAR_SENHA_Reg4:
cjne R4, #2Fh, Continua_ESPERAR_nao_teclou_reiniciou
mov R1, #2Fh; Teclou / => Digitao Senha Reiniciar => voltar
GRAVAR_SENHA
Lcall Resetar_Parte_Pilha
mov R0, #30h
Lcall LCD_clear
Lcall LCD_TRANCADO
mov R4, #00
Lcall LCD_posiciona_asterisco_senha
sjmp ESPERAR_SENHA
Continua_ESPERAR_nao_teclou_reiniciou:
cjne R4, #0Dh, Continua_ESPERAR_SENHA_nao_teclou_ENTER
sjmp saida_ESPERAR_SENHA; Teclou ENTER => Digitao Senha
Finalizada => sair
Continua_ESPERAR_SENHA_nao_teclou_ENTER:
cjne R4, #08h, Continua_ESPERAR_SENHA_nao_backspace
cjne R0, #30h, nao_inicio_pilha_ESPERAR_SENHA
mov R0, #31h; esta pilha inicia em 20h, se est no 20h, o
dec R0, a sequncia garante estar no 20h
sjmp nao_limpe_um_asterisco_ESPERAR_SENHA

15

nao_inicio_pilha_ESPERAR_SENHA:
Lcall LCD_limpa_um_asterisco_senha
nao_limpe_um_asterisco_ESPERAR_SENHA:
dec R0
mov @R0, #00; garante que no ter nada errado na posio de
memria
;rotina para o LCD ir para trs
mov R4, #00
sjmp ESPERAR_SENHA
Continua_ESPERAR_SENHA_nao_backspace:
mov @R0, 04h
inc R0
mov R4, #00
mov DPTR, #0FFD2h
mov A, #'*'
movx @DPTR, A;
clr TR0
mov TH0, #00h
mov TL0, #00h
mov R7, #00h
setb TR0
cjne R0, #40h, ESPERAR_SENHA
sjmp saida_ESPERAR_SENHA; Encheu a pilha da senha => sair
estourou_tempo_ESPERAR_SENHA:
clr TR0
mov 09h, #00
cjne R0, #30h, limpa_LCD_ESPERAR_SENHA
sjmp nao_limpa_LCD_ESPERAR_SENHA
limpa_LCD_ESPERAR_SENHA:
Lcall LCD_clear
Lcall LCD_TRANCADO
mov R4, #00
Lcall LCD_posiciona_asterisco_senha
nao_limpa_LCD_ESPERAR_SENHA:
mov R1, #2Fh; prepara para limpar a pilha senha 30h -> 3Fh
Lcall Resetar_Parte_Pilha
mov R0, #30h
setb TR0
Ljmp ESPERAR_SENHA
saida_ESPERAR_SENHA:
mov R4, #00h
clr P1.1
RET
;=============
CONFERIR_SENHA:
;mov R0, #1Fh; prepara para a pilha senha 20h -> 2Fh
;mov R1, #2Fh; prepara para a pilha senha 30h -> 3Fh
;mov R2, #00; valor antes de entrar em CONFERIR_SENHA
setb P1.2
inc R0
inc R1
mov A, @R0
mov 0Ch, @R1
;cjne @R0, @R1, Errou_senha ; esta instruo no existe
cjne A, 0Ch, Errou_senha
cjne R1, #3fh, CONFERIR_SENHA
; Acertou_senha
mov R2, #02; senha correta
sjmp saida_CONFERIR_SENHA

16

Errou_senha:
mov R0, #0Fh; prepara para a pilha senha 10h -> 1Fh
mov R1, #2Fh; prepara para a pilha senha 30h -> 3Fh
loop_verificar_senha_mestre:
inc R0
inc R1
mov A, @R0
mov 0Ch, @R1
;cjne @R0, @R1, Errou_senha_mestre ; esta instruo no existe
cjne A, 0Ch, Errou_senha_mestre
cjne R1, #3fh, loop_verificar_senha_mestre
; Acertou_senha_mestre
mov R2, #03; senha correta mestre
sjmp saida_CONFERIR_SENHA
Errou_senha_mestre:
mov R2, #01; senha incorreta
saida_CONFERIR_SENHA:
clr P1.2
RET
;==============================
;subrotinas auxiliares
Resetar_Parte_Pilha:
mov R3, #00h
loop_Resetar_Parte_Pilha:
inc R1; inicia a limpeza com (X+1)h onde antes de entrar mov R1, Xh
mov @R1, #00h
inc R3
cjne R3, #16, loop_Resetar_Parte_Pilha
mov R3, #00h
RET
;=============
monitora_BF:
mov DPTR, #0FFE2h
movx A, @DPTR;
jb Acc.7, monitora_BF ; a busy flag esta na MSB do acumulador
RET
;=============
LCD_generico:
lcall monitora_BF
mov R7, 0Dh
;cjne 0Dh, #01, nao_tab_LCD_ABERTO ; instruo no existe
cjne R7, #01, nao_tab_LCD_ABERTO
mov dptr, #tab_LCD_ABERTO; aponta para a tabela
nao_tab_LCD_ABERTO:
cjne R7, #02, nao_tab_LCD_SENHA
mov dptr, #tab_LCD_SENHA; aponta para a tabela
nao_tab_LCD_SENHA:
cjne R7, #03, nao_tab_LCD_TRANCADO
mov dptr, #tab_LCD_TRANCADO; aponta para a tabela
nao_tab_LCD_TRANCADO:
cjne R7, #04, nao_tab_LCD_SENHA_CORRETA
mov dptr, #tab_LCD_SENHA_CORRETA; aponta para a tabela
nao_tab_LCD_SENHA_CORRETA:
cjne R7, #05, nao_tab_LCD_SENHA_CORRETA_MESTRE
mov dptr, #tab_LCD_SENHA_CORRETA_MESTRE; aponta para a tabela
nao_tab_LCD_SENHA_CORRETA_MESTRE:
cjne R7, #06, nao_tab_LCD_SENHA_INCORRETA
mov dptr, #tab_LCD_SENHA_INCORRETA; aponta para a tabela
nao_tab_LCD_SENHA_INCORRETA:

17

mov A, 0Bh; 0Bh guarda a posio a ser exibida da tab


movc A, @A+DPTR
cjne A ,#00, nao_saida_LCD_generico
sjmp saida_LCD_generico
nao_saida_LCD_generico:
cjne A, #01, quebra_1_LCD_generico
lcall monitora_BF
mov DPTR, #0FFC2h
mov A, #090h ; LCD na posio 40h, i.e., linha 2 coluna 1
movx @DPTR, A ; function set
quebra_1_LCD_generico:
cjne A, #02, quebra_2_LCD_generico
lcall monitora_BF
mov DPTR, #0FFC2h
mov A, #0C0h ; LCD na posio 10h, i.e., linha "3" coluna 1
movx @DPTR, A ; function set
quebra_2_LCD_generico:
cjne A, #03, quebra_3_LCD_generico
lcall monitora_BF
mov DPTR, #0FFC2h
mov A, #0D0h ; LCD na posio 10h, i.e., linha "3" coluna 1
movx @DPTR, A ; function set
quebra_3_LCD_generico:
mov DPTR, #0FFD2h
movx @DPTR, A;
inc 0Bh
mov R6, #10
lcall delay_rapido
sjmp LCD_generico
saida_LCD_generico:
mov R7, #00
mov 0Bh, #00; Zera o apontador de tabela
RET
;=============
LCD_clear:
lcall monitora_BF
mov DPTR, #0FFC2h
mov A, #01h
movx @DPTR, A ; clear display
RET
;=============
LCD_posiciona_asterisco_senha:
lcall monitora_BF
mov DPTR, #0FFC2h
mov A, #0D0h ; LCD na posio 10h, i.e., linha "3" coluna 1
movx @DPTR, A ; function set
RET
;=============
LCD_incrementar_06:
;rotina para o LCD ir para frente
lcall monitora_BF
mov DPTR, #0FFC2h
mov A, #06h ; LCD decrementa
movx @DPTR, A ; entry mode set
RET
;=============
LCD_decrementar_04:
;rotina para o LCD ir para frente
lcall monitora_BF
mov DPTR, #0FFC2h
mov A, #04h ; LCD decrementa
movx @DPTR, A ; entry mode set
RET
;=============

18

LCD_limpa_um_asterisco_senha:
;rotina para o LCD ir para trs
Lcall LCD_decrementar_04
lcall monitora_BF
mov DPTR, #0FFD2h
mov A, #' '; insere espao onde havia um asterisco
movx @DPTR, A;
;rotina para o LCD ir para frente
Lcall LCD_incrementar_06
lcall monitora_BF
mov DPTR, #0FFD2h
mov A, #' '; insere espao onde havia um asterisco
movx @DPTR, A;
;rotina para o LCD ir para trs
Lcall LCD_decrementar_04
lcall monitora_BF
mov DPTR, #0FFD2h
mov A, #' '; insere espao onde havia um asterisco
movx @DPTR, A;
;rotina para o LCD ir para frente
Lcall LCD_incrementar_06
RET
;====================================================
;subrotinas de tempo
delay:
;mov 08h, #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 08h, loop2_delay; djnz leva 2 ciclo mquina
RET
;=============
delay_rapido:
;mov R6, #200; 100 ms
loop1_rapido:
mov R7, #250; 250 ciclo mquina
djnz R7, $; equivale 500 microsegundos
djnz R6, loop1_rapido; djnz leva 2 ciclo mquina
RET
;==============================
T_0:
inc R7
cjne R7, #76, diferente_T_0; contar 76 ciclos => total de ~5 segundos
mov 09h, #01; Indica que o tempo de espera estourou
mov R7, #00
diferente_T_0:
RETi
;==============================
;serial
S_0:
mov 0Ah, A
mov A, SBUF
mov R4, A
mov A, 0Ah
clr Ri; ltima coisa a ser feita para no receber uma em cima da outra
RETi
;====================================================
;tabelas
tab_passo:
db 01, 02, 04, 08
tab_meio_passo:

19

db 01, 03, 02, 06, 04, 12, 08, 09


tab_LCD_ABERTO:
db "COFRE ABERTO", 02, "FAVOR FECHAR", 01, "A PORTA", 00
;db 'COFRE ABERTO
;FAVOR FECHAR
;A PORTA', 00
tab_LCD_SENHA:
db "FAVOR PROGRAMAR", 02, "A NOVA SENHA",
;'FAVOR PROGRAMAR
;A NOVA SENHA'

01, "NAO TECLE RAPIDO", 00

tab_LCD_TRANCADO:
db "COFRE TRANCADO", 01, "DIGITE A SENHA", 00
;COFRE TRANCADO
;DIGITE A SENHA
tab_LCD_SENHA_CORRETA:
db "Senha correta", 00
;db 'Senha correta'
tab_LCD_SENHA_CORRETA_MESTRE:
db "Senha correta", 01, "mestre", 00
;db 'Senha correta mestre'
tab_LCD_SENHA_INCORRETA:
db "Senha incorreta", 02, "
; 'Senha incorreta'
end

Teclado Case", 01, "

Sensitive", 03, " Digite Devagar", 00