o codigo foi retirado de um artigo da saber eletronica.
include <p12F675.inc>
include <general.inc>
EXTERN Contador,Acum0,Acum1,Timer0,Timer1
__CONFIG _CPD_OFF & _CP_OFF & _BODEN_OFF & _MCLRE_ON & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT
Reset CODE H'0'
goto main
MainCode CODE
; ***************************************
; ********* RESET Vector ****************
; ***************************************
main:
BANKSEL OSCCAL
call 3FFh ;Recupera calibração do oscilador
movwf OSCCAL
movlw b'00001011' ;Entradas digitais -> GP0=Foto0; GP1=Foto1; GP2=LED; GP3=?; GP4=Out0; GP5=Out1
movwf TRISIO
movlw b'00010011' ;Entradas analógicas -> ANSEL=0x13
movwf ANSEL
movlw 08H ;Internal instruction cycle clock (CLKOUT); Prescaler is assigned to the WDT
movwf OPTION_REG
BANKSEL CMCON
movlw 0x7 ;Desabilita comparador
movwf CMCON
call InicializaVariaveis
clrf Timer0
clrf Timer0+1
clrf Timer0+2
clrf Timer0+3
clrf Timer1
clrf Timer1+1
clrf Timer1+2
clrf Timer1+3
movlw b'10000001' ;Configura CAD -> Right justified;VREF=VDD;Channel 00(AN0);ADON
movwf ADCON0
movlw TIMER_CONSTANT ;Inicializa Temporização do TIMER0
movwf TMR0
movlw b'10100000' ;Habilita interrupção do timer 0 (INTCON = 0xA0)
movwf INTCON
loop:
goto loop ;Nada (loop sem fim)
InicializaVariaveis:
GLOBAL InicializaVariaveis
BANKSEL GPIO ; Garante Banco 0
movlw .1
clrf Contador ; Zera contador
clrf Acum0 ; Zera acumulador0
clrf Acum0+1
clrf Acum0+2
; clrf Acum0+3 ;=============
movwf Acum0+3
clrf Acum1 ; Zera acumulador1
clrf Acum1+1
clrf Acum1+2
; clrf Acum1+3 ;===============
movwf Acum1+3
bcf GPIO,LED ; Apaga LED
return
org 0x3FF
dt 0xFF ; calibration value
end
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
include <p12F675.inc>
include <general.inc>
extern InicializaVariaveis
UDATA_SHR
Contador RES 1 ; Contador do numero de amostras (0~255)
Acum0 RES 14 ; Acumulador da integração do fotosensor 0
Acum1 RES 4 ; Acumulador da integração do fotosensor 1
Timer0 RES 4 ; Temporizador do monoestável 0
Timer1 RES 4 ; Temporizador do monoestável 1
W_TEMP RES 1 ; Registros temporários para interrupção
STATUS_TEMP RES 1
GLOBAL Contador,Acum0,Acum1,Timer0,Timer1
; Subtrai uma variavel de 32 bits do valor do CAD (16 bits)
Sub32_CAD macro Variavel
BANKSEL ADRESL
movf ADRESL,w
BANKSEL Variavel
subwf Variavel,f
BANKSEL ADRESH
movf ADRESH,w
btfss STATUS,C
incf ADRESH,w
BANKSEL Variavel
subwf Variavel+1,f
btfss STATUS,C
decf Variavel+2,f
btfss STATUS,C
decf Variavel+3,f
endm
; Soma uma variavel de 32 bits e o valor do CAD (16 bits)
Add32_CAD macro Variavel
BANKSEL ADRESL
movf ADRESL,w
BANKSEL Variavel
addwf Variavel,f
BANKSEL ADRESH
movf ADRESH,w
btfsc STATUS,C
incf ADRESH,w
BANKSEL Variavel
addwf Variavel+1,f
btfsc STATUS,C
incf Variavel+2,f
btfsc STATUS,C
incf Variavel+3,f
endm
; Decrementa uma variável de 32 bits
Dec32 macro Variavel
BANKSEL Variavel
movlw .1
subwf Variavel,f
btfss STATUS,C
subwf Variavel+1,f
btfss STATUS,C
subwf Variavel+2,f
btfss STATUS,C
subwf Variavel+3,f
endm
EhZero macro Variavel
movf Variavel,w ; Verifica se Timer0 é ZERO
iorwf Variavel+1,w
iorwf Variavel+2,w
iorwf Variavel+3,w
endm
; Inicializa uma variável de 32 bits
Init32 macro Variavel,Valor
BANKSEL Variavel
movlw low Valor
movwf Variavel
movlw low (Valor >> .

movwf Variavel+1
movlw low (Valor >> .16)
movwf Variavel+2
movlw low (Valor >> .24);24==============
movwf Variavel+3
endm
;Compara uma variavel de 32 bits com LIMITE_VALOR
;retorna C=1 se Variavel >= LIMITE_VALOR
Compara32_LIMITE_VALOR macro Variavel
BANKSEL Variavel
movlw LIMITE_VALOR_byte0
subwf Variavel,w
movlw LIMITE_VALOR_byte1
btfss STATUS,C
addlw 1
subwf Variavel+1,w
movlw LIMITE_VALOR_byte2
btfss STATUS,C
addlw 1
subwf Variavel+2,w
movlw LIMITE_VALOR_byte3
btfss STATUS,C
addlw 1
subwf Variavel+3,w
endm
CODE H'4'
InterrupcaoTIMER0:
; Salva contexto
movwf W_TEMP
swapf STATUS,W
movwf STATUS_TEMP
BANKSEL INTCON ; Zera flag de interrupção
bcf INTCON,T0IF
; ****************************************
; ******* CRITICAL TIME SESSION **********
; ****************************************
movlw TIMER_CONSTANT ; Reinicializa o TIMER0
movwf TMR0
incf Contador,f ; Incrementa o contador
btfss GPIO,LED
goto LED_desligado
LED_ligado:
call CAD ; converte canal 0
bsf ADCON0,CHS0 ; CAD canal 1
Sub32_CAD Acum0 ; Acum0 -= CAD
call CAD ; converte canal 1
bcf ADCON0,CHS0 ; CAD canal 0
Sub32_CAD Acum1 ; Acum1 -= CAD
goto fim_teste_LED
LED_desligado:
call CAD ; converte canal 0
bsf ADCON0,CHS0 ; CAD canal 1
Add32_CAD Acum0 ; Acum0 += CAD0
call CAD ; converte canal 1
bcf ADCON0,CHS0 ; CAD canal 0
Add32_CAD Acum1 ; Acum0 += CAD0
fim_teste_LED:
movlw 0x3 ; Contador&0x3==0?
andwf Contador,w
gotoNZ fim_int
BANKSEL GPIO ; Contador&0x4?
btfss Contador,2
goto DesligaLED
LigaLED:
bsf GPIO,LED ; Liga LED
goto TestaLimites
DesligaLED:
bcf GPIO,LED ; Desliga LED
TestaLimites:
movlw LIMITE_AMOSTRAS ; Contador >= LIMITE_AMOSTRAS?
subwf Contador,w
gotoNC fim_int
call Verifica_Acum_LimiteValor0
call Verifica_Acum_LimiteValor1
call InicializaVariaveis
fim_int
; Restaura contexto
swapf STATUS_TEMP,W
movwf STATUS
swapf W_TEMP,F
swapf W_TEMP,W
retfie
;------------------------------------------------------
CAD: ; Realiza a conversao CAD
bsf ADCON0,GO ; Dispara conversao
aguardaConcluirCAD:
btfsc ADCON0,GO ; Aguarda concluir conversão
goto aguardaConcluirCAD
return
;------------------------------------------------------
Verifica_Acum_LimiteValor0:
Continua:
Compara32_LIMITE_VALOR Acum0
if TIPO==0
MESSG "Compilando versão FEIXE REFLETIDO"
gotoC Acum0EhMaiorOuIgual
else
MESSG "Compilando versão FEIXE DIRETO"
gotoNC Acum0EhMaiorOuIgual
endif
Acum0EhMenor:
EhZero Timer0
gotoNZ ContinuaMono0
bcf GPIO,Out0 ; Apaga o OUT0
goto VALV0_FIM
ContinuaMono0:
Dec32 Timer0
goto VALV0_FIM
Acum0EhMaiorOuIgual:
bsf GPIO,Out0 ; Acende o OUT0
Init32 Timer0,MON_0
VALV0_FIM:
return
;------------------------------------------------------
Verifica_Acum_LimiteValor1:
TestaLimites2:
Compara32_LIMITE_VALOR Acum1
if TIPO==0
gotoC Acum1EhMaiorOuIgual
else
gotoNC Acum1EhMaiorOuIgual
endif
Acum1EhMenor:
EhZero Timer1
gotoNZ ContinuaMono1
bcf GPIO,Out1 ; Apaga o OUT1
goto VALV1_FIM
ContinuaMono1:
Dec32 Timer1
goto VALV1_FIM
Acum1EhMaiorOuIgual:
bsf GPIO,Out1 ; Acende o OUT2
Init32 Timer1,MON_1
VALV1_FIM:
return
end
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
gotoNZ macro target
btfss STATUS,Z
goto target
endm
gotoZ macro target
btfsc STATUS,Z
goto target
endm
retNZ macro
btfss STATUS,Z
return
endm
retZ macro
btfsc STATUS,Z
return
endm
gotoNC macro target
btfss STATUS,C
goto target
endm
gotoC macro target
btfsc STATUS,C
goto target
endm
retNC macro
btfss STATUS,C
return
endm
retC macro
btfsc STATUS,C
return
endm
; Global constants
constant Clock = 4000000
constant IntFreq = 4800
constant LIMITE_AMOSTRAS = 64
constant TIMER_CONSTANT = .256+.8-(Clock/(.4*IntFreq))
constant LED = 2
constant Out0 = 4
constant Out1 = 5
constant LIMITE_VALOR_byte0 = low LIMITE_VALOR
constant LIMITE_VALOR_byte1 = low (LIMITE_VALOR >> .

constant LIMITE_VALOR_byte2 = low (LIMITE_VALOR >> .16)
constant LIMITE_VALOR_byte3 = .1