Ir ao conteúdo
  • Cadastre-se

Relógio-higrômetro com PIC 16F877 e displays de 7 segmentos


joao.raffo

Posts recomendados

Saudações, pessoal!

Estou desenvolvendo meu projeto de conclusão de curso em eletrônica, trata-se de um medidor de umidade relativa do ar, utilizando o sensor HIH-4021 da Honeywell, um PIC 16F877A e seis displays de sete segmentos.

O circuito deve mostrar a umidade relativa do ar, dia, mês, ano, horas e minutos, tudo nos displays.

Consultando o livro Conectando o PIC, desenvolvi um programa em Assembly mesmo para contar o tempo e mostrar hora, minuto e segundo nos displays. Até aí tudo bem, mas acontece que devo fazer com que o display "varie" para mostrar também dia, mês e ano, e também a umidade. Não estou conseguindo fazer isso, alguém pode me dar uma luz?

Aí está o código-fonte:

; ***********************************

; *** CONFIGURAÇÕES PARA GRAVAÇÃO ***

; ***********************************

__CONFIG _CP_OFF & _CPD_OFF & _DEBUG_OFF & _LVP_OFF & _WRT_OFF & _BODEN_OFF & _PWRTE_ON & _WDT_ON & _XT_OSC

; *********************************

; *** DEFININIÇÃO DAS VARIÁVEIS ***

; *********************************

; O PRIMEIRO BLOCO DE VARIÁVEIS ESTÁ LOCALIZADO LOGO NO INÍCIO DO BANCO 0

CBLOCK 0X20 ; POSIÇÃO INICIAL DA MEMÓRIA RAM

UNIDADE

DEZENA

CENTENA

MILHAR1

MILHAR2

MILHAR3

DIA

MES

ANO

FILTRO_BOTOES

TEMPO_TURBO

INDICE_VARRE_DISPLAY

DIVISOR_TMR1 ;CONTADOR AUXILIAR P/SEGUNDOS

ENDC

; O SEGUNDO BLOCO DE VARIÁVEIS ESTÁ LOCALIZADO NO FINAL DO BANCO 0, A PARTIR DO ENDEREÇO 0X70

; POIS ESTÁ LOCALIZAÇÃO É ACESSADA DE QUALQUER BANCO, FACILITANDO A OPERAÇÃO COM AS VARIÁVEIS

; AQUI LOCALIZADAS

CBLOCK 0X70 ; REGIÃO COMUM A TODOS OS BANCOS

STATUS_TEMP ; REGISTRADOR DE STATUS TEMPORÁRIO

WORK_TEMP ; REGISTRADOR DE TRABALHO TEMPORÁRIO

FSR_TEMP ; REG. DE ENDEREÇO INDIRETO TEMPORÁRIO

PCLATH_TEMP ; REGISTRADOR DE PAGINAÇÃO TEMPORÁRIO

ENDC

; ***********************************************

; *** DEFINIÇÃO DAS VARIÁVEIS INTERNAS DO PIC ***

; ***********************************************

; O ARQUIVO DE DEFINIÇÕES DO PIC UTILIZADO DEVE SER REFERENCIADO PARA QUE OS NOMES DEFINIDOS

; PELA MICROCHIP POSSAM SER UTILIZADOS, SEM A NECESSIDADE DE REDIGITAÇÃO

#INCLUDE <P16F877A.INC>

; ***********************************

; *** DEFINIÇÃO DOS BANCOS DE RAM ***

; ***********************************

; OS PSEUDO-COMANDOS "BANK0" E "BANK1", AQUI DEFINIDOS, AJUDAM A COMUTAR ENTRE OS BANCOS

; DE MEMÓRIA

#DEFINE BANK1 BSF STATUS,RP0 ;SELECIONA BANK1 DA MEMÓRIA RAM

#DEFINE BANK0 BCF STATUS,RP0 ;SELECIONA BANK0 DA MEMÓRIA RAM

; ***************************

; *** CONSTANTES INTERNAS ***

; ***************************

; A DEFINIÇÃO DE CONSTANTES FACILITA A PROGRAMAÇÃO E A MANUTENÇÃO

FILTRO_TECLA EQU .200 ; FILTRO PARA EVITAR RUIDOS NOS BOTÕES

TURBO_TECLA EQU .70 ; TEMPORIZADOR PARA TURBO DAS TECLAS

TMR1_HIGH EQU HIGH(.65536-.62500)

TMR1_LOW EQU LOW (.65536-.62500) ;VALOR PARA CONTAGEM DE 62500 CICLOS

;DE CONTAGEM DO TMR1 (PROGRAMADO PRA

;PRESCALER DE 1:8)

; ****************************************

; *** DECLARAÇÃO DOS FLAGS DE SOFTWARE ***

; ****************************************

; A DEFINIÇÃO DE FLAGS AJUDA NA PROGRAMAÇÃO E ECONOMIZA MEMÓRIA RAM.

