It's unclear , from the way
the code was posted , if you have anything happening after
the " RLF "
instructions . . . .are you dropping down to finish the " Servicing
External Int. " ?
Also , I wonder how you are
using TMR0 , I see that you have a prescale of 16 selected ,
but , are you considering
the " watchdog timer " when you put the device to " Sleep "
?
I suggest that you add a
" CLRWDT " ( clear watchdog timer ) immediately before you
put
the device to sleep ( in
the main section ) also , if you have the " Global Interrupt "
enabled
before you put it to sleep
( which it looks like you do ) , then when it wakes , the device
will
complete sleep , do the
next instruction . . . . Then it will " GO TO THE INTERRUPT VECTOR
".
If you want the system to
come out of sleep and then proceed with your instruction flow ,
then
" Disable " the
Global Interrupt " before putting the device to sleep . . . . when it wakes
it will
not go directly to the
interrupt on the second instruction.
Good Luck . . . . hope it
helps . . . .
Regards . . .
Steve Kelley
Protobyte Inc.
I'm having problems with the
external interrupt on a 12C672. I've used
interrupts extensively
and successfully on the 16F84 and 16C71. I've
generated a stimulus
file that simulates successfully. I've double and
triple checked
the schematic and wiring. I've made sure that /MCLR is
disabled in
the configuration bits and in the MPLAB setup (since if
enabled, it also
uses one of my inputs). I have verified that the part is
working by
turning on a LED if it gets past the initialization routine. I
put
the same code to turn on the LED as the first thing executed in
the
interrupt (after context saving), and it never turns on. I have
verified
that the signal is coming in to the part with both an
oscilloscope (for
level) and a logic analyzer (for pattern) .
GP2
(pin 5) is used as the interrupt source, which serves as a clock for
an
incoming serial data stream on GP3 (pin 4). The main loop is a
timer (not
necessarily precise, I just need a long duration timer).
The object of the
code is to turn on an output when a certain synchronous
serial message is
received, or after a certain period of time from
startup. I am using an
external 32KHz crystal.
It seems that
the external interrupt is never occuring when I am using the
real part,
but it simulates just fine. Is there something about the
12C672
that I'm missing?
Here's is the relevant code (please
excuse the tabs- they don't seem to
paste
properly):
;**********************************************************************
;
compiler
directives
;**********************************************************************
LIST
p=PIC12c672
#include
"P12c672.INC"
__CONFIG _CP_OFF & _LP_OSC & _PWRTE_ON & _MCLRE_OFF &
_WDT_OFF
;**********************************************************************
;
equates
;**********************************************************************
ramstart
equ 0x20
; GPIO
port
scuttle_out equ
0x00
scuttlen_out equ
0x01
data_clock equ
0x02
data_in
equ
0x03
;**********************************************************************
;
constants
;**********************************************************************
;**********************************************************************
;
variables
;**********************************************************************
count0
equ ramstart + 0x00
count1
equ ramstart + 0x01
count2
equ ramstart +
0x02
quantum_delay_count
equ ramstart +
0x04
keyword0
equ ramstart +
0x05
keyword1
equ ramstart +
0x06
keyword2
equ ramstart +
0x07
keyword3
equ ramstart +
0x08
temp
equ ramstart +
0x09
_w
equ ramstart +
0x0a
_status
equ ramstart +
0x0b
;**********************************************************************
;
code
;**********************************************************************
start
org 0x0
call
initialize
goto
main
;**********************************************************************
;
subroutines
;**********************************************************************
;**********************************************************************
;
interrupt
;
;**********************************************************************
interrupt
org
0x04
; context save
movwf
_w
;save the contents of W
movf STATUS, w ;get
and save the contents of
STATUS
bcf STATUS, RP0 ; Optional -
put PIC Regs into a known page
movwf _status
;save STATUS refister
btfss INTCON, INTF ; was it an external
interrupt?
goto
end_interrupt
external_interrupt
clrc
; clear the carry
btfsc GPIO,data_in ; is the data a
0?
setc
; no, so set the carry
rlf keyword3,f ;
rotate it into the keyword
rlf
keyword2,f
rlf
keyword1,f
rlf keyword0,f
; do
stuff
end_interrupt
movfw INTCON
andlw b'11111000' ; clear all interupt
flags
movwf
INTCON ; load it into
the register
movf _status,W ; get
and store the contents of
STATUS
movwf
STATUS ;
register from before the
interrupt
swapf
_w,F ;
flip and load the W register
without
swapf
_w,W
; affecting the STATUS
register
retfie
; return, re-enabling the
interrupts
;**********************************************************************
;
initialize
;**********************************************************************
initialize
movlw b'00000010' ; make sure output is
OFF before we
movwf
GPIO
; set it up as output
movlw
b'10010000'
; |---------------enable
interrupts
; |--------------disable peripherial
interrupts
; |-------------disable timer
interrupt
; |------------enable external interrupt
(GP2/INT)
; |-----------disable GPIO int on
change
; |||--------clear interrput
flags
movwf
INTCON ; load the
INTCON register
bsf STATUS,RP0 ; move
to bank1
movlw
b'11000011' ; for the OPTION
register
; |---------------disable weak
pullups
; |--------------int on rising edge of
GP2/INT
; |-------------TMR0 from internal inst.
clock
; |------------inc tmr0 on l->h from
ext.
; |-----------prescaler assigned to
tmr0
; |||--------prescaler
1:16
movwf
OPTION_REG
movlw
b'00111100' ; for the TRIS
register
; |||------- set GP0, GP1 to
outputs
; the rest as inputs
movwf TRISIO
bcf STATUS,RP0 ; back
to page 0
clrf count0
clrf count1
clrf count2
clrf
keyword0
clrf
keyword1
clrf
keyword2
clrf
keyword3
return
;**********************************************************************
;
quantum
delay
;**********************************************************************
quantum_delay
movlw .25
movwf
quantum_delay_count
quantum_delay_loop
decfsz
quantum_delay_count,f
goto
quantum_delay_loop
nop
return
;*******
scuttle
; do stuff
return
;**********************************************************************
;
main
;**********************************************************************
main
clrf temp
bcf temp,
scuttle_out
bsf temp,
scuttlen_out
inclsb
movfw temp
movwf GPIO
call
quantum_delay
incfsz
count0,f
goto inclsb
incfsz count1,f
goto inclsb
incfsz count2,f
goto inclsb
call scuttle
sleep
goto
start
end