Aprenda a trabalhar com as memórias EPROM do tipo UVPROM, que necessitam da Luz Ultravioleta para serem apagadas.
Neste artigo você vai aprender como apagar uma memória EPROM 27C512 com luz Ultravioleta UV e fazer a gravação de um novo programa com o programador de memórias Minipro / TL866 II plus.
Escolhemos uma placa de sucata de impressora antiga para o nosso aprendizado.
Figura 1 - Placa de sucata com o microcontrolador 80C32 e memória EPROM 27C512.
Figura 2 - Memória EPROM 27C512 de 64 kB com a janela de quartzo sem o selo.
Figura 3 - Pinos da memória EPROM 27C512. Fonte: datasheet da ST.
Figura 4 - Exemplo de diagrama de um circuito com uma memória EPROM.
Figura 5 - Equipamentos para trabalhar com as memórias EPROM.
Vejamos o que dizem os datasheets das memórias EPROMs com relação a forma de apagá-las.
Fonte: datasheet da EPROM M27C512 da ST.
Fonte: datasheet da EPROM TMS27C512 da TI.
Resumindo tudo: para apagarmos o conteúdo da memória temos que utilizar um apagador de EPROM, que possui uma lâmpada Ultravioleta, e deixar nosso chip lá dentro durante 20 minutos com a janela de quartzo exposta a luz UV! Simples assim né! :)
Figura 6 - Memória pronta para ser limpa com o Apagador de EPROM.
Figura 7 - Memória EPROM sendo apagada com Luz Ultravioleta.
Depois de apagar a memória EPROM todos os bits passam para o nível lógico 1 (bytes com valor FF em hexadecimal).
Dizemos que a memória está limpa, ou em branco, e pode ser gravada com um novo programa.
Existem diversos modelos de programadores no mercado. Neste post vamos utilizar o programador de memórias Minipro / TL866 II plus da XGecu.
Figura 8 - Memória encaixada no soquete ZIF do programador Minipro / TL866 II plus.
Figura 9 - Software XGpro para programação de memórias.
Figura 10 - Programa .HEX ou .BIN aberto no programador.
Figura 11 - Processo de programação e verificação do programa na memória EPROM.
Devemos proteger novamente a janela de quartzo do chip com um selo para evitar que o programa seja apagado parcialmente ao ser exposto a luz solar ou lâmpadas fluorescente.
Figura 12 - Memória EPROM já programada, montada na placa e com o selo na janela de quartzo.
Acompanhe no vídeo todo o processo passo-a-passo para Apagar e Programar uma memória EPROM 27C512!
Vídeo 1 - 80C32 + EPROM - Como Apagar e Gravar a Memória EPROM 27C512
Transformando uma placa de sucata em um Kit de Desenvolvimento 8051: Microcontrolador 80C32 com memória de programa externa EPROM 27C512.
Projeto 8051 Pisca LED a 1 Hz no Port P1.4.
Você vai aprender a trabalhar com a memória EPROM 27C512, como fazer o apagamento da memória com luz Ultra Violeta e fazer a gravação com o programador Minipro / TL866 II plus.
Figura 1 - Diagrama do circuito com o Microcontrolador 80C32 e memória externa EPROM 27C512.
Figura 2 - Placa de sucata com o Microcontrolador 80C32 e memória externa EPROM 27C512.
Figura 3 - Ferramentas utilizadas.
Código para o primeiro projeto 8051 Pisca LED 1 Hz.
;############ PISCA LED 1 HZ ###############
; MICROCONTROLADOR 8051
; COMPILADOR ASM51 ou Keil
; MAIO/2013 M.R.G. original placa desenvolvimento aT89s82
; MARC/2021 M.R.G. adaptado para placa 80c32 + EPROM 27C512
; PINO 5, P1.4 = LED
$MOD51
; *************** DEFINE CONSTANTES **************
TEMPO10MS EQU 9210
LED EQU P1.4
ENABLE_INPUT_DRIVE_MTA011 EQU P3.5
;*************** VETOR DE RESET ****************************************
ORG 000H
LJMP INICIO
;************************** MAIN ***************************************
ORG 100H
INICIO:
;CONFIGURA TIMER0
MOV TMOD,#00000001B ;TIMER 0 MODO 1 - 16 BITS
; HABILITA ENTRADAS DO DRIVE MTA011 - TEM PORTA INVERSORA LS05 ENTRE 80C32 E MTA011
CLR ENABLE_INPUT_DRIVE_MTA011 ;QUANDO EM ZERO HABILITA DRIVE
LOOP:
MOV R0, #50D ;50 X 10 MS = 500 MS
DELAY10MS:
MOV TL0, #LOW (65535-TEMPO10MS) ;CARREGA VALOR PARA TIMER 0
MOV TH0, #HIGH(65535-TEMPO10MS)
SETB TR0 ;LIGA TIMER 0
JNB TF0, $ ;AGUARDA FIM DA CONTAGEM
CLR TR0 ;LIMPA FLAG
CLR TF0
DJNZ R0, DELAY10MS ;DECREMENTA E VERIFICA SE TERMINOU OS 50 LOOPS
CPL LED ;INVERTE SAIDA PARA O LED
LJMP LOOP
END
Figura 4 - Código em Assembly do programa 8051 Pisca LED 1Hz.
Figura 5 - Apagando a memória EPROM com Luz Ultravioleta.
Figura 6 - Programando a memória EPROM com Minipro TL866 II plus.
Figura 7 - Placa 80C32 rodando o programa. LED piscando a 1 Hz
Assista ao vídeo para ver como ficou nosso projeto:
Vídeo 1 - 80C32 EPROM - O primeiro projeto 8051 Pisca LED 1 Hz.
Referência:
NICOLOSI, D. E. C.; Laboratório de Microcontroladores: Treino de instruções, hardware e software. São Paulo: Érica, 2002.
Transformando uma placa de sucata em um Kit de Desenvolvimento 8051: Microcontrolador 80C32 com memória de programa externa EPROM 27C512.
Projeto Teste da Comunicação Serial com o 8051: o programa inicia e envia algumas mensagens de texto para o computador pela comunicação serial. Depois passa a aguardar dados vindos pela serial e retorna os caracteres para o computador como uma função de echo. A cada dado recebido o 8051 inverte o status do LED ligado no Port P1.4. Trabalha com a Interrupção Serial.
Você vai aprender a trabalhar com a memória EPROM 27C512, como fazer o apagamento da memória com luz Ultra Violeta e fazer a gravação com o programador Minipro / TL866 II plus.
Figura 1 - Diagrama do circuito com o Microcontrolador 80C32 e memória externa EPROM 27C512.
Figura 2 - Placa de sucata com o Microcontrolador 80C32 e memória externa EPROM 27C512.
Figura 3 - Ferramentas utilizadas.
Código do projeto Testando a Comunicação Serial do 8051.
;############ PROGRAMA 8051 COM LED E SERIAL ###############
; ENVIA MENSAGENS INICIAIS PARA O COMPUTADOR
; DEVOLVE DADO RECEBIDO PARA O COMPUTADOR E INVERTE STATUS DO LED
; COMPILADOR ASM51 ou Keil
; V 1.1 ABRIL/2013 PLACA AT89S52
; V 1.2 MARÇO/2021 ADAPTADO PARA PLACA 80C32
; v 1.3 CORRIGIDO BUG DA INTERRUPCAO SERIAL
; M.R.G.
; PINO 10, P3.0 = RX
; PINO 11, P3.1 = TX
; PINO 5, P1.4 = LED
; PINO 15, P3.5 = enable drive MTA011
$MOD51
; *************** DEFINE CONSTANTES **************
TEMPO EQU 60535
TEMPO2 EQU 15535
STRING01 EQU 0500h
STRING02 EQU 0520h
STRING03 EQU 0540h
STRING04 EQU 0560h
STRING05 EQU 0580h
STRING06 EQU 0600h
STRING07 EQU 0620h
STRING08 EQU 0640h
TRANSMIT EQU F0 ;UTILIZANDO BIT DO PSW PARA FLAG DE TRANSMISSÃO
LED EQU P1.4
ENABLE_INPUT_DRIVE_MTA011 EQU P3.5
; ******************** DECLARACAO DE VARIAVEIS DA RAM **********************
;*************** VETOR DE RESET **********************************************
ORG 000H
MOV R0, #0FFH
LJMP INICGERAL
;****************** TRATAMENTO DA INTERRUPÇÃO SERIAL ***************************
ORG 023H
LJMP INT_SERIAL
ORG 100H
INT_SERIAL:
JNB RI, INT_TX ;SEPARA POR SOFTWARE A INTERRUPCAO DA TRANSMISSAO E DA RECEPCAO
INT_RX:
MOV A,SBUF ;MOVE DADO RECEBIDO DA SERIAL PARA R1
MOV R1, A ;MOVE DADO DO ACUMULADOR PARA REGISTRADOR R1
CALL TRANSMITE ;DEVOLVE DADO RECEBIDO PARA O COMPUTADOR
CPL LED ;INVERTE SAIDA DO LED
CLR RI ;LIMPA FLAG DE RECEPCAO SERIAL
INT_TX:
CLR TI ;LIMPA FLAG DE TRANSMISSAO SERIAL
RETI
;************************** MAIN ***************************************
INICGERAL:
; HABILITA ENTRADAS DO DRIVE MTA011 - TEM PORTA INVERSORA LS05 ENTRE 80C32 E MTA011
CLR ENABLE_INPUT_DRIVE_MTA011 ;QUANDO EM ZERO HABILITA DRIVE
;CONFIGURA SERIAL
MOV TMOD,#00100001B ;TIMER 1 NO MODO2 TIMER 0 MODO 1
MOV TH1,#232D ;VALOR DA RECARGA AUTOMÁTICA PARA BAUD RATE = 2400 @11,0592 MHz
SETB TR1 ;LIGO TIMER1
MOV A,PCON
SETB ACC.7 ;SETA BIT SMOD PARA TER BAUD RATE = 2400
MOV PCON,A
;MOV IE,#10010000B ;HABILITA INTERRUPÇÃO GERAL E SERIAL
MOV SCON,#01000000B ;MODO 1 DA SERIAL, DESABILITA RECEPÇÃO
; ENVIA MENSAGENS INICIAIS PELA SERIAL - COM AS INTERRUPCOES DESABILITADAS
MENSAGEM7:
MOV DPTR, #STRING07 ;carrega endereço da string
LCALL WRITESTRING
LCALL ENVIA_ENTER
LCALL ATRASO
MENSAGEM1:
MOV DPTR, #STRING01 ;carrega endereço da string
LCALL WRITESTRING
LCALL ENVIA_ENTER
LCALL ATRASO
MENSAGEM2:
MOV DPTR, #STRING02 ;carrega endereço da string
LCALL WRITESTRING
LCALL ENVIA_ENTER
LCALL ATRASO
MENSAGEM3:
MOV DPTR, #STRING03 ;carrega endereço da string
LCALL WRITESTRING
LCALL ENVIA_ENTER
LCALL ATRASO
MENSAGEM4:
MOV DPTR, #STRING04 ;carrega endereço da string
LCALL WRITESTRING
LCALL ENVIA_ENTER
LCALL ATRASO
MENSAGEM5:
MOV DPTR, #STRING05 ;carrega endereço da string
LCALL WRITESTRING
LCALL ENVIA_ENTER
LCALL ATRASO
MENSAGEM6:
MOV DPTR, #STRING06 ;carrega endereço da string
LCALL WRITESTRING
LCALL ENVIA_ENTER
LCALL ATRASO
MENSAGEM8:
MOV DPTR, #STRING08 ;carrega endereço da string
LCALL WRITESTRING
LCALL ATRASO
; FIM DAS MENSAGENS NO DISPLAY - HABILITA COMUNICACAO SERIAL
MOV IE,#10010000B ;HABILITA INTERRUPÇÃO GERAL E SERIAL
MOV SCON,#01010000B ;MODO 1 DA SERIAL, HABILITA RECEPÇÃO
LOOP:
LJMP LOOP
; ----------- SUB-ROTINAS DE ENVIO DE MENSAGENS ----------------
WRITESTRING:
MOV A, #0
MOVC A, @A + DPTR
CJNE A, #'$', WRITE_NEXT
SJMP FINIS_STRING
WRITE_NEXT:
MOV R1, A ;MOVE DADO DO ACUMULADOR PARA REGISTRADOR R1
LCALL TRANSMITE ;ENVIA CARACTERE PARA O COMPUTADOR
INC DPTR
SJMP WRITESTRING
FINIS_STRING:
RET
ENVIA_ENTER:
MOV A, #13 ;CR (Carriage Return) = “\r” = (char) 13
MOV R1, A ;MOVE DADO DO ACUMULADOR PARA REGISTRADOR R1
LCALL TRANSMITE ;ENVIA CARACTERE PARA O COMPUTADOR
RET
; *********** SUBROTINAS DE DELAY ****************************************
T5MS:
MOV TL0, #LOW(TEMPO)
MOV TH0, #HIGH(TEMPO)
SETB TR0
JNB TF0, $
CLR TR0
CLR TF0
RET
ATRASO:
MOV R2, #10D
DENOVO:
MOV TL0, #LOW (TEMPO2)
MOV TH0, #HIGH(TEMPO2)
SETB TR0
JNB TF0, $
CLR TR0
CLR TF0
DJNZ R2, DENOVO
RET
; *********** TRANSMISSAO SERIAL ****************************************
TRANSMITE:
MOV SBUF,R1 ;TRANSMITE DADO QUE ESTÁ EM R1
ESPERA:
JNB TI, ESPERA ;ESPERA TRANSMISSAO
CLR TI
RET
; MENSAGENS SALVAS NA FLASH - MEMORIA DE PROGRAMA
ORG STRING01
DB ' Microcontrolador$'
ORG STRING02
DB ' 80C32, LED e RS232$'
ORG STRING03
DB ' Freq 11.0592 MHz$'
ORG STRING04
DB ' 256 B RAM$'
ORG STRING05
DB ' 64 kB EPROM$'
ORG STRING06
DB ' 32 kB Ext RAM$'
ORG STRING07
DB 'Inicializando...$'
ORG STRING08
DB '8051 echo:>_ $'
;ENTER
;CR (Carriage Return) = “\r” = (char) 13
;LF (Line Feed) = “\n” = (char) 10
END
Figura 4 - Código em Assembly do programa 8051 Teste Serial.
Figura 5 - Apagando a memória EPROM com Luz Ultravioleta.
Figura 6 - Programando a memória EPROM com Minipro TL866 II plus.
Figura 7 - Placa 80C32 conectada ao computador pela porta serial.
Figura 8 - Mensagens iniciais enviadas do 80C32 para o computador.
Figura 9 - Frame da comunicação serial de 1 caractere medida com o osciloscópio.
Assista ao vídeo para ver como ficou nosso projeto:
Vídeo 1 - 80C32 EPROM - Projeto Teste Comunicação Serial com o 8051.
Referência:
NICOLOSI, D. E. C.; Laboratório de Microcontroladores: Treino de instruções, hardware e software. São Paulo: Érica, 2002.
Que tal montar seu próprio Relógio Digital com um 8051?
Este artigo mostra o projeto de um Relógio Digital simples com 4 displays do tipo 7 Segmentos para fins didáticos.
Para a montagem é utilizada a lista de componentes:
- 1 microcontrolador da família 8051 (Atmel AT89S52); - 4 displays 7 segmentos catodo comum (-); - 4 transistores NPN BC337 para drive dos displays. - 8 transistores PNP BC327 para drive dos segmentos. - 2 botões para ajustes de hora e minuto; - 1 cristal de 11,0592 MHz - 2 capacitores de 33 pF para o cristal. - 8 resistores de 330 ohms para os segmentos do display; - 2 resistores de 10 kohms para pullup dos botões; - 12 resistores de 10 kohms para acionamento dos transistores.
O circuito é alimentado com 5 Vcc.
O diagrama de interligação é mostrado na Figura 1.
Figura 1 - Diagrama do Relógio Digital.
A montagem pode ser feita em Matriz de Contatos. Veja a Figura 2.
Figura 2 - Montagem do Circuito em Matriz de Contatos.
O Vídeo a seguir mostra o Relógio Digital funcionando e a Simulação do circuito no Proteus.
Vídeo 1 - Nosso Relógio Digital com o 8051 funcionando.
O programa do 8051
O
programa do Relógio Digital foi escrito em Linguagem Assembly e
pode ser compilado com os Compiladores ASM51 ou Keil. No Anexo 1 você encontra o código fonte.
A interrupção do Timer1 é utilizada como base de tempo para o relógio (clock).
O programa inicia no endereço 100H. Após a inicialização algumas variáveis são carregadas com seus valores iniciais.
O temporizador Timer1 é configurado para operar no modo 2: 8-bit com recarga automática.
Os registros TL1 e TH1, carga e recarga do Timer1, são setados com valor (255 - 225).
No final das configurações são habilitadas as interrupções do Timer1 e global.
O Timer1 é inicializado.
O programa passa a rodar em um loop infinito verificando se os botões de ajustes de hora e minuto foram pressionados e atualizando o display.
A rotina de interrupção do Timer1 é chamada a cada 244,140625 us. Os cálculos para definir a carga do Timer1 com valor (255 - 225) estão disponíveis no Quadro 1:
; CLOCK DO RELOGIO BASEADO NA INTERRUPCAO DO TIMER 1
; OPERANDO NO MODO 1 - 8 BITS COM RECARGA AUTOMATICA
;
; CALCULOS
; FREQUENCIA DO CRISTAL f = 11.059.200 MHz
; PERIODO DO CRISTAL T = 1/f = 9,04224537037037...e-8 s
; PERIODO DE UMA INSTRUCAO = T * 12 = 1,085069444...e-6 s
; NUMERO DE INSTRUCOES EM 1 SEGUNDO = 921.600 IPS
; CARREGAMENTO DO TIMER 1 = 921.000 / 4096 = 225
; 4096 DECIMAL = 1000 HEXADECIMAL = 1 0000 0000 0000 BINARIO
Quadro 1 - Cálculos para definir o tempo da interrupção do Timer1.
As variáveis CONTADOR_L e CONTADOR_H armazenam o número de interrupções.
A cada 4096 interrupções (1000H em hexadecimal) é completado 1 segundo. A variável SEGUNDO é incrementada em 1 unidade e quando necessário as demais variáveis são incrementadas:
- UNIDADE, para a unidade dos minutos do relógio; - DEZENA, para dezena dos minutos do relógio; - CENTENA, para a unidade das horas do relógio; - MILHAR, para dezena das horas do relógio.
Este relógio possui o formato de 24 horas.
O acionamento do display é feito por multiplexação. Cada dígito fica ligado por um tempo de 1 ms. Pela cintilação do olho humano enxergamos os 4
displays acesos, mas na verdade apenas um se mantém ligado!
O horário do relógio é atualizado.
A cada 500 ms o "ponto" do relógio é invertido de status, para "piscar" a cada segundo.
Os "2 pontos" do relógio são formados invertendo-se a montagem do terceiro display de 7 segmentos em 180°.
Você agora pode
implementar o código e criar um horário de alarme para adicionar a
função de despertador para o seu Relógio Digital!
Obs:
Este
é um circuito didático para ensinar o princípio de funcionamento de um
relógio digital.
Para
melhor precisão no relógio deve-se utilzar um Relógio de Tempo Real (Real Time
Clock - RTC), como por exemplo o DS1302 com cristal de 32,768 kHz ou
um microcontrolador com o módulo RTC interno. Exemplos de circuitos com RTCC: https://www.youtube.com/watch?v=zR0KW0H_dD4 https://www.youtube.com/watch?v=k_SVMvWyYak O circuito também não pode ser desligado da alimentação, senão perde a hora, pois não tem bateria de backup.
Referência:
NICOLOSI, D. E. C.; Laboratório de Microcontroladores: Treino de instruções, hardware e software. São Paulo: Érica, 2002.
Anexo 1 - Código fonte do Relógio Digital com o 8051 em Assembly
; ############ RELOGIO DIGITAL COM 4 DISPLAYS DE 7 SEGMENTOS ########################
; RELOGIO DIGITAL COM HORA MINUTO E 2 PONTOS
; AJUSTE DE HORA E MINUTO ATRAVES DE 2 TECLAS
; MICROCONTROLADOR 8051 - AT89S52
; COMPILADOR ASM51 ou Keil
; JUNHO/2013 M.R.G.
; SEGMENTOS DO DISPLAY NO PORT 3
; DISPLAY CATODO COMUM (-)
; SEGMENTO ATIVO COM LOGICA NIVEL BAIXO (TRANSISTOR PNP PARA CADA SEGMENTO)
; DISPLAY UNIDADE P2.0
; DISPLAY DEZENA P2.1
; DISPLAY CENTENA P2.2
; DISLAY MILHAR P2.3
; BOTAO 1 P2.4
; BOTAO 2 P2.5
; CLOCK DO RELOGIO BASEADO NA INTERRUPCAO DO TIMER 1
; OPERANDO NO MODO 1 - 8 BITS COM RECARGA AUTOMATICA
; CALCULOS
; FREQUENCIA DO CRISTAL f = 11.059.200 MHz
; PERIODO DO CRISTAL T = 1/f = 9,04224537037037...e-8 s
; PERIODO DE UMA INSTRUCAO = T * 12 = 1,085069444...e-6 s
; NUMERO DE INSTRUCOES EM 1 SEGUNDO = 921.600 IPS
; CARREGAMENTO DO TIMER 1 = 921.000 / 4096 = 225
; 4096 DECIMAL = 1000 HEXADECIMAL = 1 0000 0000 0000 BINARIO
$MOD51
; *************** DEFINE CONSTANTES **********************************
TEMPO10MS EQU 9210
TEMPO1MS EQU 921
DISPU EQU P2.0
DISPD EQU P2.1
DISPC EQU P2.2
DISPM EQU P2.3
BOTAO1 EQU P2.4
BOTAO2 EQU P2.5
; ******************** DECLARACAO DE VARIAVEIS DA RAM ******************
UNIDADE EQU 60H ;NUMERO
DEZENA EQU 61H ;NUMERO
CENTENA EQU 62H ;NUMERO
MILHAR EQU 63H ;NUMERO
UNIDADE7SEG EQU 64H ;CARACTERE
DEZENA7SEG EQU 65H ;CARACTERE
CENTENA7SEG EQU 66H ;CARACTERE
MILHAR7SEG EQU 67H ;CARACTERE
CONTADOR_L EQU 68H ;LSB CONTADOR INTERRUPCOES T1
CONTADOR_H EQU 69H ;MSB CONTADOR INTERRUPCOES T1
SEGUNDO EQU 6AH ;ARMAZENA OS SEGUNDOS
PONTO EQU 00H ;BIT UTILIZADO PARA PISCAR 2 PONTOS
;*************** VETOR DE RESET ****************************************
ORG 000H
NOP
NOP
LJMP INICIO
;************ VETOR DE INTERRUPCAO DO TIMER 1***************************
ORG 01BH
LJMP INT_TIMER1
;************************** MAIN ***************************************
ORG 100H
INICIO:
MOV SP, #30H ;ALTERA ENDERECO DA BASE DA PILHA
;DESLIGA DISPLAYS
MOV P3, #0FFH ;DESATIVA TODOS OS SEGMENTOS
CLR DISPU ;DESATIVA TODOS OS DISPLAY
CLR DISPD
CLR DISPC
CLR DISPM
;INICIALIZA VARIAVEIS DA RAM
MOV UNIDADE, #0
MOV DEZENA, #0
MOV CENTENA, #0
MOV MILHAR, #0
MOV CONTADOR_L, #0
MOV CONTADOR_H, #0
MOV SEGUNDO, #0
CLR PONTO
;CONFIGURA TIMERS
MOV TMOD,#00100001B ;TIMER 0 MODO 1 - 16 BITS
;TIMER 1 MODO 2 - 8 BITS COM RECARGA AUTOMATICA
MOV TL1, #(255 - 225) ;CARGA DO TIMER 1
MOV TH1, #(255 - 225) ;RECARGA DO TIMER 1
LCALL ESCREVE7SEG ;TESTE DISPLAYS
SETB EA ;HABILITA FLAG DE INTERRUPCAO GERAL
SETB ET1 ;HABILITA FLAG DE INTERRUPCAO DO TIMER 1
SETB TR1 ;INICIA TEMPORIZADOR TIMER1
LOOP:
JB BOTAO1, TESTA_BT2 ;SE TECLA NAO PRESSIONADA(1) DESVIA
LCALL ACERTA_MINUTO
TESTA_BT2:
JB BOTAO2, ACIONA_DISPLAY ;SE TECLA NAO PRESSIONADA(1) DESVIA
LCALL ACERTA_HORA
ACIONA_DISPLAY:
LCALL ATUALIZA_DISPLAY
LJMP LOOP
;AJUSTE MANUAL DO MINUTO PELO BOTAO 1
ACERTA_MINUTO:
INC UNIDADE
MOV A, UNIDADE
CJNE A, #10D, INCREMENTO_MIN_FIM
ACERTA_DEZ_MINUTO:
MOV UNIDADE, #0
INC DEZENA
MOV A, DEZENA
CJNE A, #06D, INCREMENTO_MIN_FIM
MOV DEZENA, #0
INCREMENTO_MIN_FIM:
RET
;AJUSTE MANUAL DA HORA PELO BOTAO 2
ACERTA_HORA:
INC CENTENA
MOV A, CENTENA
CJNE A, #04D, ACERTA_DEZ_HORA ;VERIFICA SE COMPLETOU 24 HORAS
MOV A, MILHAR
CJNE A, #02D, INCREMENTO_HORA_FIM
MOV CENTENA, #0 ;COMPLETOU 24 HORAS ZERA O RELOGIO
MOV MILHAR, #0
AJMP INCREMENTO_HORA_FIM
ACERTA_DEZ_HORA:
CJNE A, #10D, INCREMENTO_HORA_FIM
MOV CENTENA, #0
INC MILHAR
INCREMENTO_HORA_FIM:
RET
;SUBROTINA PARA ESCRITA NOS DISPLAY
ESCREVE7SEG:
MOV P3, #00000000B ;ACENDE TODOS OS SEGMENTOS
LCALL MUX7SEG
;SUBROTINA MULTIPLEXA NUMERO NO DISPLAY - VISUALIZA 1 DISPLAY ACESO POR VEZ
MUX7SEG:
CLR DISPU ;DESATIVA TODOS OS DISPLAY
CLR DISPD
CLR DISPC
CLR DISPM
SETB DISPU ;LIGA DISPLAY DA UNIDADE
LCALL DELAY500MS ;DELAY
CLR DISPU ;DESLIGA DISPLAY DA UNIDADE
NOP
SETB DISPD ;LIGA DISPLAY DA DEZENA
LCALL DELAY500MS ;DELAY
CLR DISPD ;DESLIGA DISPLAY DA DEZENA
NOP
SETB DISPC ;LIGA DISPLAY DA CENTENA
LCALL DELAY500MS ;DELAY
CLR DISPC ;DESLIGA DISPLAY DA CENTENA
NOP
SETB DISPM ;LIGA DISPLAY DO MILHAR
LCALL DELAY500MS ;DELAY
CLR DISPM ;DESLIGA DISPLAY DO MILHAR
NOP
RET
; ############## ATUALIZA DISPLAY 7 SEGMENTOS ##########################
ATUALIZA_DISPLAY:
LCALL CONVERTE ;CONVERTE NUMERO NO CARACTER CORRESPONDENTE
;PARA O DISPLAY 7 SEGMENTOS
MOV R3, #50D ;4 X 50 X 1ms = 200 ms
;FAZ A MULTIPLEXACAO DOS 4 DISPLAYS DE 7 SEGMENTOS
LOOP_DISPLAY_CONT2:
MOV P3, UNIDADE7SEG ;MOVE CARACTER DA UNIDADE PARA DISPLAY
NOP
NOP
SETB DISPU ;LIGA DISPLAY DA UNIDADE
LCALL DELAY1MS ;DELAY
CLR DISPU ;DESLIGA DISPLAY DA UNIDADE
NOP
NOP
MOV A, DEZENA7SEG ;MOVE CARACTER DA DEZENA PARA ACC
MOV C, PONTO ;MOVE VALOR DO PONTO DECIMAL
MOV ACC.7, C
MOV P3, A ;MOVE CARACTER DA DEZENA PARA DISPLAY COM PONTO
NOP
NOP
SETB DISPD ;LIGA DISPLAY DA DEZENA
LCALL DELAY1MS ;DELAY
CLR DISPD ;DESLIGA DISPLAY DA DEZENA
NOP
NOP
MOV A, CENTENA7SEG ;MOVE CARACTER DA CENTENA PARA ACC
MOV C, PONTO ;MOVE VALOR DO PONTO DECIMAL
MOV ACC.7, C
MOV P3, A ;MOVE CARACTER DA CENTENA PARA DISPLAY COM PONTO
NOP
NOP
SETB DISPC ;LIGA DISPLAY DA CENTENA
LCALL DELAY1MS ;DELAY
CLR DISPC ;DESLIGA DISPLAY DA CENTENA
NOP
NOP
MOV P3, MILHAR7SEG ;MOVE CARACTER DO MILHAR PARA DISPLAY
NOP
NOP
SETB DISPM ;LIGA DISPLAY DO MILHAR
LCALL DELAY1MS ;DELAY
CLR DISPM ;DESLIGA DISPLAY DO MILHAR
NOP
NOP
DJNZ R3, LOOP_DISPLAY_CONT2 ;DECREMENTA E VERIFICA SE TERMINOU OS 50 LOOPS
RET
; ---------------------------------------------------------
;CONVERTE NUMERO NO CARACTER CORRESPONDENTE
CONVERTE:
MOV A, UNIDADE
LCALL COMPARA
MOV UNIDADE7SEG, A
MOV A, DEZENA
LCALL COMPARA
MOV DEZENA7SEG, A
MOV A, CENTENA
LCALL COMPARA
MOV CENTENA7SEG, A
MOV A, MILHAR
LCALL COMPARA
MOV MILHAR7SEG, A
RET
;COMPARA E CARREGA ACC COM VALOR DO CARACTER 7 SEGMENTO
;CORRESPONDENTE AO ALGARISMO DECIMAL
COMPARA:
CJNE A, #0D, COMPARA1
MOV A, #11000000B ;CARACTER 0
RET
COMPARA1:
CJNE A, #1D, COMPARA2
MOV A, #11111001B ;CARACTER 1
RET
COMPARA2:
CJNE A, #2D, COMPARA3
MOV A, #10100100B ;CARACTER 2
RET
COMPARA3:
CJNE A, #3D, COMPARA4
MOV A, #10110000B ;CARACTER 3
RET
COMPARA4:
CJNE A, #4D, COMPARA5
MOV A, #10011001B ;CARACTER 4
RET
COMPARA5:
CJNE A, #5D, COMPARA6
MOV A, #10010010B ;CARACTER 5
RET
COMPARA6:
CJNE A, #6D, COMPARA7
MOV A, #10000010B ;CARACTER 6
RET
COMPARA7:
CJNE A, #7D, COMPARA8
MOV A, #11111000B ;CARACTER 7
RET
COMPARA8:
CJNE A, #8D, COMPARA9
MOV A, #10000000B ;CARACTER 8
RET
COMPARA9:
CJNE A, #9D, COMPARA_ERRO
MOV A, #10010000B ;CARACTER 9
RET
COMPARA_ERRO: ;ERRO - NAO E ALGARISMO DECIMAL 0 A 9
MOV A, #0000000B ;ACENDE TODOS SEGMENTOS
RET
;SUBROTINA DE DELAY
DELAY500MS:
MOV R0, #50D ;50 X 10 MS = 500 MS
DELAY10MS:
MOV TL0, #LOW (65535-TEMPO10MS) ;CARREGA VALOR PARA TIMER 0
MOV TH0, #HIGH(65535-TEMPO10MS)
SETB TR0 ;LIGA TIMER 0
JNB TF0, $ ;AGUARDA FIM DA CONTAGEM
CLR TR0 ;LIMPA FLAG
CLR TF0
DJNZ R0, DELAY10MS ;DECREMENTA E VERIFICA SE TERMINOU OS 50 LOOPS
RET
;DELAY UNICO 1 MS
DELAY1MS:
MOV TL0, #LOW (65535-TEMPO1MS) ;CARREGA VALOR PARA TIMER 0
MOV TH0, #HIGH(65535-TEMPO1MS)
SETB TR0 ;LIGA TIMER 0
JNB TF0, $ ;AGUARDA FIM DA CONTAGEM
CLR TR0 ;LIMPA FLAG
CLR TF0
RET
DELAY20CICLO:
MOV R4, #20
DJNZ R4, $ ;DELAY
RET
; ############# SUBROTINA DE TRATAMENTO DE INTERRUPCAO DO TIMER 1 ###########
INT_TIMER1:
PUSH PSW ;ARMAZENA VALORES DOS REGISTROS PRINCIPAIS
PUSH ACC
MOV A, CONTADOR_L ;MOVE BYTE LSB DO CONTADOR PARA ACC
ADD A, #1D ;INCREMENTA UMA UNIDADE
JNC COMPARA_CONT_L ;DESVIA SE CARRY = 0 - VERIFICA OVERFLOW
CLR A ;ZERA BYTE LSB SE MAIOR QUE 255
INC CONTADOR_H ;INCREMENTA CONTADOR H
; COMPARA SE COMPLETOU MEIO SEGUNDO = 0800H OU 1 SEGUNDO = 1000H
COMPARA_CONT_L:
MOV CONTADOR_L, A ;RETORNA VALOR DE ACC PARA CONTADOR
CJNE A, #00D , INT_FIM ; SE NAO COMPLETOU TEMPO SAI DA INTERRUPCAO
COMPARA_CONT_H:
MOV A, CONTADOR_H ; MOVE BYTE MSB DO CONTADOR PARA ACC
CJNE A, #08H , COMPARA_1SEG ; SE NAO COMPLETOU MEIO SEGUNDO DESVIA
CPL PONTO ; COMPLETOU MEIO SEGUNDO INVERTE 2 PONTOS
COMPARA_1SEG:
CJNE A, #10H , INT_FIM ; SE NAO COMPLETOU 1 SEGUNDO SAI DA INTERRUPCAO
MOV CONTADOR_H, #0 ;LIMPA CONTADOR
INCREMENTA_1SEG:
INC SEGUNDO ;INCREMENTA SEGUNDO
CPL PONTO ; COMPLETOU MEIO SEGUNDO INVERTE 2 PONTOS
MOV A, SEGUNDO
CJNE A, #60D, INCREMENTO_FIM ;VERIFICA SE COMPLETOU 1 MINUTO
INC_UNI_MINUTO:
MOV SEGUNDO, #0
INC UNIDADE
MOV A, UNIDADE
CJNE A, #10D, INCREMENTO_FIM
INC_DEZ_MINUTO:
MOV UNIDADE, #0
INC DEZENA
MOV A, DEZENA
CJNE A, #06D, INCREMENTO_FIM
INC_UNI_HORA:
MOV DEZENA, #0
INC CENTENA
MOV A, CENTENA
CJNE A, #04D, INC_DEZ_HORA ;VERIFICA SE COMPLETOU 24 HORAS
MOV A, MILHAR
CJNE A, #02D, INCREMENTO_FIM
MOV CENTENA, #0 ;COMPLETOU 24 HORAS ZERA O RELOGIO
MOV MILHAR, #0
AJMP INCREMENTO_FIM
INC_DEZ_HORA:
CJNE A, #10D, INCREMENTO_FIM
MOV CENTENA, #0
INC MILHAR
INCREMENTO_FIM:
INT_FIM:
CLR TF1 ;LIMPA FLAG DE INTERRUPCAO DO TIMER 1
POP ACC ;RESTAURA VALORES DOS REGISTROS PRINCIPAIS
POP PSW
RETI ;RETORNA DA INTERRUPCAO
END