; ESTE PROGRAMA NÃO USA NENHUM FLAG DE USUÁRIO

; ****************

; *** ENTRADAS ***

; ****************

; AS ENTRADAS DEVEM SER ASSOCIADAS A NOMES PARA FACILITAR A PROGRAMAÇÃO E FUTURAS ALTERAÇÕES

; DE HARDWARE

#DEFINE BT_UP PORTA,1 ; ESTADO DO BOTÃO 1

; 0 = LIBERADO

; 1 = PRESSIONADO

#DEFINE BT_DOWN PORTA,2 ; ESTADO DO BOTÃO 2

; 0 = LIBERADO

; 1 = PRESSIONADO

#DEFINE BT_START_STOP PORTA,3 ; ESTADO DO BOTÃO 3

; 0 = LIBERADO

; 1 = PRESSIONADO

; **************

; *** SAIDAS ***

; **************

; AS SAÍDAS TAMBÉM DEVEM SER ASSOCIADAS A NOMES PARA FACILITAR A PROGRAMAÇÃO

#DEFINE LED_HORAS PORTD,7 ; LEDS QUE INDICAM OS "DOIS PONTOS" QUANDO AS HORAS SÃO MOSTRADAS

; 1 = LIGADOS

; 0 = DESLIGADOS

#DEFINE DIAS_DA_SEMANA PORTD ; DEFINE OS 7 LEDS QUE SERÃO UTILIZADOS PARA INDICAR OS DIAS DA SEMANA

; (DE RD0 ATÉ RD6)

#DEFINE ESTADO_TIMER PORTE,0

#DEFINE MUX PORTC ;MUX PARA ACIONAMENTO DOS DISPLAYS

#DEFINE SEGMENTOS PORTB ; SEGMENTOS DOS DISPLAYS

; ******************************************

; *** VETOR DE RESET DO MICROCONTROLADOR ***

; ******************************************

; POSIÇÃO INICIAL PARA EXECUÇÃO DO PROGRAMA

ORG 0X0000 ; ENDEREÇO DO VETOR DE RESET

; GOTO configur ; PULA PARA CONFIG DEVIDO A REGIÃO

; DESTINADA ÀS INTERRUPÇÕES

; ****************************

; *** VETOR DE INTERRUPÇÃO ***

; ****************************

; POSIÇÃO DE DESVIO DO PROGRAMA QUANDO UMA INTERRUPÇÃO ACONTECE

ORG 0X0004 ; ENDEREÇO DO VETOR DE INTERRUPÇÃO

; É MUITO IMPORTANTE QUE OS REGISTRADORES PRIORITÁTIOS AO FUNCIONAMENTO DA MÁQUINA, E QUE PODEM SER

; ALTERADOS TANTO DENTRO QUANTO FORA DAS INTS SEJAM SALVOS EM REGISTRADORES TEMPORÁRIOS PARA PODEREM

; SER POSTERIORMENTE RECUPERADOS

SALVA_CONTEXTO

MOVWF WORK_TEMP ;SALVA REGISTRADORES DE TRABALHO E

SWAPF STATUS,W ;DE STATUS DURANTE O TRATAMENTO DA

MOVWF STATUS_TEMP ;INTERRUPÇÃO

MOVF FSR,W

MOVWF FSR_TEMP ;SALVA REGISTRADOR FSR

MOVF PCLATH,W

MOVWF PCLATH_TEMP ;SALVA REGISTRADOR PCLATH

CLRF PCLATH ;LIMPA REGISTRADOR PCLATH

;(SELECIONA PÁGINA 0)

CLRF STATUS ;LIMPA REGISTRADOR STATUS

;(SELECIONA BANCO 0)

; *********************************************

; *** TESTA QUAL INTERRUPÇÃO FOI SOLICITADA ***

; *********************************************

; TESTA O FLAG DAS INTERRUPÇÕES PARA SABER PARA QUAL ROTINA DESVIAR

BTFSS INTCON,T0IF ;FOI INTERRUPÇÃO DE TMR0?

GOTO INT_TMR1 ;NÃO, ENTÃO VAI PARA INT_TMR1

;SIM

; **********************************************

; *** TRATAMENTO DAS INTERRUPÇÕES DE TIMER 0 ***

; **********************************************

; ROTINA PARA EXECUTAR AS AÇÕES NECESSÁRIAS SEMPRE QUE A INTERRUPÇÃO ACONTECE. NESTE CASO, A

; INTERRUPÇÃO ESTÁ SENDO UTILIZADA PARA GERAR A FREQUÊNCIA DE VARREDURA DOS DISPLAYS, POR ISSO, CADA

; VEZ QUE ELA ACONTECER, O PRÓXIMO DISPLAY SERÁ ACIONADO

INT_TMR0

INCF INDICE_VARRE_DISPLAY,F ;INCREMENTA O ÍNDICE DE VAR. DOS DISPLAYS

MOVLW B'00000101'

