;*******************************************************************
; 16F628 Timer Program
;*******************************************************************
;
list p=16f628A ; list directive to define processor
#include <p16F628A.inc> ; processor specific variable definitions
errorlevel -302 ; suppress message 302 from list file
__CONFIG _CP_OFF & _DATA_CP_OFF & _LVP_OFF & _BOREN_OFF & _MCLRE_ON & _WDT_OFF & _PWRTE_ON & _LP_OSC
cblock 20h
Phase
endc
cblock 70h
int_work
int_status
int_pclath
int_fsr
endc
org 0h
goto start
nop
nop
nop
interupt movwf int_work
swapf STATUS,W
movwf int_status
bcf STATUS,RP0
bcf STATUS,RP1
movfw PCLATH
movwf int_pclath
clrf PCLATH
movfw FSR
movwf int_fsr
btfss INTCON,INTF ;has RB0 gone high
goto NotRB0 ; no
; yes, clear the timer and phase
bcf INTCON,INTF
clrf TMR1L
clrf TMR1H
clrf Phase
NotRB0 btfss PIR1,CCP1IF
goto NotCCP1
;time up so toggle port b outputs.
bcf PIR1,CCP1IF; reset special event trigger interupt
movlw b'00001100'; make rb1 low and rb2 high
btfss Phase,0
movlw b'00001010'; make rb1 high and rb2 low
movwf PORTB
incf Phase,F ; will toggle bit 0 of phase
NotCCP1
movfw int_pclath
movwf PCLATH
movfw int_fsr
movwf FSR
swapf int_status,W
movwf STATUS
swapf int_work,F; swap to file
swapf int_work,W; swap to work
retfie
start bsf STATUS,RP0
bcf STATUS,RP1
bcf STATUS,IRP
movlw b'01000000'; interrupt on rising edge
movwf OPTION_REG
movlw b'11111111'
movwf TRISA
movlw b'11110001'; make rb1,2,3 output
movwf TRISB
clrf PORTA
clrf PORTB
movlw b'00000111'; setup comparator
movwf CMCON
movlw B'00000001'
movwf T1CON; enable timer 1
movlw low(0x4000); 0x4000 = half of 32768 i.e. 0.5 seconds
movwf CCPR1L
movlw high(0x4000)
movwf CCPR1H
movlw B'00001011'; enable special event trigger on CCP1
movwf CCP1CON;
bsf STATUS,RP0
bsf PIE1,CCP1IE; enable CCP1 interupt
bcf STATUS,RP0
movlw (1<<GIE|1<<PEIE|0<<T0IE|1<<INTE|0<<RBIE|0<<T0IF|0<<INTF|0<<RBIF)
movwf INTCON; enable Peripheral and RB0 interrupts
Loop goto Loop
end