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.
A montagem pode ser feita em Matriz de Contatos. Veja a Figura 2.
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°.
Após compilar o seu projeto com o ASM51 ou Keil você deve programar o microcontrolador 8051 com o arquivo .hex. O vídeo 8051 - O primeiro projeto - Pisca LED - Compilação e Gravação do AT89S52 mostra um exemplo de como programar o AT89S52.
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