ANDWF INDICE_VARRE_DISPLAY,F ;LIMITA A CONTAGEM DE 0 A 5 (6 DISPLAYS)

MOVF INDICE_VARRE_DISPLAY,W ;CARREGA NO WORK O VALOR DO ÍNDICE

ADDLW UNIDADE ;SOMA ENDEREÇO DO PRIMEIRO DÍGITO

MOVWF FSR ;SALVA RESULTADO NO FSR, APONTANDO PARA O ENDEREÇO DO

;DÍGITO ATUAL (ENDEREÇAMENTO INDIRETO)

BSF SEGMENTOS,0 ;LIMPA OS SEGMENTOS PARA EVITAR SOMBRAS NOS DISPLAYS

BSF SEGMENTOS,1 ;(POR SE TRATAR DE DISPLAYS ANODO COMUM, MANDA-SE "1" PARA QUE

BSF SEGMENTOS,2 ; O SEGMENTO APAGUE)

BSF SEGMENTOS,3

BSF SEGMENTOS,4

BSF SEGMENTOS,5

BSF SEGMENTOS,6

BSF SEGMENTOS,7

MOVLW B'11000000' ;PREPARA A MÁSCARA

ANDWF PORTC,F ;EXECUTA A MÁSCARA (DESLIGA OS DISPLAYS)

MOVF INDICE_VARRE_DISPLAY,W ;SALVA NO WORK O VALOR DO ÍNDICE

CALL TABELA_MUX ;CONSULTA TABELA MUX

IORWF MUX,F ;ATUALIZA MUX, SELECIONANDO O DISPLAY CORRETO PARA O MOMENTO

GOTO $+1 ;DELAY DE 2uS (TEMPO DE RESPOSTA DO TRANSISTOR)

MOVF INDF,W ;RECUPERA NO WORK O VALOR DO DÍGITO

CALL TABELA_DISPLAY_7_SEG ;CONSULTA A TABELA P/ DISPLAYS

MOVWF SEGMENTOS ;ATUALIZA OS SEGMENTOS, ESCREVENDO O VALOR DO DÍGITO CORRETO (PORTB)

SAI_INT_TMR0

BCF INTCON,T0IF ;LIMPA FLAG DA INTERRUPÇÃO DE TMRO

GOTO SAI_INT ;PULA P/SAI_INT

; ********************************************

; *** TRATAMENTO DA INTERRUPÇÃO DE TIMER 1 ***

; ********************************************

; ROTINA PARA EXECUTAR AS AÇÕES NECESSÁRIAS SEMPRE QUE A INTERRUPÇÃO ACONTECE. NESTE CASO, A INTERRUPÇÃO

; ESTÁ SENDO UTILIZADA PARA CONTAR O TEMPO DO TEMPORIZADOR. POR ISSO, CADA VEZ QUE ELA ACONTECER O VALOR

; DO TIMER SERÁ DECREMENTADO, CASO JÁ TENHA SE PASSADO 1 SEGUNDO

; PERÍODO DA INTERRUPÇÃO: 1uS (CICLO DA MÁQUINA) * 8 (PRESCALER DO TMR1) * 62500 (CONTAGEM DO TMR1) = 0,5 SEG

INT_TMR1

MOVLW TMR1_HIGH

MOVWF TMR1H

MOVLW TMR1_LOW

MOVWF TMR1L ;RECARREGA CONTADOR DO TMR1. PERIODICIDADE DE 0,5 SEG

DECFSZ DIVISOR_TMR1,F ;PASSOU-SE 1 SEGUNDO?

GOTO SAI_INT_TMR1 ;NÃO, ENTÃO SAI DA INTERRUPÇÃO

;SIM

MOVLW .2

MOVWF DIVISOR_TMR1 ;RECARREGA O CONTADOR DE 1 SEG

CALL DECREMENTA_TIMER ; DECREMENTA O VALOR DO TIMER

MOVF UNIDADE,F

BTFSS STATUS,Z

GOTO SAI_INT_TMR1

MOVF DEZENA,F

BTFSS STATUS,Z

GOTO SAI_INT_TMR1

MOVF CENTENA,F

BTFSS STATUS,Z

GOTO SAI_INT_TMR1

MOVF MILHAR1,F

BTFSS STATUS,Z

GOTO SAI_INT_TMR1

MOVF MILHAR2,F

BTFSS STATUS,Z

GOTO SAI_INT_TMR1

MOVF MILHAR3,F

BTFSS STATUS,Z ;FINAL DA CONTAGEM?

GOTO SAI_INT_TMR1 ; NÃO - SAI DA INTERRUPÇÃO

; SIM

BCF T1CON,TMR1ON ; PARALIZA CONTADOR DO TMR1

SAI_INT_TMR1

BCF PIR1,TMR1IF ; LIMPA FLAG DA INTERRUPÇÃO DE TMR1

; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

; * SAÍDA DA INTERRUPÇÃO *

; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

; ANTES DE SAIR DA INTERRUPÇÃO, O CONTEXTO SALVO NO INÍCIO DEVE SER

; RECUPERADO PARA QUE O PROGRAMA NÃO SOFRA ALTERAÇÕES INDESEJADAS.

SAI_INT

MOVF PCLATH_TEMP,W

MOVWF PCLATH ; RECUPERA REG. PCLATH (PAGINAÇÃO)

MOVF FSR_TEMP,W

MOVWF FSR ; RECUPERA REG. FSR (END. INDIRETO)

SWAPF STATUS_TEMP,W

MOVWF STATUS ; RECUPERA REG. STATUS

SWAPF WORK_TEMP,F

SWAPF WORK_TEMP,W ; RECUPERA REG. WORK

RETFIE ; RETORNA DA INTERRUPÇÃO (HABILITA GIE)

; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

; * TABELA PARA OS DISPLAYS DE 7 SEGMENTOS *

; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

; ROTINA PARA CONVERSÃO DO VALOR NÚMÉRICO DO DÍGITO EM RELAÇÃO AOS SEGMENTOS

; QUE DEVEM SER ACESOS E APAGADOS NO DISPLAY

TABELA_DISPLAY_7_SEG

ANDLW B'00001111' ; EXECUTA MASCARA P/ EVITAR PULOS ERRADOS

ADDWF PCL,F ; SOMA DESLOCAMENTO AO PROGRAM COUNTER,

; GERANDO UMA TABELA DO TIPO "CASE".

; PGFEDCBA ; POSIÇÃO RELATIVA AOS SEGMENTOS

RETLW B'11000000' ; 0H - 0

RETLW B'11111001' ; 1H - 1

RETLW B'10100100' ; 2H - 2

RETLW B'10110000' ; 3H - 3

RETLW B'10011001' ; 4H - 4

RETLW B'10010010' ; 5H - 5

RETLW B'10000010' ; 6H - 6

RETLW B'11111000' ; 7H - 7

RETLW B'10000000' ; 8H - 8

RETLW B'10010000' ; 9H - 9

RETLW B'11111111' ; AH - BLANK

RETLW B'11111111' ; BH - BLANK

RETLW B'11111111' ; CH - BLANK

RETLW B'11111111' ; DH - BLANK

RETLW B'11111111' ; é - BLANK

RETLW B'11111111' ; FH - BLANK

; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

; * TABELA PARA ACIONAMENTO DOS DISPLAYS *

; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

; ROTINA PARA CONVERTER O DÍGITO ATUAL EM RELAÇÃO AO PORT QUE DEVE SER

; LIGADO PARA ACIONAMENTO DO DISPLAY RELACIONADO.

TABELA_MUX

ADDWF PCL,F ; SOMA DESLOCAMENTO AO PROGRAM COUNTER

; GERANDO UMA TABELA DO TIPO "CASE".

RETLW B'00010000' ; 0 - ACIONA DISPLAY 0

RETLW B'00100000' ; 1 - ACIONA DISPLAY 1

RETLW B'01000000' ; 2 - ACIONA DISPLAY 2

RETLW B'10000000' ; 2 - ACIONA DISPLAY 3

; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

; * ROTINA PARA INCREMENTAR O VALOR DO TIMER (BCD) *

; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

; ROTINA UTILIZADA PARA INCREMENTAR O VALOR DOS REGISTRADORES UNIDADE,

; DEZENA, CENTENA E MILHAR, QUE SÃO OS CONTADORES DO TIMER. A CONTAGEM É

; FEITA DIRETAMENTE EM BCD.

INCREMENTA_TIMER

INCF UNIDADE,F ; INCREMENTA UNIDADE

MOVLW .10

XORWF UNIDADE,W

BTFSS STATUS,Z ; UNIDADE = 10 ?

RETURN ; NÃO - RETORNA

; SIM

CLRF UNIDADE ; ZERA A UNIDADE

INCF DEZENA,F ; INCREMENTA A DEZENA

MOVLW .6

XORWF DEZENA,W

BTFSS STATUS,Z ; DEZENA = 6 ?

RETURN ; NÃO - RETORNA

; SIM

CLRF DEZENA ; ZERA A DEZENA

INCF CENTENA,F ; INCREMENTA A CENTENA

MOVLW .10

XORWF CENTENA,W

BTFSS STATUS,Z ; CENTENA = 10 ?

RETURN ; NÃO - RETORNA

; SIM

CLRF CENTENA ; ZERA A CENTENA

INCF MILHAR1,F ; INCREMENTA O MILHAR 1

MOVLW .6

XORWF MILHAR1,W

BTFSS STATUS,Z ; MILHAR = 6 ?

RETURN

CLRF MILHAR1 ; SIM - ZERA MILHAR1

INCF MILHAR2,F ; INCREMENTA O MILHAR2

MOVLW .10

XORWF MILHAR2,W

BTFSS STATUS,Z ; MILHAR2 = 10 ?

RETURN

