Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;* MODIFICAÇÕES PARA USO COM 12F675 *
- ;* FEITAS PELO PROF. MARDSON *
- ;* FEVEREIRO DE 2016 *
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;* NOME DO PROJETO *
- ;* CLIENTE *
- ;* DESENVOLVIDO PELA MOSAICO ENGENHARIA E CONSULTORIA *
- ;* VERSÃO: 1.0 DATA: 17/06/03 *
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;* DESCRIÇÃO DO ARQUIVO *
- ;*-----------------------------------------------------------------*
- ;* MODELO PARA O PIC 12F675 *
- ;* *
- ;* *
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;* ARQUIVOS DE DEFINIÇÕES *
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- #INCLUDE <p12f675.inc> ;ARQUIVO PADRÃO MICROCHIP PARA 12F675
- __CONFIG _BODEN_OFF & _CP_OFF & _PWRTE_ON & _WDT_OFF & _MCLRE_ON & _INTRC_OSC_NOCLKOUT
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;* PAGINAÇÃO DE MEMÓRIA *
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;DEFINIÇÃO DE COMANDOS DE USUÁRIO PARA ALTERAÇÃO DA PÁGINA DE MEMÓRIA
- #DEFINE BANK0 BCF STATUS,RP0 ;SETA BANK 0 DE MEMÓRIA
- #DEFINE BANK1 BSF STATUS,RP0 ;SETA BANK 1 DE MAMÓRIA
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;* VARIÁVEIS *
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ; DEFINIÇÃO DOS NOMES E ENDEREÇOS DE TODAS AS VARIÁVEIS UTILIZADAS
- ; PELO SISTEMA
- CBLOCK 0x20 ;ENDEREÇO INICIAL DA MEMÓRIA DE
- ;USUÁRIO
- W_TEMP ;REGISTRADORES TEMPORÁRIOS PARA USO
- STATUS_TEMP ;JUNTO ÀS INTERRUPÇÕES
- LOOP_VAL
- AUX
- ENTRADA_A
- ENTRADA_B
- RESTO
- RESTO_TEMP
- X
- X_DECIMAL
- Y
- D1
- D2
- RESULTADO
- NUM_DISPLAY
- DENOMINADOR
- ; CONVERSÃO PARA BCD
- FIRST_DIGIT
- SECOND_DIGIT
- ENDC ;FIM DO BLOCO DE MEMÓRIA
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;* FLAGS INTERNOS *
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ; DEFINIÇÃO DE TODOS OS FLAGS UTILIZADOS PELO SISTEMA
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;* CONSTANTES *
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ; DEFINIÇÃO DE TODAS AS CONSTANTES UTILIZADAS PELO SISTEMA
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;* ENTRADAS *
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ; DEFINIÇÃO DE TODOS OS PINOS QUE SERÃO UTILIZADOS COMO ENTRADA
- ; RECOMENDAMOS TAMBÉM COMENTAR O SIGNIFICADO DE SEUS ESTADOS (0 E 1)
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;* SAÍDAS *
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ; DEFINIÇÃO DE TODOS OS PINOS QUE SERÃO UTILIZADOS COMO SAÍDA
- ; RECOMENDAMOS TAMBÉM COMENTAR O SIGNIFICADO DE SEUS ESTADOS (0 E 1)
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;* VETOR DE RESET *
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ORG 0x00 ;ENDEREÇO INICIAL DE PROCESSAMENTO
- GOTO INICIO
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;* INÍCIO DA INTERRUPÇÃO *
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ; ENDEREÇO DE DESVIO DAS INTERRUPÇÕES. A PRIMEIRA TAREFA É SALVAR OS
- ; VALORES DE "W" E "STATUS" PARA RECUPERAÇÃO FUTURA
- ORG 0x04 ;ENDEREÇO INICIAL DA INTERRUPÇÃO
- MOVWF W_TEMP ;COPIA W PARA W_TEMP
- SWAPF STATUS,W
- MOVWF STATUS_TEMP ;COPIA STATUS PARA STATUS_TEMP
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;* ROTINA DE INTERRUPÇÃO *
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ; AQUI SERÁ ESCRITA AS ROTINAS DE RECONHECIMENTO E TRATAMENTO DAS
- ; INTERRUPÇÕES
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;* ROTINA DE SAÍDA DA INTERRUPÇÃO *
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ; OS VALORES DE "W" E "STATUS" DEVEM SER RECUPERADOS ANTES DE
- ; RETORNAR DA INTERRUPÇÃO
- SAI_INT
- SWAPF STATUS_TEMP,W
- MOVWF STATUS ;MOVE STATUS_TEMP PARA STATUS
- SWAPF W_TEMP,F
- SWAPF W_TEMP,W ;MOVE W_TEMP PARA W
- RETFIE
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;* ROTINAS E SUBROTINAS *
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ; CADA ROTINA OU SUBROTINA DEVE POSSUIR A DESCRIÇÃO DE FUNCIONAMENTO
- ; E UM NOME COERENTE ÀS SUAS FUNÇÕES.
- ; ************************** DIVISÃO********************************
- ; Efetua a divisão de dois números, retornando também o resto.
- ;
- ; ENTRADAS: AUX (Numerador), DENOMINADOR (Denominador)
- ; SAÍDAS: W = QUOCIENTE, RESTO = resto da divisão
- ;
- ; TEMPORARIOS: RESULTADO
- DIVISAO
- MOVFW DENOMINADOR ; COPIA O DENOMINADOR PRO WORK
- SUBWF AUX, 0; SUBTRAI O DENOMINADOR DA VARIAVEL AUXILIAR (TOTAL)
- BTFSC STATUS, C ; VERIFICA SE É POSSÍVEL DIVIDIR (AUX > DENOMINADOR)
- GOTO DECREMENTA ; SE SIM, INCREMENTA O RESULTADO DA DIVISAO E ATUALIZA AUX
- ; FIM DA DIVISÃO (AUX < DENOMINADOR, NESSE MOMENTO)
- MOVFW AUX ; COPIA O QUE SOBROU EM AUX
- MOVWF RESTO ; E JOGA EM RESTO
- ; COPIA O RESULTADO PARA O WORK (SAIDA)
- MOVFW RESULTADO
- CLRF RESULTADO ; LIMPA O RESULTADO
- RETURN
- DECREMENTA ; INCREMENTA O RESULTADO DA DIVISAO E ATUALIZA AUX
- MOVWF AUX ; AUX = AUX - DENOMINADOR
- INCF RESULTADO, 1 ; INCREMENTA O RESULTADO DA DIVISAO EM 1 UNIDADE
- GOTO DIVISAO ; VOLTA PARA VERIFICAR SE AINDA É POSSÍVEL DIVIDIR O NOVO VALOR DE AUX
- ; ************************** DIVISÃO DO RESTO****************************
- ; Verifica se a divisão possui resto. Multiplica por 10 o Resto e divide.
- ; Caso RESTO > 25, há um tratamento especial: o denominador é dividido por dez, ao invés de
- ; multiplicar o numerador por dez. Isto é feito para evitar o estouro do limite de 255 (1 byte)
- ;
- ; ENTRADAS: RESTO (Numerador), DENOMINADOR (Denominador)
- ; SAÍDAS: W = QUOCIENTE, RESTO = resto da divisão
- ;
- ; TEMPORARIOS: LOOP_VAL, AUX
- DIVISAO_RESTO
- CLRF AUX ; LIMPA A VARIAVEL AUXILIAR
- ; VERIFICA SE O RESTO É ZERO
- MOVFW RESTO
- XORLW .0 ; XOR(RESTO, 0) ATIVARÁ O FLAG STATUS,Z
- BTFSC STATUS,Z ; VERIFICA SE EXISTE RESTO
- RETURN ; SE Z = 1, ENTÃO RESTO = 0. RETORNA.
- ; VERIFICA SE O RESTO É >=26, POIS NESTE CASO NÃO DÁ PRA MULTIPLICAR POR DEZ
- MOVLW .26
- SUBWF RESTO, W
- BTFSC STATUS, C
- GOTO DIVIDE_ESTOURO ; TRATAMENTO ESPECIAL PARA RESTO >= 26
- ; MULTIPLICA O RESTO POR DEZ
- MOVFW RESTO
- MOVWF AUX
- CALL MULTIPLICA_10
- ; SE MESMO APÓS A MULTIPLICAÇÃO POR 0 NÃO FOR POSSÍVEL DIVIDIR
- MOVFW DENOMINADOR
- SUBWF RESTO, W; RESTO - DENOMINADOR
- MOVLW .0
- BTFSS STATUS, C ; VERIFICA SE MESMO APÓS A MULTIPLICAÇÃO, AINDA NÃO DÁ PRA DIVIDIR
- RETURN ; RETORNA 0
- ; CASO SEJA POSSÍVEL DIVIDIR
- CLRF RESULTADO ;LIMPA A VARIAVEL RESULTADO
- ; EFETUA A DIVISAO E RETORNA O RESULTADO
- CALL DIVISAO
- RETURN
- DIVIDE_ESTOURO
- ; **** INICIO DA DIVISAO DO DENOMINADOIR POR DEZ ****
- MOVFW DENOMINADOR ; COPIA O DENOMINADOR PRO NUMERADOR
- MOVWF AUX
- MOVLW .10 ; COPIA "10" PARA O DENOMINADOR
- MOVWF DENOMINADOR
- ; GUARDA O VALOR TEMPORARIO DO RESTO ORIGINAL EM RESTO_TEMP
- MOVFW RESTO
- MOVWF RESTO_TEMP
- CALL DIVISAO ; DIVIDE O DENOMINADOR ORIGINAL POR 10
- MOVWF DENOMINADOR
- ; **** FIM DA DIVISAO DO DENOMINADOR POR DEZ ****
- MOVFW RESTO_TEMP ; DEVOLVE O NUMERADOR ORIGINAL
- MOVWF AUX
- CALL DIVISAO ; DIVIDE O RESTO PELO (DENOMINADOR / 10) E RETORNA
- RETURN
- ;MAKE_DIVISIVEL
- ;MOVFW ENTRADA_B
- ;SUBWF RESTO, W; RESTO - DENOMINADOR
- ;BTFSS STATUS, C ; Verifica se já pode dividir (RESTO > DENOMINADOR)
- ;CALL MULTIPLICA_10
- ;RETURN
- ; MULTIPLICA O VALOR EM AUX POR DEZ E SALVA EM RESTO
- MULTIPLICA_10
- MOVLW .9
- MOVWF LOOP_VAL
- LOOP10 ;LOOP (RODA 9 VEZES)
- MOVFW RESTO
- ADDWF AUX, 1 ; AUX = AUX + RESTO
- DECFSZ LOOP_VAL,1
- GOTO LOOP10
- ; COPIA O RESULTADO PARA RESTO
- MOVFW AUX
- MOVWF RESTO
- RETURN
- ; ************************** ARREDONDAMENTO ****************************
- ; Arredonda o numero fornecido.
- ; Regra adotada:
- ; 1) Segunda casa decimal maior que 5, arredonda a primeira casa.
- ; 2) Se a primeira casa decimal for 10 após o arredondamento, seta como ZERO e aumenta o valor de X.
- ;
- ; ENTRADAS: Y (Primeira casa decimal), D2 (Segunda casa decimal)
- ; VALORES MODIFICADOS: X (se Y == 10 em algum momento), Y
- ARREDONDAR
- ; VERIFICA SE O SEGUNDO DIGITO É MAIOR QUE 5
- MOVLW .5
- SUBWF D2,W ; W=D2-5
- BTFSC STATUS, C
- INCF Y,F ; SE D2>5, ARREDONDA Y.
- ; VERIFICA SE APÓS O ARREDONDAMENTO, Y == 10
- MOVFW Y
- XORLW .10
- BTFSS STATUS, Z ; Y == 10?
- RETURN ; SE Y != 10, RETORNA.
- INCF X,F ; SE Y == 10, X++
- CLRF Y ; SE Y == 10, Y=0
- RETURN
- ; ************************** DISPLAY ****************************
- ; Escreve no Display o numero fornecido.
- ;
- ; ENTRADAS: NUM_DISPLAY
- ; VALORES MODIFICADOS: GP0, GP1, GP4, GP5
- DISPLAY_RESULTADO
- ; O PROGRAMA SÓ ENTRA NESSA ROTINA APENAS SE FOR MENOR QUE 9.
- ; LOGO, NÃO HÁ PROBLEMA EM TRATAR DIRETAMENTE OS BITS ABAIXO.
- ; LIGA LED 1
- BTFSC NUM_DISPLAY, 0
- BSF GPIO, 0
- ; LIGA LED 2
- BTFSC NUM_DISPLAY, 1
- BSF GPIO, 1
- ; LIGA LED 3
- BTFSC NUM_DISPLAY, 2
- BSF GPIO, 4
- ; LIGA LED 4
- BTFSC NUM_DISPLAY, 3
- BSF GPIO, 5
- RETURN
- ; TRATA O DISPLAY QUANDO X > 10
- ESTOURO
- BSF GPIO, 2 ; LIGA O LED DE ESTOURO
- MOVLW .255 ; COLOCA O LED COMO 1111
- MOVWF NUM_DISPLAY ; O NUM_DISPLAY VIRA 255
- RETURN
- ; ************************** CONVERSÃO EM BCD ****************************
- ; Separa o valor em dígitos para conversão em BCD.
- ; MÉTODO: Divide por 10 e pega o resto. Depois, inverte os dígitos e faz um IORWF
- ;
- ; ENTRADAS: X
- ; VALORES MODIFICADOS: FIRST_DIGIT, SECOND_DIGIT
- ; TEMPORARIOS: AUX
- FIND_DIGITS ; ENCONTRAR DÍGITOS
- CLRF RESULTADO ; LIMPA O RESULTADO
- ; COPIA X PARA O NUMERADOR
- MOVFW X
- MOVWF AUX
- ; COPIA 10 PARA O DENOMINADOR
- MOVLW .10
- MOVWF DENOMINADOR
- ; EFETUA A DIVISÃO
- CALL DIVISAO
- ; GUARDA O PRIMEIRO DIGITO
- MOVWF FIRST_DIGIT
- ; GUARDA O SEGUNDO DIGITO
- MOVFW RESTO
- MOVWF SECOND_DIGIT
- ; JUNTA OS DÍGITOS EM UM ÚNICO NÚMERO BCD
- SWAPF FIRST_DIGIT, 0 ; INVERTE OS NIBBLES
- IORWF SECOND_DIGIT, 0 ; FAZ UM OR DO PRIMEIRO DIGITO INVERTIDO COM O SEGUNDO
- ; Ex.: 0101 0000 OR 00001010 -> 0101 1010
- RETURN
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;* INICIO DO PROGRAMA *
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- INICIO
- BANK1 ;ALTERA PARA O BANCO 1
- MOVLW B'00001000' ;CONFIGURA TODAS AS PORTAS DO GPIO (PINOS)
- MOVWF TRISIO ;COMO SAÍDAS
- CLRF ANSEL ;DEFINE PORTAS COMO Digital I/O
- MOVLW B'00000100'
- MOVWF OPTION_REG ;DEFINE OPÇÕES DE OPERAÇÃO
- MOVLW B'00000000'
- MOVWF INTCON ;DEFINE OPÇÕES DE INTERRUPÇÕES
- BANK0 ;RETORNA PARA O BANCO
- MOVLW B'00000111'
- MOVWF CMCON ;DEFINE O MODO DE OPERAÇÃO DO COMPARADOR ANALÓGICO
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;* INICIALIZAÇÃO DAS VARIÁVEIS *
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;* ROTINA PRINCIPAL *
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- MAIN
- ; DEFINE OS VALORES DE ENTRADA
- MOVLW .250
- MOVWF ENTRADA_A
- MOVLW .10
- MOVWF ENTRADA_B
- ; LIMPA TODAS AS PORTAS, EXCETO GP3 (CHAVE)
- BCF GPIO,0
- BCF GPIO,1
- BCF GPIO,2
- BCF GPIO,4
- BCF GPIO,5
- ; LIMPA AS SAÍDAS
- CLRF RESULTADO
- CLRF X
- CLRF Y
- ; ********************** INICIO DA DIVISÃO ***********************
- ; COPIA A ENTRADA_A PARA O NUMERADOR
- MOVFW ENTRADA_A
- MOVWF AUX
- ; COPIA A ENTRADA_B PARA O DENOMINADOR
- MOVFW ENTRADA_B
- MOVWF DENOMINADOR
- ; CHAMA A FUNÇÃO DE DIVISÃO
- CALL DIVISAO ; DIVISAO(AUX = NUMERADOR, DENOMINADOR); SAÍDA: Quociente em WORK. Resto em RESTO.
- MOVWF X ; GUARDA A SAÍDA NO WORK
- ; PRIMEIRA CASA DECIMAL (DIVIDIR O RESTO)
- CALL DIVISAO_RESTO; DIVIDE O RESTO PELO DENOMINADOR
- MOVWF D1 ; D1 = PRIMEIRA CASA DECIMAL
- MOVWF Y ; COPIA DIRETO PARA Y. LOGO MAIS SERÁ FEITO O ARREDONDAMENTO.
- ; SEGUNDA CASA DECIMAL (DIVIDIR O RESTO DO RESTO)
- CALL DIVISAO_RESTO
- MOVWF D2 ; D2 = SEGUNDA CASA DECIMAL
- ; FUNCAO DE ARREDONDAMENTO ( D2 > 5, ARREDONDA. D2 === 10, INCREMENTA D1 E ZERA D2)
- CALL ARREDONDAR
- ; ********************** FIM DA DIVISÃO ***********************
- ; *************** INICIO DA CONVERSÃO EM BCD ******************
- ; GUARDA O VALOR DE X EM DECIMAL NA VARIAVEL X_DECIMAL
- MOVFW X
- MOVWF X_DECIMAL
- ; SEPARACAO EM DIGITOS (EX.: 15 -> FIRST_DIGIT = 1, SECOND_DIGIT = 5)
- CALL FIND_DIGITS
- MOVWF X ; SALVA O QUOCIENTE EM BCD EM X
- ; *************** FIM DA CONVERSÃO EM BCD **********************
- ; **************** INÍCIO DA ESCRITA NO VISOR ******************
- ; TODO: VERIFICAR SE GP3 É LOW. SE SIM, COPIAR Y PRA RESULTADO
- ; TODO: VERIFICAR SE GP3 É HIGH. SE SIM, COPIAR X PRA RESULTADO
- MOVFW X ; COPIA A PARTE INTEIRA PRO WORK. CASO GP3=HIGH, A PRÓXIMA INSTRUÇÃO SERÁ PULADA, MANTENDO ESTE VALOR NO WORK.
- BTFSS GPIO,3 ; TESTA O VALOR DE GP3
- MOVFW Y ; SE GP3=LOW, COPIA A PARTE DECIMAL.
- MOVWF NUM_DISPLAY ; COPIA O QUE ESTIVER NO WORK (X OU Y, DEPENDENDO DE GP3) PARA A VARIAVEL RESULTADO
- ; VERIFICA SE NUM_DISPLAY > 10
- ; SE NUM_DISPLAY = X
- ; NOTE QUE X ESTÁ EM BCD. LOGO, SE X (DECIMAL) FOR 10, EM BCD SERÁ 0x10 = 16
- ; PORTANTO A VALIDAÇÃO ABAIXO AINDA É VÁLIDA.
- ; SE NUM_DISPLAY = Y
- ; COMO Y SEMPRE ESTÁ ENTRE 0 E 9, A VERIFICAÇÃO TAMBÉM FUNCIONA NORMALMENTE.
- MOVLW .10
- SUBWF X, W
- BTFSC STATUS, C
- CALL ESTOURO ; SE NUM_DISPLAY >= 10
- ; DAQUI PRA BAIXO = SE NUM_DISPLAY < 10
- CALL DISPLAY_RESULTADO
- ; **************** FIM DA ESCRITA NO VISOR ******************
- GOTO MAIN
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;* FIM DO PROGRAMA *
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- END
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement