Hi, new today - and of course a question to ask....
Having forgotten most of what I knew when my hobby was programming in the early 1970s I have now, in retirement, decided to play with PICS.
I've got a PICkit2, so am using the 16f690 to play with.
I have got LEDs flashing etc. so am now moving on to a gadget I want to make. It will time frequency and duty cycle, use a look-up table to work out a new time and duration and send it out again.
Seems OK ... I've read the Tips'nTricks and have started on the program - just the capture and interrupt part to begin with.
Now all I have to do is ask someone who knows rather than me keep working by trial and error - as it seems to be all error right now.
The program listed below should just change a variable "Semaphore" and show it on an LED - so I know the interrupt routine and Capture is working. I've added some flashing LEDS so I know the chip is actually doing something.
Would someone have a look and tell me what I've done wrong?
Thanks in advance.
;* Trying to learn how to use capture mode*
; *******************************************************************
; * 16/5/89 version 1 *
; *******************************************************************
#include <p16F690.inc>
__config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOR_OFF & _IESO_OFF & _FCMEN_OFF)
;***** VARIABLE DEFINITIONS
w_temp EQU 0x7D ; variable used for context saving
status_temp EQU 0x7E ; variable used for context saving
pclath_temp EQU 0x7F ; variable used for context saving
cblock 0x20
Semaphore
Delay1
Delay2
endc
;*****************************************************
;begin here
ORG 0x000
goto main
nop ;fill up some memory until interrupt vector
nop
nop
; interrupt vector location
;*******************************************************
; interrupt routine - save current status
movwf w_temp ; save off current W register contents
movf STATUS,w ; move status register into W register
movwf status_temp ; save off contents of STATUS register
movf PCLATH,w ; move pclath register into W register
movwf pclath_temp ; save off contents of PCLATH register
;*******************************************************
; turn off interrupts
bcf PIR1,CCP1IE ;turn off ccp interrupt
bcf INTCON,GIE ;turn off global interrupts
clrf PIR1 ;clear interrupt flag
; ******************************************************
bsf Semaphore,0 ; set as interrupt routine has been called
;*******************************************************
; reinstate status
movf pclath_temp,w ; retrieve copy of PCLATH register
movwf PCLATH ; restore pre-isr PCLATH register contents
movf status_temp,w ; retrieve copy of STATUS register
movwf STATUS ; restore pre-isr STATUS register contents
swapf w_temp,f
swapf w_temp,w ; restore pre-isr W register contents
;********************************************************
; reset interrupts
bsf PIE1,CCP1IE ; turn on ccp interrupt
bcf INTCON,GIE ;turn global interrupts on
retfie ; return from interrupt
;*******************************************************
;main program here
main:
bsf STATUS,RP0 ; select Register Page 1
movlw b'00100000' ; make IO PortC,5 input the rest output
movwf TRISC
bcf STATUS,RP0 ; back to Register Page 0
movlw b'00110011' ;set timer controls - as below
;set timer 1 internal bit 1 set
;set prescaler to /8 bit 5,4 set
movwf T1CON ;start timer 1 bit 0 set
movlw b'00000101' ;set ccp on rising edge
movwf CCP1CON
clrf PIR1 ;clear ccp interrupt flag
bsf PIE1,CCP1IE ; turn on ccp interrupt
bsf INTCON,GIE ;turn on global interrupts
clrf Semaphore
Mainloop:
;do a flash on LEDs to show something is working, use 1 and 3 so 0 is free to show the interrupt has been called
OffDelayLoop:
decfsz Delay1,f
goto OffDelayLoop
decfsz Delay2,f
goto OffDelayLoop
movlw b'00000010'
movwf PORTC
OnDelayLoop:
decfsz Delay1,f
goto OnDelayLoop
decfsz Delay2,f
goto OnDelayLoop
movlw b'00001000'
addwf Semaphore,0 ;this should flash portC,0 if the interrupt routine has been called
movwf PORTC
goto Mainloop
end
Having forgotten most of what I knew when my hobby was programming in the early 1970s I have now, in retirement, decided to play with PICS.
I've got a PICkit2, so am using the 16f690 to play with.
I have got LEDs flashing etc. so am now moving on to a gadget I want to make. It will time frequency and duty cycle, use a look-up table to work out a new time and duration and send it out again.
Seems OK ... I've read the Tips'nTricks and have started on the program - just the capture and interrupt part to begin with.
Now all I have to do is ask someone who knows rather than me keep working by trial and error - as it seems to be all error right now.
The program listed below should just change a variable "Semaphore" and show it on an LED - so I know the interrupt routine and Capture is working. I've added some flashing LEDS so I know the chip is actually doing something.
Would someone have a look and tell me what I've done wrong?
Thanks in advance.
;* Trying to learn how to use capture mode*
; *******************************************************************
; * 16/5/89 version 1 *
; *******************************************************************
#include <p16F690.inc>
__config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOR_OFF & _IESO_OFF & _FCMEN_OFF)
;***** VARIABLE DEFINITIONS
w_temp EQU 0x7D ; variable used for context saving
status_temp EQU 0x7E ; variable used for context saving
pclath_temp EQU 0x7F ; variable used for context saving
cblock 0x20
Semaphore
Delay1
Delay2
endc
;*****************************************************
;begin here
ORG 0x000
goto main
nop ;fill up some memory until interrupt vector
nop
nop
; interrupt vector location
;*******************************************************
; interrupt routine - save current status
movwf w_temp ; save off current W register contents
movf STATUS,w ; move status register into W register
movwf status_temp ; save off contents of STATUS register
movf PCLATH,w ; move pclath register into W register
movwf pclath_temp ; save off contents of PCLATH register
;*******************************************************
; turn off interrupts
bcf PIR1,CCP1IE ;turn off ccp interrupt
bcf INTCON,GIE ;turn off global interrupts
clrf PIR1 ;clear interrupt flag
; ******************************************************
bsf Semaphore,0 ; set as interrupt routine has been called
;*******************************************************
; reinstate status
movf pclath_temp,w ; retrieve copy of PCLATH register
movwf PCLATH ; restore pre-isr PCLATH register contents
movf status_temp,w ; retrieve copy of STATUS register
movwf STATUS ; restore pre-isr STATUS register contents
swapf w_temp,f
swapf w_temp,w ; restore pre-isr W register contents
;********************************************************
; reset interrupts
bsf PIE1,CCP1IE ; turn on ccp interrupt
bcf INTCON,GIE ;turn global interrupts on
retfie ; return from interrupt
;*******************************************************
;main program here
main:
bsf STATUS,RP0 ; select Register Page 1
movlw b'00100000' ; make IO PortC,5 input the rest output
movwf TRISC
bcf STATUS,RP0 ; back to Register Page 0
movlw b'00110011' ;set timer controls - as below
;set timer 1 internal bit 1 set
;set prescaler to /8 bit 5,4 set
movwf T1CON ;start timer 1 bit 0 set
movlw b'00000101' ;set ccp on rising edge
movwf CCP1CON
clrf PIR1 ;clear ccp interrupt flag
bsf PIE1,CCP1IE ; turn on ccp interrupt
bsf INTCON,GIE ;turn on global interrupts
clrf Semaphore
Mainloop:
;do a flash on LEDs to show something is working, use 1 and 3 so 0 is free to show the interrupt has been called
OffDelayLoop:
decfsz Delay1,f
goto OffDelayLoop
decfsz Delay2,f
goto OffDelayLoop
movlw b'00000010'
movwf PORTC
OnDelayLoop:
decfsz Delay1,f
goto OnDelayLoop
decfsz Delay2,f
goto OnDelayLoop
movlw b'00001000'
addwf Semaphore,0 ;this should flash portC,0 if the interrupt routine has been called
movwf PORTC
goto Mainloop
end