CLRF MILHAR2 ; SIM - ZERA MILHAR2

INCF MILHAR3,F ; INCREMENTA O MILHAR3

MOVLW .24

XORWF MILHAR3,W

BTFSS STATUS,Z ; MILHAR3 = 24 ?

RETURN

CLRF MILHAR3 ; SIM - ZERA MILHAR

INCF DIAS,F

MOVLW .31

XORWF DIAS,W

BTFSS STATUS,Z ;DIAS = 31?

RETURN

CLRF DIAS

INCF MESES,F

MOVLW .13

XORWF MESES,W

BTFSS STATUS,Z ;MESES = 13?

RETURN

CLRF MESES

INCF ANO

; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

; * ROTINA PARA DECREMENTAR O VALOR DO TIMER (BCD) *

; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

; ROTINA UTILIZADA PARA DECREMENTAR O VALOR DOS REGISTRADORES UNIDADE,

; DEZENA, CENTENA E MILHAR, QUE SÃO OS CONTADORES DO TIMER. A CONTAGEM É

; FEITA DIRETAMENTE EM BCD.

DECREMENTA_TIMER

DECF UNIDADE,F ; INCREMENTA UNIDADE

MOVLW 0XFF

XORWF UNIDADE,W

BTFSS STATUS,Z ; UNIDADE = 0XFF ?

RETURN ; NÃO - RETORNA

; SIM

MOVLW .9

MOVWF UNIDADE ; CARREGA UNIDADE COM 9

DECF DEZENA,F ; DECREMENTA A DEZENA

MOVLW 0XFF

XORWF DEZENA,W

BTFSS STATUS,Z ; DEZENA = 0XFF ?

RETURN ; NÃO - RETORNA

; SIM

MOVLW .9

MOVWF DEZENA ; CARREGA A DEZENA COM 9

DECF CENTENA,F ; DECREMENTA A CENTENA

MOVLW 0XFF

XORWF CENTENA,W

BTFSS STATUS,Z ; CENTENA = 0XFF ?

RETURN ; NÃO - RETORNA

; SIM

MOVLW .9

MOVWF CENTENA ; CARREGA CENTENA COM 9

DECF MILHAR1,F ; DECREMENTA O MILHAR1

MOVLW 0XFF

XORWF MILHAR1,W

BTFSS STATUS,Z ; MILHAR1 = 0XFF ?

RETURN ; NÃO - RETORNA

; SIM

MOVLW .9

MOVWF MILHAR1 ; CARREGA O MILHAR1 COM 9

DECF MILHAR2,F ;DECREMENTA MILHAR2

MOVLW 0XFF

XORWF MILHAR2,W

BTFSS STATUS,Z ; MILHAR2 = 0XFF ?

RETURN ; NÃO - RETORNA

; SIM

MOVLW .9

MOVWF MILHAR2 ; CARREGA O MILHAR2 COM 9

DECF MILHAR3,F ;DECREMENTA MILHAR3

MOVLW 0XFF

XORWF MILHAR3,W

BTFSS STATUS,Z ; MILHAR3 = 0XFF ?

RETURN ; NÃO - RETORNA

; SIM

MOVLW .9

MOVWF MILHAR3 ; CARREGA O MILHAR3 COM 9

RETURN ; RETORNA

; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

; * CONFIGURAÇÕES INICIAIS DE HARDWARE E SOFTWARE *

; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

; NESTA ROTINA SÃO INICIALIZADAS AS PORTAS DE I/O DO MICROCONTROLADOR E AS

; CONFIGURAÇÕES DOS REGISTRADORES ESPECIAIS (SFR). A ROTINA INICIALIZA A

; MÁQUINA E AGUARDA O ESTOURO DO WDT.

; configur

; CLRF PORTA ; GARANTE TODAS AS SAÍDAS EM ZERO

; CLRF PORTB

; CLRF PORTC

; CLRF PORTD

; CLRF PORTE

BANK1 ; SELECIONA BANCO 1 DA RAM

MOVLW B'11111111'

MOVWF TRISA ; CONFIGURA I/O DO PORTA

MOVLW B'00000000'

MOVWF TRISB ; CONFIGURA I/O DO PORTB

MOVLW B'00000000'

MOVWF TRISC ; CONFIGURA I/O DO PORTC

MOVLW B'00000000'

MOVWF TRISD ; CONFIGURA I/O DO PORTD

MOVLW B'00000111'

MOVWF TRISE ; CONFIGURA I/O DO PORTE

MOVLW B'11011111'

MOVWF OPTION_REG ; CONFIGURA OPTIONS

; PULL-UPs DESABILITADOS

; INTER. NA BORDA DE SUBIDA DO RB0

; TIMER0 INCREM. PELO CICLO DE MÁQUINA

; WDT - 1:128

; TIMER0- 1:1

MOVLW B'01100000'

MOVWF INTCON ; CONFIGURA INTERRUPÇÕES

; HABILITADA A INTERRUPÇÃO DE TIMER0

