Estou fazendo o programa em assembly com o set de instruções reduzido, oscilador interno de 4MHz.
O programa está da seguinte maneira:
- Código: Selecionar todos
#INCLUDE <P18F25J50.INC>
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
; * CONSTANTES *
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
; DEFINIÇÃO DE TODAS AS CONSTANTES UTILIZADAS PELO SISTEMA
FILTRO_TECLA EQU .10
TRIPHI EQU .0
TRIPLO EQU .20
AVDEPTH EQU .5
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
; * VARIÁVEIS *
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
; DEFINIÇÃO DOS NOMES E ENDEREÇOS DE TODAS AS VARIÁVEIS UTILIZADAS PELO SISTEMA
CBLOCK 0x001 ; ENDEREÇO INICIAL DO PRIMEIRO BLOCO DE MEMÓRIA DO USUÁRIO
REGAUX ; REGISTRADOR AUXILIAR
CONT ; CONTADORES
CONT2
CONT3
FILTRO_ONOFF_PRESS ; FILTRO DAS TECLAS
FILTRO_ONOFF_NPRESS
FILTRO_MODE_PRESS
FILTRO_MODE_NPRESS
FILTRO_OKCE_PRESS
FILTRO_OKCE_NPRESS
ADHI ; VALOR DA CONVERSÃO A/D
ADLO
MEDIAHI
MEDIALO
MEDIAFRAC
MEDIATEMPHI
MEDIATEMPLO
TEMP1
TEMP2
DIFHI
DIFLO
TMR1HI
TMR1LO
FLAG ; FLAGS INDICADORES
ENDC ; FIM DO BLOCO
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
; * FLAGS DE CONTROLE *
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
; FLAGS DE ESTADOS E/OU ATIVAÇÃO UTILIZADOS EM ROTINAS ESPECÍFICAS OU GLOBAIS
#DEFINE KEYDOWN FLAG,0
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
; * ENTRADAS *
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
; DEFINIÇÃO DE TODOS OS PINOS QUE SERÃO UTILIZADOS COMO ENTRADA
; TECLA ON/OFF = RB0 = AN12
; TECLA MODE = RB1 = AN10
; TECLA OK/CE = RB2 = AN8
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
; * SAÍDAS *
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
; TODOS OS PINOS QUE SERÃO UTILIZADOS COMO SAÍDA
#DEFINE LED_ONOFF LATC,0 ; SAÍDA ON/OFF
#DEFINE LED_MODE LATC,2 ; SAÍDA MODE
#DEFINE LED_OKCE LATC,1 ; SAÍDA OK/CE
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
; * VETOR DE RESET *
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
; QUANDO O SISTEMA É LIGADO O PC INICIA NESTE ENDEREÇO E PULA PARA A CONFIGURAÇÃO
; DE INICIALIZAÇÃO DO SISTEMA
ORG 0x0000 ; ENDEREÇO INICIAL DE PROCESSAMENTO
GOTO INICIO ; DESVIA PARA A ROTINA DE INICIALIZAÇÃO
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
; * DELAY *
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
; ROTINAS DE TEMPORIZAÇÃO
DELAY_1MS
MOVLW .250
MOVWF CONT ; CARREGA CONTADOR
NOP ; 1uS
DECFSZ CONT,F ; 1uS
GOTO $-.4 ; 2uS
RETURN ; RETORNA
DELAY_250MS
MOVLW .250
MOVWF CONT2 ; CARREGA CONTADOR
CALL DELAY_1MS
DECFSZ CONT2,F
GOTO $-.6
RETURN ; RETORNA
DELAY_SEG
MOVLW .4 ; 4 -> 1 SEGUNDO
MOVWF CONT3 ; CARREGA CONTADOR
CALL DELAY_250MS
DECFSZ CONT3,F
GOTO $-.6
RETURN ; RETORNA
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
; * LEITURA DO CTMU *
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
; LEITURA DOS CHAVES CAPACITIVAS
LER_CTMU
; SELECIONA CANAL ANALÓGICO
MOVWF REGAUX ; SALVA CANAL ANALÓGICO
MOVLW B'00111100' ; RESETA ADCON0
IORWF ADCON0,F
RLNCF REGAUX,F
RLNCF REGAUX,W
IORLW B'11000011'
ANDWF ADCON0,F ; SALVA CONFIGURAÇÃO DO CANAL
; DESCARREGA CIRCUITO A/D
BSF CTMUCONH,IDISSEN ; ATIVA DESCARGA PARA O TERRA
NOP ; ESPERA DESCARGA
BCF CTMUCONH,IDISSEN ; FINALIZA DESCARGA DO CIRCUITO A/D
; CARREGA CIRCUITO A/D
BSF CTMUCONL,EDG1STAT ; INICIA CARGA DO CIRCUITO A/D
NOP ; ESPERA CARGA
BCF CTMUCONL,EDG1STAT ; FINALIZA CARGA DO CIRCUITO A/D
; LÊ VALOR DO CONVERSOR A/D
BSF ADCON0,GO_DONE ; INICIA CONVERSÃO A/D
BTFSC ADCON0,GO_DONE ; ESPERA FIM DA CONVERSÃO A/D
GOTO $-.2
MOVF ADRESH,W ; SALVA VALOR A/D
MOVWF ADHI
MOVF ADRESL,W
MOVWF ADLO
RETURN ; RETORNA
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
; * CÁLCULO DA MÉDIA *
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
; CALCULA MÉDIA DOS VALORES A/D
; ENTRADA: ADHI:ADLO
CALC_MEDIA
MOVF MEDIAHI,W
MOVWF MEDIATEMPHI
MOVF MEDIALO,W
MOVWF MEDIATEMPLO
CLRF TEMP2 ; MAKE A COPY OF THE ORIGINAL VALUE
CALL DIVIDEBY2PWRN ; DIVIDE THE COPY BY 2^N
MOVF TEMP2,W
SUBWF MEDIAFRAC ; AND SUBTRACT THE RESULT FROM THE ORIGINAL
BTFSC STATUS,C
GOTO HOPOVER
DECF MEDIALO
MOVLW .255
XORWF MEDIALO,W
BTFSC STATUS,Z
DECF MEDIAHI
HOPOVER
MOVF MEDIATEMPLO,W
SUBWF MEDIALO
BTFSS STATUS,C
DECF MEDIAHI
MOVF MEDIATEMPHI,W
SUBWF MEDIAHI ; AVERAGE - 1/(2^N)
MOVF ADHI,W
MOVWF MEDIATEMPHI
MOVF ADLO,W
MOVWF MEDIATEMPLO ; MAKE A COPY OF THE ORIGINAL VALUE
CLRF TEMP2
CALL DIVIDEBY2PWRN ; DIVIDE BY 2^N
MOVF TEMP2,W
ADDWF MEDIAFRAC
BTFSS STATUS,C
GOTO HOPOVER2
INCF MEDIALO
BTFSC STATUS,Z
INCF MEDIAHI
HOPOVER2
MOVF MEDIATEMPLO,W
ADDWF MEDIALO
BTFSC STATUS,C
INCF MEDIAHI
MOVF MEDIATEMPHI,W
ADDWF MEDIAHI
RETLW .0
DIVIDEBY2PWRN
MOVLW AVDEPTH
MOVWF TEMP1
SHIFT1
BCF STATUS,C
RRCF MEDIATEMPHI
RRCF MEDIATEMPLO
RRCF TEMP2
DECFSZ TEMP1
GOTO SHIFT1
RETLW .0
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
; * VERIFICA DIFERENÇA *
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
; VRIFICA DIFERENÇA ENTRE O VALOR ATUAL E A MÉDIA
; SAÍDA: ADHI:ADLO
VERIF_DIF
MOVF MEDIAHI,W
MOVWF DIFHI
MOVF MEDIALO,W
MOVWF DIFLO ; MAKE A COPY OF THE AVERAGEVALUE
MOVF ADLO,W
SUBWF DIFLO
BTFSS STATUS,C
DECF DIFHI
MOVF ADHI,W
SUBWF DIFHI ; AVERAGEVALUE - CURRENTVALUE
BTFSC STATUS,C ; IS THE DIFFERENCE NEGATIVE?
GOTO EVALDIFFERENCE ; NO POSITIVE, CHECK IF IT EXCEEDS THE TRIP POINT
MOVF ADHI,W ; YES, KEY IS RELEASED
MOVWF MEDIAHI ; AVERAGE SHOULD FOLLOW ACTUAL VALUE
MOVF ADLO,W
MOVWF MEDIALO
CLRF DIFHI
CLRF DIFLO
BCF KEYDOWN
RETLW .0
EVALDIFFERENCE
BCF KEYDOWN
MOVLW TRIPHI
SUBWF DIFHI,W
BTFSS STATUS,Z ; ARE HI BYTES EQUAL?
GOTO RESULTS
MOVLW TRIPLO ; YES, COMPARE LOWER BYTES
SUBWF DIFLO,W
RESULTS
BTFSS STATUS,C ; WAS THE DIFFERENCE > TRIP POINT?
RETLW .0 ; NO, RETURN
BSF KEYDOWN ; YES, SET THE KEYDOWN FLAG
RETLW .0
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
; * INÍCIO DO PROGRAMA *
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
; INICIALIZA PORTAS, CTMU E O CONVERSOR A/D
INICIO
; CONFIGURA PORTAS
CLRF PORTA ; LIMPA PORTAS
CLRF PORTB
CLRF PORTC
CLRF LATA ; LIMPA LATCHES
CLRF LATB
CLRF LATC
MOVLW B'11111111' ; CONFIGURA TODO RA0 A RA7 COMO ENTRADA
MOVWF TRISA
MOVLW B'11111111' ; CONFIGURA TODO RB0 A RB7 COMO ENTRADA
MOVWF TRISB
MOVLW B'11111000' ; CONFIGURA RC0, RC1 E RC2 COMO SAÍDA
MOVWF TRISC ; E RC3 A RC7 COMO ENTRADA
; CONFIGURA MÓDULO CTMU
MOVLW B'10000000'
; ||||||||__ (RESERVADO)
; |||||||___ IDISSEN CORRENTE PARA TERRA DESATIVADO
; ||||||____ EDGSEQEN SEM SEQUÊNCIA
; |||||_____ EDGEN BORDAS BLOQUEADAS
; ||||______ TGEN DELAY DESABILITADO
; |||_______ CTMUISDL CONTINUA EM MODO DE ESPERA
; ||________ (NÃO USADO)
; |_________ CTMUEN MÓDULO CMTU HABILITADO
MOVWF CTMUCONH
MOVLW B'10010000'
; ||||||||__ EDG1STAT SEM EVENTO NA BORDA 1
; |||||||___ EDG2STAT SEM EVENTO NA BORDA 2
; ||||||____ EDG1SEL0
; |||||_____ EDG1SEL1 BORDA 1 PROGRAMADA PARA DISPARO COM TIMER 1
; ||||______ EDG1POL BORDA 1 PROGRAMADA PARA RESPOSTA POSITIVA
; |||_______ EDG2SEL0
; ||________ EDG2SEL1 BORDA 2 PROGRAMADA PARA DISPARO COM TIMER 1
; |_________ EDG2POL BORDA 2 PROGRAMADA PARA RESPOSTA POSITIVA
MOVWF CTMUCONL
MOVLW B'000000011'
; ||||||||__ IRNG0 FONTE DE CORRENTE (55uA)
; |||||||___ IRNG1 1 1 = 55uA
; |||||| 1 0 = 5.5uA
; |||||| 0 1 = 0.55uA
; |||||| 0 0 = DESABILITADO
; ||||||____ ITRIM0
; |||||_____ ITRIM1
; ||||______ ITRIM2
; |||_______ ITRIM3
; ||________ ITRIM4
; |_________ ITRIM5 CORRENTE DE SAÍDA NOMINAL ESPECIFICADO EM IRNG<1:0>
MOVWF CTMUICON
; CONFIGURA CONVERSOR A/D
MOVLW B'00011111'
; ||||||||__ PCFG0
; |||||||___ PCFG1
; ||||||____ PCFG2
; |||||_____ PCFG3
; ||||______ PCFG4 AN0 A AN4 COMO PORTAS DIGITAIS
; |||_______ (NÃO USADO)
; ||________ (NÃO USADO)
; |_________ (NÃO USADO)
MOVWF REGAUX
MOVFF REGAUX,ANCON0
MOVLW B'00001010'
; ||||||||__ PCFG8
; |||||||___ PCFG9
; ||||||____ PCFG10
; |||||_____ PCFG11 AN8, AN10 E AN12 COMO PORTAS ANALÓGICAS
; ||||______ PCFG12 AN9 E AN11 COMO PORTAS DIGITAIS
; |||_______ (NÃO USADO)
; ||________ (NÃO USADO)
; |_________ VBGEN REFERÊNCIA DE 1.2V DESATIVADA
MOVWF REGAUX
MOVFF REGAUX,ANCON1
MOVLW B'00000001'
; ||||||||__ ADON CONVERSOR A/D HABILITADO
; |||||||___ GO_DONE CONVERSÃO PARADA
; ||||||____ CHS0
; |||||_____ CHS1
; ||||______ CHS2
; |||_______ CHS3 CANAL 0 SELECIONADO
; ||________ VCFG0 TENSÃO DE REFERÊNCIA POSITIVA = VDD
; |_________ VCFG1 TENSÃO DE REFERÊNCIA NEGATIVA = VSS
MOVWF ADCON0
MOVLW B'10010100'
; ||||||||__ ADCS0 CLOCK DO CONVERSOR A/D (FOSC/4)
; |||||||___ ADCS1 1 1 0 = FOSC/64
; ||||||____ ADCS2 1 0 1 = FOSC/16
; ||||| 1 0 0 = FOSC/4
; ||||| 0 1 1 = FRC
; ||||| 0 1 0 = FOSC/32
; ||||| 0 0 1 = FOSC/8
; ||||| 0 0 0 = FOSC/2
; |||||_____ ACQT0 TEMPO DE AQUISIÇÃO A/D (4TAD)
; ||||______ ACQT1 1 1 1 = 20 TAD
; |||_______ ACQT2 1 1 0 = 16 TAD
; || 1 0 1 = 12 TAD
; || 1 0 0 = 8 TAD
; || 0 1 1 = 6 TAD
; || 0 1 0 = 4 TAD
; || 0 0 1 = 2 TAD
; || 0 0 0 = 0 TAD
; ||________ ADCAL CONVERSÃO A/D EM OPERAÇÃO NORMAL
; |_________ ADFM FORMATO DO RESULTADO (DIREITA)
; 0 = JUSTIFICADO A ESQUERDA
; 1 = JUSTIFICADO A DIREITA
MOVWF ADCON1
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
; * INICIALIZAÇÃO DAS VARIÁVEIS *
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
; LIMPA VERIÁVEIS
CLRF FLAG
CLRF REGAUX
CLRF CONT
CLRF CONT2
CLRF CONT3
CLRF FILTRO_ONOFF_PRESS
CLRF FILTRO_ONOFF_NPRESS
CLRF FILTRO_MODE_PRESS
CLRF FILTRO_MODE_NPRESS
CLRF FILTRO_OKCE_PRESS
CLRF FILTRO_OKCE_NPRESS
CLRF ADHI
CLRF ADLO
CLRF MEDIAHI
CLRF MEDIALO
CLRF MEDIAFRAC
CLRF MEDIATEMPHI
CLRF MEDIATEMPLO
CLRF TEMP1
CLRF TEMP2
CLRF DIFHI
CLRF DIFLO
CLRF TMR1HI
CLRF TMR1LO
; PISCA LEDS PARA INDICAR INICIALIZAÇÃO
BSF LED_ONOFF
BSF LED_MODE
BSF LED_OKCE
CALL DELAY_250MS
BCF LED_ONOFF
BCF LED_MODE
BCF LED_OKCE
; ATIVA WATCHDOG TIMER (WDT)
BSF WDTCON,SWDTEN
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
; * ROTINA PRINCIPAL *
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
; LÊ VALOR DAS TECLAS A CADA 1 MILISEGUNDO
MAIN
CLRWDT ; LIMPA WATCHDOG TIMER (WDT)
CALL DELAY_1MS ; ESPERA 1 MILISEGUNDO
; VERIFICA TECLA ON/OFF
VERIF_ONOFF
MOVLW .12
CALL LER_CTMU ; LÊ VALOR A/D
CALL CALC_MEDIA ; CALCULA MÉDIA
CALL VERIF_DIF ; VERIFICA TECLA PRESSIOANADA
COMF MEDIAHI,W
MOVWF TMR1HI
COMF MEDIALO,W
MOVWF TMR1LO
BTFSS KEYDOWN ; FILTRA TECLA
GOTO ONOFF_NPRESS
BSF LED_OKCE
MOVLW FILTRO_TECLA
MOVWF FILTRO_ONOFF_NPRESS
DECFSZ FILTRO_ONOFF_PRESS,F
GOTO VERIF_MODE
BSF LED_ONOFF
GOTO VERIF_MODE
ONOFF_NPRESS
BCF LED_OKCE
MOVLW FILTRO_TECLA
MOVWF FILTRO_ONOFF_PRESS
DECFSZ FILTRO_ONOFF_NPRESS,F
GOTO VERIF_MODE
BCF LED_ONOFF
; VERIFICA TECLA MODE
VERIF_MODE
MOVLW .10
CALL LER_CTMU ; LÊ VALOR A/D
; VERIFICA TECLA OK/CE
VERIF_OKCE
MOVLW .8
CALL LER_CTMU ; LÊ VALOR A/D
GOTO MAIN ; RETORNA AO INÍCIO DO LOOP PRINCIPAL