Continuous Interrupts when using DT_INTS and an INCLUDE file
Am using DT_INTS with 18F4550 to detect an alarm interrupt on INT2 from DS1330 real-time-clock. So that I can reuse a tested routine for operating the clock and a SRF02 peripheral via I2C bus, I adapted it into an INCLUDE file as a callable routine from the Main program. The INCLUDE processes the clock/SRF02 operations and provides results via global variables to the Main program. The program compiles and assembles OK without any errors in either the Main or INCLUDE file. However, when the program runs, I get continous interrupts that continuously trigger the Alarm handler in the INCLUDE file. I had seen this problem in previous versions and solved it (without understanding why) by placing a PAUSE 100 at beginning of the Main program. This previous fix didn't work in this case.
I am posting the applicable code from my Main program below. Can anyone tell me why it would create continuous INT2 interrupts??
Code:
''----------------[ Define Include Files & special DEFINES ]
INCLUDE "DS1337_SRF02.inc" ' Include use of DS1337_SRF02 Alarm handler
INCLUDE "Modedefs.Bas"
INCLUDE "DT_INTS-18.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP-18.bas" ' Include if using PBP high priority interrupts
INCLUDE "ALLDIGITAL.pbp" DEFINE OSC 16
DEFINE I2C_SLOW 1 ' Set i2c to the standard speed
DEFINE I2C_HOLD 1 ' Enable recieving i2c device to pause communication
'--------------[ Declare Variables, Aliases & Constants ]
' Global variables & constants used in both Main program and Include files
'rng0 VAR w0.Byte0 ' LSB of range measurement when right justified
'rng1 VAR w0.byte1 ' MSB of range measurement when right justified
'SCL VAR PORTB.1 ' I2C clock pin
'SDA VAR PORTB.0 ' I2C data pin
'w0 var word ' W0 is the word value to store the range data
'rtcdevice CON $D0 ' Device address for DS1337 Real-time-clock (RTC)
'srfdevice CON $E0 ' Device address for SRF02 ultrasonic range finder
'Alarm1 VAR PORTB.2 ' Alarm1 input from DS1337 INTA (pin-3)
'Alarm2 VAR PORTB.3 ' Alarm2 input from DS1337 INTB (pin-7)
'RTC_INT_FLG VAR INTCON3.1 'Alias for RB2 INTA interrupt flag from RTC
' Clock Variables
'sec VAR BYTE ' seconds
'MINs VAR BYTE ' minutes
'hr VAR BYTE ' hours
'day VAR BYTE ' day
'date VAR BYTE ' date
'mon VAR BYTE ' month
'yr VAR BYTE ' year
' ALARM1 VARIABLES
'A1sec VAR BYTE ' seconds
'A1MINs VAR BYTE ' minutes
'A1hr VAR BYTE ' hours
'A1day VAR BYTE ' day
' ALARM2 VARIABLES
'A2MINs VAR BYTE ' minutes
'A2hr VAR BYTE ' hours
'A2day VAR BYTE ' day
GoSub SetTimeAndDate ' Setup current time & alarm settings
'----------------------[ SETUP FOR INTERRUPTS ]
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
;INT_Handler USB_Handler
INT_Handler INT2_INT, _AlarmHdlr, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
@ INT_ENABLE INT2_INT ; enable external (INT) interrupts
' Per DT, DT_INTS already takes care of setting INTCON and RCON registers
' but this doesn't work unles INTCON2 set per below:
'INTCON.7 = 1 ' Set Global Interrupt Enable bit
INTCON2 = %00000000 ' Set INT2 for falling edge (Bit4-low)
' on RTC's interrupt.
'INTCON3 = %10010000 ' Set INT2 high priority (Bit7-high), enable INT2
' (Bit4-high)
' Initialize Hardware
'Set registers
'OSCCON.7 = 0 ' Clear IDLEN bit to allow SLEEP mode
' According to data sheet, must clear CONFIG2H.0 (WDTEN bit)
' in order to use WDTCON. Not clear from Data sheet how to reach
' WDTEN bit with with config fuses??
'WDTCON.0 = 1 ' Set SWDTEN bit to turn on WDT
TRISA = 0 ' PORTA all outputs for LCD use
TRISB =%00001100 ' RB2 & RB3 set as RTC Alarm1 & Alarm2 inputs
TRISC = 0
TRISD = 0
TRISE = 0
'--------------------[ Begin Main Program Loop ]
Main:
PAUSE 100 ' ?? For some reason this 100 millisec delay has been
'required in previous versions
' to keep RTC interrupts from happening every 11 secs ??
Low PORTC.0 ' Turn off Test LED while in Main loop
GoTo Main ' Endless Loop waiting for interrupt
End ' Safety measure to insure program stops if reaches here
'-------------------[ Begin Interrupt Handler }-----------------------
AlarmHdlr:
Goto Alarm ' Call Alarm handler subroutine in INCLUDE file
@ INT_RETURN
Here is code for the called Alarm handler
Quote:
Originally Posted by
Bruce
you'll need to post all your code....;o}
With your interrupt handler jumping to AlarmHdlr, what happens in your Alarm routine
to send it back to the proper place to return from the interrupt, to land on your
@ INT_RETURN?
@ INT_RETURN clears the interrupt flag bit (& handles GIE), which keeps it from
returning to your int handler.
Your GOTO Alarm is probably leaving the interrupt flag bits set, and it simply returns assuming
the interrupt is still pending.
Notice that I am using two different INCLUDE files: one to setup the DS1337 and the other as an Alarm handler of an INT2 interrupt. I am posting below the code for the INCLUDE file that is involved with the servicing of the INT2 interrupt. You can see that I have a RETURN statement at the end of the routine that is called to service the interrupte, so I presumed the @INT_RETURN that is the next statement after the RETURN would take care of flags. Do I need to separately clear the GIE flag at the end of the called routine before the RETURN to keep the continuous interrupts from happening?
Code:
'--------------[ Declare Variables, Aliases & Constants ]----------------
' Global variables, constants & aliases used in both Main program and
' INCLUDE files that are declared in Main are commented out here.
'Alarm1 VAR PORTB.2 ' Alarm1 input from DS1337 INTA (pin-3)
'Alarm2 VAR PORTB.3 ' Alarm2 input from DS1337 INTB (pin-7)
IN2_ext_pwr VAR PORTC.6 ' Alias to control power to Ultrasonic sensor
rng0 VAR w0.Byte0 ' LSB of range measurement when right justified
rng1 VAR w0.byte1 ' MSB of range measurement when right justified
IN2_SCL VAR PORTB.1 ' I2C clock pin
IN2_SDA VAR PORTB.0 ' I2C data pin
w0 var word ' W0 is the word value to store the range data
'rtcdevice CON $D0 ' Device address for DS1337 Real-time-clock (RTC)
srfdevice CON $E0 ' Device address for SRF02 ultrasonic range finder
'Other variables in DS1337 setup below that DON'T have INC_ prefix
' Local variables & constants only used in this Include file
' Other variables in DS1337 setup below that have INC_ prefix
' Initialize Hardware
' ===================
'Set registers
'OSCCON.7 = 0 ' Clear IDLEN bit to allow SLEEP mode
TRISA = 0 ' PORTA reserved as outputs for LCD use
TRISB =%00001100 ' RB2 & RB3 set as RTC Alarm1 & Alarm2 inputs
TRISC = 0 ' RC0 used for test LED
GOTO Alarm ' Jump over Subroutines, so they don't try to execute
'-------------------[ Begin Alarm Interrupt Handler ]--------------------
Alarm:
High PORTC.0 ' Turn on Test LED to indicate Alarm ISR entered
HIGH IN2_ext_pwr ' Turn on power to the SRF02 during interrupt service
' in order to use the I2C bus without distortion.
PAUSE 3000 ' Delay to let I2C bus stabilize after SRF02 turn on
'DEFINE WRITE_USED 1 'Required if only writing WORD variables in v2.6
' Process the RTC alarm
' Read the current time from the DS1337
I2CREAD IN2_SDA,IN2_SCL,$D0,SecReg,[sec,MINs,hr,day,date,mon,yr]
PAUSE 10
'Write time of latest alarm to EEPROM
WRITE 21,hr
PAUSE 20
WRITE 22,MINs
PAUSE 20
WRITE 23,sec
Pause 20
' Make SRF02 Range Measurement
I2CWRITE IN2_SDA,IN2_SCL,$E0,0,[80]' Request start of ranging in inches
pause 100 ' Wait for ranging to finish
I2CREAD IN2_SDA,IN2_SCL,$E0,2,[rng1,rng0] ' Get ranging results
pause 10
WRITE 253,rng1 ' Write range to EEPROM
PAUSE 20
Write 254,rng0
PAUSE 20
' Read the ALARM settings from the DS1337
'I2CREAD IN2_SDA, IN2_SCL, $D0, IN2_Alm1sec,[A1sec,A1MINs,A1hr,A1day]
'Pause 10
'I2CRead IN2_SDA, IN2_SCL, $D0, IN2_Alm2min,[A2MINs,A2hr,A2day]
'PAUSE 10
' Clear the Alarm flags to be ready for next day's interrupt
' Clear STATUS register
I2CWrite IN2_SDA,IN2_SCL,$D0,IN2_StatusReg,[$00]
Pause 1000
WRITE 255, MINs
PAUSE 20
LOW IN2_ext_pwr ' Turn off power to the SRF02 at end of interrupt
' This statement will distort the I2C bus and ext_pwr
' must be HIGH before any attempts are made to use the
' I2C bus.
PAUSE 1000 ' Delay to permit I2C bus to stabilize after SRF02 off
RETURN
' Resume Main Program
'----------------{ End of Alarm Interrupt Handler }------------------
Here is applicable INCLUDE file that is ISR for INT2
Here is code for the related INCLUDE file that services the INT2 interrupt:
Code:
'----------------[ Define special DEFINES ]--------------
' These I2C settings must be defined in the Main Program
'DEFINE I2C_SLOW 1 ' Set i2c to the standard speed
'DEFINE I2C_HOLD 1 ' Enable recieving i2c device to pause communication
'--------------[ Declare Variables, Aliases & Constants ]----------------
' Global variables, constants & aliases used in both Main program and
' INCLUDE files that are declared in Main files are commented out here
'Alarm1 VAR PORTB.2 ' Alarm1 input from DS1337 INTA (pin-3)
'Alarm2 VAR PORTB.3 ' Alarm2 input from DS1337 INTB (pin-7)
IN2_ext_pwr VAR PORTC.6 ' Alias to control power to Ultrasonic sensor
rng0 VAR w0.Byte0 ' LSB of range measurement when right justified
rng1 VAR w0.byte1 ' MSB of range measurement when right justified
IN2_SCL VAR PORTB.1 ' I2C clock pin
IN2_SDA VAR PORTB.0 ' I2C data pin
w0 var word ' W0 is the word value to store the range data
'rtcdevice CON $D0 ' Device address for DS1337 Real-time-clock (RTC)
srfdevice CON $E0 ' Device address for SRF02 ultrasonic range finder
'Other variables in DS1337 setup below that DON'T have IN2_ prefix
' Local variables & constants only used in this Include file
' Other variables in DS1337 setup below that have IN2_ prefix
'---------------[ Initialize this INCLUDE module ]-----------------------
'---------------SETUP FOR USING DS1337 Real Time Clock-------------------
' Setup Hardware for uart...already done by DS1337_Setup
'DEFINE HSER_BAUD 115200
'DEFINE HSER_RCSTA 90h
'DEFINE HSER_TXSTA 24h
'DEFINE HSER_CLROERR 1
' Alias of Clock register addresses
IN2_ContReg CON $0E ' CONTROL register address
IN2_StatusReg CON $0F ' STATUS register address
'RTC_INT_FLG VAR INTCON3.1 'Alias for RB2 INTA interrupt flag from RTC
' Initialize Hardware
' ===================
'Set registers
'OSCCON.7 = 0 ' Clear IDLEN bit to allow SLEEP mode
TRISA = 0 ' PORTA reserved as outputs for LCD use
TRISB =%00001100 ' RB2 & RB3 set as RTC Alarm1 & Alarm2 inputs
TRISC = 0 ' RC0 used for test LED
GOTO Alarm ' Jump over Subroutines, so they don't try to execute
'-------------------[ Begin Alarm Interrupt Handler ]--------------------
Alarm:
High PORTC.0 ' Turn on Test LED to indicate Alarm interrupt entered
HIGH IN2_ext_pwr ' Turn on power to the SRF02 during interrupt service
' in order to use the I2C bus without distortion.
PAUSE 3000 ' Delay to let I2C bus stabilize after SRF02 turn on
'DEFINE WRITE_USED 1 'Required if only writing WORD variables in v2.6
' Process the RTC alarm
' Read the current time from the DS1337
I2CREAD IN2_SDA,IN2_SCL,$D0,SecReg,[sec,MINs,hr,day,date,mon,yr]
PAUSE 10
'Write time of latest alarm to EEPROM
WRITE 21,hr
PAUSE 20
WRITE 22,MINs
PAUSE 20
WRITE 23,sec
Pause 20
' Make SRF02 Range Measurement
I2CWRITE IN2_SDA,IN2_SCL,$E0,0,[80]' Request start of ranging in inches
pause 100 ' Wait for ranging to finish
I2CREAD IN2_SDA,IN2_SCL,$E0,2,[rng1,rng0] ' Get ranging results
pause 10
WRITE 253,rng1 ' Write range to EEPROM
PAUSE 20
Write 254,rng0
PAUSE 20
' Read the ALARM settings from the DS1337
I2CREAD IN2_SDA, IN2_SCL, $D0, Alm1sec,[A1sec,A1MINs,A1hr,A1day]
Pause 10
I2CRead IN2_SDA, IN2_SCL, $D0, Alm2min,[A2MINs,A2hr,A2day]
PAUSE 10
' Clear the Alarm flags to be ready for next day's interrupt
' Clear STATUS register
I2CWrite IN2_SDA,IN2_SCL,$D0,IN2_StatusReg,[$00]
Pause 1000
WRITE 255, MINs
PAUSE 20
LOW IN2_ext_pwr ' Turn off power to the SRF02 at end of interrupt
' This statement will distort the I2C bus and ext_pwr
' must be HIGH before any attempts are made to use the
' I2C bus.
PAUSE 1000 ' Delay to permit I2C bus to stabilize after SRF02 off
RETURN
' Resume Main Program
'------------------{ End of Alarm Interrupt Handler }--------------------