; HABILITA AS INTERRUPÇÕES DE PERIFÉRICO

MOVLW B'00000001'

MOVWF PIE1 ; CONFIGURA INTERRUPÇÕES DE PERIFIÉRICOS

; HABILITADA A INTERRUPÇÃO DE TMR1

MOVLW B'00000111'

MOVWF ADCON1 ; CONFIGURA CONVERSOR A/D

; CONFIGURA PORTA E PORTE COMO I/O DIGITAL

BANK0 ; SELECIONA BANCO 0 DA RAM

MOVLW B'00110000'

MOVWF T1CON ; CONFIGURA TMR1

; PRESCALER -> 1:8

; INCREMENTADO PELO CICLO DE MÁQUINA

; AS INSTRUÇÕES A SEGUIR FAZEM COM QUE O PROGRAMA TRAVE QUANDO HOUVER UM

; RESET OU POWER-UP, MAS PASSE DIRETO SE O RESET FOR POR WDT. DESTA FORMA,

; SEMPRE QUE O PIC É LIGADO, O PROGRAMA TRAVA, AGUARDA UM ESTOURO DE WDT

; E COMEÇA NOVAMENTE. ISTO EVITA PROBLEMAS NO START-UP DO PIC.

BTFSC STATUS,NOT_TO ; RESET POR ESTOURO DE WATCHDOG TIMER?

GOTO $ ; NÃO - AGUARDA ESTOURO DO WDT

; SIM

; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

; * INICIALIZAÇÃO DA RAM *

; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

; ESTA ROTINA IRÁ LIMPAR TODA A RAM DO BANCO 0, INDO DE 0X20 A 0X7F.

; EM SEGUIDA, AS VARIÁVEIS DE RAM DO PROGRAMA SÃO INICIALIZADAS.

MOVLW 0X20

MOVWF FSR ; APONTA O ENDEREÇAMENTO INDIRETO PARA

; A PRIMEIRA POSIÇÃO DA RAM

LIMPA_RAM

CLRF INDF ; LIMPA A POSIÇÃO

INCF FSR,F ; INCREMENTA O PONTEIRO P/ A PRÓX. POS.

MOVF FSR,W

XORLW 0X80 ; COMPARA O PONTEIRO COM A ÚLT. POS. +1

BTFSS STATUS,Z ; JÁ LIMPOU TODAS AS POSIÇÕES?

GOTO LIMPA_RAM ; NÃO - LIMPA A PRÓXIMA POSIÇÃO

; SIM

BCF ESTADO_TIMER ; INICIA COM ESTADO EM OFF

MOVLW .2

MOVWF DIVISOR_TMR1 ; CARREGA CONTADOR DE 1SEG.

; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

; * VARREDURA DOS BOTÕES *

; * LOOP PRINCIPAL *

; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

; A ROTINA PRINCIPAL FICA CHECANDO O ESTADO DOS BOTÕES. CASO ALGUM SEJA

; PRESSIONADO, A ROTINA DE TRATAMENTO DO BOTÃO É CHAMADA.

BSF INTCON,GIE ; HABILITA AS INTERRUPÇÕES

; USADA INT. TMR0 PARA VARREDURA

; DOS DISPLAYS

VARRE

CLRWDT ; LIMPA WATCHDOG TIMER

BTFSS BT_UP ; O BOTÃO DE UP ESTÁ PRESSIONADO?

GOTO TRATA_BT_UP ; SIM - PULA P/ TRATA_BT_UP

; NÃO

BTFSS BT_DOWN ; O BOTÃO DE DOWN ESTÁ PRESSIONADO?

GOTO TRATA_BT_DOWN ; SIM - PULA P/ TRATA_BT_DOWN

; NÃO

BTFSS BT_START_STOP ; O BOTÃO START/STOP ESTÁ PRESSIONADO?

GOTO TRATA_BT_START_STOP ; SIM - PULA P/ TRATA_BT_START_STOP

; NÃO

MOVLW FILTRO_TECLA ; CARREGA NO WORK O VALOR DE FILTRO_TECLA

MOVWF FILTRO_BOTOES ; SALVA EM FILTRO_BOTOES

; RECARREGA FILTRO P/ EVITAR RUIDOS

MOVLW .1

MOVWF TEMPO_TURBO ; CARREGA TEMPO DO TURBO DAS TECLAS

; COM 1 - IGNORA O TURBO A PRIMEIRA

; VEZ QUE A TECLA É PRESSIONADA

GOTO VARRE ; VOLTA PARA VARRER TECLADO

; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

; * TRATAMENTO DOS BOTÕES *

; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

; ************************* TRATAMENTO DO BOTÃO DE UP ***********************

TRATA_BT_UP

; BTFSC ESTADO_TIMER ; TIMER ESTÁ PARADO ?

GOTO VARRE ; NÃO - VOLTA P/ VARRE

; SIM

DECFSZ FILTRO_BOTOES,F ; FIM DO FILTRO ? (RUIDO?)

GOTO VARRE ; NÃO - VOLTA P/ VARRE

; SIM - BOTÃO PRESSIONADO

DECFSZ TEMPO_TURBO,F ; FIM DO TEMPO DE TURBO ?

GOTO VARRE ; NÃO - VOLTA P/ VARRE

; SIM

MOVLW TURBO_TECLA

MOVWF TEMPO_TURBO ; RECARREGA TEMPORIZADOR DO TURBO

; DAS TECLAS

CALL INCREMENTA_TIMER ; INCREMENTA O VALOR DO TIMER

GOTO VARRE ; VOLTA P/ VARREDURA DOS BOTÕES

; ************************* TRATAMENTO DO BOTÃO DE DOWN **********************

TRATA_BT_DOWN

; BTFSC ESTADO_TIMER ; TIMER ESTÁ PARADO ?

GOTO VARRE ; NÃO - VOLTA P/ VARRE

; SIM

DECFSZ FILTRO_BOTOES,F ; FIM DO FILTRO ? (RUIDO?)

GOTO VARRE ; NÃO - VOLTA P/ VARRE

; SIM - BOTÃO PRESSIONADO

DECFSZ TEMPO_TURBO,F ; FIM DO TEMPO DE TURBO ?

GOTO VARRE ; NÃO - VOLTA P/ VARRE

; SIM

MOVLW TURBO_TECLA

MOVWF TEMPO_TURBO ; RECARREGA TEMPORIZADOR DO TURBO

; DAS TECLAS

CALL DECREMENTA_TIMER ; DECREMENTA O VALOR DO TIMER

GOTO VARRE ; VOLTA P/ VARREDURA DOS BOTÕES

; ************************* TRATAMENTO DO BOTÃO START / STOP *****************

TRATA_BT_START_STOP

MOVF FILTRO_BOTOES,F

BTFSC STATUS,Z ; FILTRO JÁ IGUAL A ZERO ?

; (FUNÇÃO JÁ FOI EXECUTADA?)

GOTO VARRE ; SIM - VOLTA P/ VARREDURA DO TECLADO

; NÃO

DECFSZ FILTRO_BOTOES,F ; FIM DO FILTRO ? (RUIDO?)

GOTO VARRE ; NÃO - VOLTA P/ VARRE

; SIM - BOTÃO PRESSIONADO

; BTFSS ESTADO_TIMER ; TIMER ESTA LIGADO ?

GOTO LIGA_TIMER ; NÃO - ENTÃO LIGA

; SIM - ENTÃO DESLIGA

DESLIGA_TIMER

; BCF ESTADO_TIMER ; DESLIGA LED E FLAG DO ESTADO DO TIMER

BCF T1CON,TMR1ON ; PARA CONTADOR DO TMR1

GOTO VARRE ; VOLTA P/ VARREDURA DOS BOTÕES

LIGA_TIMER

MOVF UNIDADE,F

BTFSS STATUS,Z ; UNIDADE ESTÁ ZERADA ?

GOTO LIGA_TIMER_2 ; NÃO - PULA P/ LIGA_TIMER_2

; SIM - TESTA DEZENA

MOVF DEZENA,F

BTFSS STATUS,Z ; DEZENA ESTÁ ZERADA ?

GOTO LIGA_TIMER_2 ; NÃO - PULA P/ LIGA_TIMER_2

; SIM - TESTA CENTENA

MOVF CENTENA,F

BTFSS STATUS,Z ; CENTENA ESTÁ ZERADA ?

GOTO LIGA_TIMER_2 ; NÃO - PULA P/ LIGA_TIMER_2

; SIM - TESTA MILHAR1

MOVF MILHAR1,F

BTFSS STATUS,Z ; MILHAR ESTÁ ZERADO ?

GOTO LIGA_TIMER_2 ; NÃO - PULA P/ LIGA_TIMER_2

GOTO VARRE ; SIM - VOLTA P/ VARRER TECLADO

; SEM LIGAR O TIMER

LIGA_TIMER_2

MOVLW TMR1_HIGH

MOVWF TMR1H

MOVLW TMR1_LOW

MOVWF TMR1L ; INICIALIZA CONTADORES

MOVLW .2

MOVWF DIVISOR_TMR1 ; INICIALIZA DIVISOR

BSF T1CON,TMR1ON ; LIGA CONTAGEM DO TMR1

GOTO VARRE ; VOLTA P/ VARREDURA DOS BOTÕES

; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

; * FIM DO PROGRAMA *

; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

END ; FIM DO PROGRAMA

E o esquemático:

placa2.png

Por favor, ignorem qualquer "mancada" feia, garanto que é devido ao stress e cansaço do dia-a-dia:D

Abraços

Link para o comentário
Compartilhar em outros sites

João,

Olha, espero que esse sensor não seja do tipo que exija pré-calibração a partir de vários dados em I2C.... se for desses, e tiver de ser em Assembler , vai ser o CAPETA escrever o programa em Assembler hehehehehhe !

Por curiosidade, seu curso é de Eletrônica, ou é de Programação ??????

Juro que não vejo nenhum sentido exigir esse código em Assembler, quando todo o mundo está indo de C, em um curso orientado ao Hardware ( Eletrônica ) !

E olha que eu defendo o tal de "NÃO IMPORTA A COR DO GATO, DESDE QUE ELE PEGUE OS RATOS !!!! " , mas exigir em Assembler, doeu .....

Tá na hora de reciclar o teu professor, isso sim !!!!!! :D

Boa sorte, meu amigo !

Paulo

Link para o comentário
Compartilhar em outros sites

João,

Olha, espero que esse sensor não seja do tipo que exija pré-calibração a partir de vários dados em I2C.... se for desses, e tiver de ser em Assembler , vai ser o CAPETA escrever o programa em Assembler hehehehehhe !

Por curiosidade, seu curso é de Eletrônica, ou é de Programação ??????

Juro que não vejo nenhum sentido exigir esse código em Assembler, quando todo o mundo está indo de C, em um curso orientado ao Hardware ( Eletrônica ) !

E olha que eu defendo o tal de "NÃO IMPORTA A COR DO GATO, DESDE QUE ELE PEGUE OS RATOS !!!! " , mas exigir em Assembler, doeu .....

Tá na hora de reciclar o teu professor, isso sim !!!!!! :D

Boa sorte, meu amigo !

Paulo

Desculpa, expliquei mal. Falei com o professor ontem, a exigência é usar displays de 7 segmentos, a linguagem pode ser qualquer uma. O problema é que não aprendi praticamente NADA de programação de microcontroladores em C. :(

Achei alguns exemplos em C na internet mas não consegui nem compilar (usei o MPLAB, ele aceita programas em C ou só Assembler mesmo?). Tem algum compilador bom que possam recomendar? Acho que vou pegar esses exemplos mesmo, e simplesmente modificá-los usando o pouco que conheço de C...

Link para o comentário
Compartilhar em outros sites

João,

Agora sim !!!! É muito mais fácil, inclusive obter ajuda aqui no Fórum para o seu programa em C . !

Creio que agora o pessoal que domina o C vai te ajudar !

Infelizmente, eu também não sei nem como começa um programa em C, sou um burro velho empacado.... mas se voce quiser fazer em Basic, dá para te ajudar bastante.

Por exemplo, as rotinas que fazem o display multiplexado já estão prontas em um dos projetos do Tutorial de Programação em Basic para PIC, elas tratam 4 displays, mas é muito simples modificar para 6.

E do jeito que eu escreví elas, fica muito simples voce implementar no loop principal as rotinas para mostrar dia , mes , ano, hora, minuto, segundo e também a umidade relativa do ar.

Para voce ter uma ideia da facilidade em fazer o seu projeto, eu diria que dá para fazer todo o programa do seu projeto em um ou dois dias, incluindo os testes do simulador do PSI, antes de voce ter de montar o circuito.

Mas claro que usando o programa do display do tutorial e modificando para 6 dígitos, o resto é bico !!!!

Ah, uma pergunta : e a base de tempo, qual voce vai usar, vai usar um CI de relógio, ou implementar tudo por software, confiando no cristal de clock ? Usar um CI RTC é muito melhor, mais seguro, e simplifica bastante o software. Não se esqueça que vai ter de bolar ajuste de data e hora de alguma maneira, seja via serial a partir de um micro, ou seja via botões.

Aguarde aparecer alguém com dicas e sugestões em C para te orientar também, e em último caso, se não aparecer ninguém, e se voce preferir, então experimente o Píc Simulator IDE, que é o que é usado no Tutorial.

Boa sorte no projeto !

Paulo

Link para o comentário
Compartilhar em outros sites

João,

Ah, uma pergunta : e a base de tempo, qual voce vai usar, vai usar um CI de relógio, ou implementar tudo por software, confiando no cristal de clock ? Usar um CI RTC é muito melhor, mais seguro, e simplifica bastante o software. Não se esqueça que vai ter de bolar ajuste de data e hora de alguma maneira, seja via serial a partir de um micro, ou seja via botões.

A base do tempo vai ser por software mesmo, porque o próprio professor disse que não precisa ser um relógio preciso, é apenas pra se ter como "exemplo"... Ah sim, muito obrigado pela disposição cara, vou fazer como você disse, se não aparecer nenhuma solução em C, falo com você ;)

Abraço

Ps. O ajuste de data e hora vai ser por meio de botões ligados ao PIC. Todo o hardware já está montado e funcionando, o pic apresenta sinais de estar queimado mas isso com certeza é pela minha falta de cuidado na hora de ligar na alimentação; e meu sensor ainda não chegou pelo correio, mas com certeza até a próxima sexta já vai estar em minhas mãos.

Link para o comentário
Compartilhar em outros sites

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...