PDA

View Full Version : INT2 anomaly in DT_INTS-18??



jellis00
- 17th February 2010, 00:10
Am using PBP 2.6 to use INT2 as an external interrupt from a DS1337 real-time-clock. Code attached below works perferctly, but for some strange reason I have to insert a PAUSE 100 at the start of the Main loop or the INT2 doesn't work properly. As long as the PAUSE 100 is there, works fine. Can anyone tell me why??


' [ Device Declaration ]
ASM ; 18F2550/4550, 8mhz crystal
__CONFIG _CONFIG1L, _PLLDIV_2_1L & _CPUDIV_OSC4_PLL6_1L & _USBDIV_2_1L
__CONFIG _CONFIG1H, _FOSC_HSPLL_HS_1H
__CONFIG _CONFIG2L, _PWRT_ON_2L & _BOR_OFF_2L & _VREGEN_ON_2L
__CONFIG _CONFIG2H, _WDT_ON_2H & _WDTPS_512_2H
__CONFIG _CONFIG3H, _PBADEN_OFF_3H ; PortB resets as digital
__CONFIG _CONFIG4L, _LVP_OFF_4L & _XINST_OFF_4L
ENDASM

Include "Modedefs.Bas"
INCLUDE "DT_INTS-18.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP-18.bas"
INCLUDE "ALLDIGITAL.pbp" ' Sets all registers for digital ops.

DEFINE OSC 16
DEFINE I2C_SLOW 1
DEFINE I2C_HOLD 1

' Initialize Hardware
TRISA = 0 ' all outputs for LCD use
TRISB =%00001100 ' RB2 & RB3 set as RTC Alarm1/2 inputs
TRISC = 0
TRISD = 0
TRISE = 0

'[ Declare Variables, Aliases & Constants ]
rng0 VAR Byte ' Range LSB when right justified
rng1 VAR Byte ' Range MSB when right justified
ext_pwr VAR PORTC.6 ' Controls power to SRF02
SCL VAR PORTB.1
SDA VAR PORTB.0

' Constants
rtcdevice CON $D0 ' Address for DS1337
srfdevice CON $E0 ' Address for SRF02

'SETUP FOR USING DS1337 Real Time Clock
' Setup Hardware for uart
DEFINE HSER_BAUD 115200
DEFINE HSER_RCSTA 90h
DEFINE HSER_TXSTA 24h
DEFINE HSER_CLROERR 1

' Aliased Variables for CLock
Alarm1 VAR PORTB.2 ' Alarm1 input from DS1337 INTA (pin-3)
Alarm2 VAR PORTB.3 ' Alarm2 input from DS1337
contrl CON %00000101 ' Starts oscillator, enables INTA interrupt
' from A1F, INTA/SQW off.

' RTC Address definitions
SecReg CON $00 ' seconds (00 - 59)
' must set MSB of SecReg to 0 to enable RTC
MinReg CON $01 ' minutes (00 - 59)
HrReg CON $02 ' hours (01 - 12) or (00 - 23)
DayReg CON $03 ' day (1 - 7)
DateReg CON $04 ' date (01 - 28/29, 30, 31)
MonReg CON $05 ' month (01 - 12)
YearReg CON $06 ' year (00 - 99)

' Alarm 1 Address definitions
Alm1sec CON $07 ' Alarm 1 seconds (00-59)
Alm1min CON $08 ' Alarm 1 minutes (00-59)
Alm1hr CON $09 ' Alarm 1 hours (01-12) or (00-23)
Alm1Day CON $0A ' Alarm 1 day (1-7)

' Alarm 2 Address definitions
Alm2min CON $0B ' Alarm 2 minutes (00-59)
Alm2hr CON $0C ' Alarm 2 hours (01-12) or (00-23)
Alm2Day CON $0D ' Alarm 2 day (1-7)

' Alias of Clock register addresses
ContReg CON $0E ' CONTROL register
StatusReg CON $0F ' STATUS register

' 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, _Alarm, PBP, yes
endm
INT_CREATE
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:
INTCON2.4 = 0 ' Set INT2 for falling edge (Bit4-low)interrupt
INTCON2.7 = 1 ' Disable all PortB Pull-ups

RTC_INT_FLG VAR INTCON3.1 'Alias for RB2 INTA interrupt flag from RTC

'[ Begin Main Program Loop ]
Main:
PAUSE 100 ' ?? For some reason this 100 millisec delay is required
' to keep INT2 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

'[ Begin Interrupt Handler ]
Alarm:
High PORTC.0 ' Turn on Test LED to indicate Alarm interrupt entered
HIGH 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
I2CREAD SDA,SCL,RTCdevice,SecReg,[sec,MINs,hr,day,date,mon,yr]
PAUSE 10
'Write time to EEPROM
WRITE 21,hr
PAUSE 20
WRITE 22,MINs
PAUSE 20
WRITE 23,sec
Pause 20
' Read the ALARM settings from the DS1337
I2CREAD SDA,SCL,RTCdevice,Alm1sec,[A1sec,A1MINs,A1hr,A1day]
Pause 10
I2CRead SDA,SCL,RTCdevice,Alm2min,[A2MINs,A2hr,A2day]
PAUSE 10

' Make SRF02 Range Measurement
I2CWRITE SDA,SCL,$E0,0,[80]' Request start of ranging in inches
pause 100 ' Wait for ranging to finish
I2CREAD SDA,SCL,$E0,2,[rng1,rng0] ' Get ranging results
WRITE 253,rng1 ' Write range to EEPROM for testing
Write 254,rng0

' Clear the Alarm flags to be ready for next day intterupt
' Clear STATUS register
I2CWrite SDA,SCL,RTCdevice, StatusReg,[$00]
Pause 1000
WRITE 255, MINs
PAUSE 20
LOW 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
' Resume Main Program
@ INT_RETURN
End ' Safety measure to insure program stops if reaches here
'{ End of Interrupt Handler ]

' [ START LIST OF SUBROUTINES ]

SetTimeAndDate: ' Subroutine to set current time, date and alarms
HIGH ext_pwr ' Turn on power to the SRF02 during this routine
PAUSE 3000 ' Delay to let I2C bus stabilize after SRF02 turn on
' Initialize clock variables to 0
yr=0:date =0:mon =0:day=0:hr=0:MINs=0:sec=0
A1sec=0:A1MINs=0:A1hr=0:A1Day=0
A2MINs=0:A2hr=0:A2day=0
' The BCD constants below set the RTC to: 11:00:00 on 12-20-2009
hr=$11
MINs=$00
sec=$00
day=$07
mon=$12
date=$20
yr=$09
' Per MAXIM TechSupport, proper sequencing requires setting INTCN = 1,
' & A2IE=A1IE=0 before setting alarms.
I2CWrite SDA, SCL, RTCdevice, ContReg,[%00000100]
Pause 20
'Define ALARM1 FOR 11:01:00 & to alarm when secs match (1/min).
' This requires A1M1=0 and A1M2=A1M3=A1M4=1
' (A1xxx + $80 or A1xxx + 128d sets bit 7 as A1Mx = 1)
A1hr = %10010001 '$11 + $80 = %10010001, for A1M3 = 1
'Bit6 must be 0 for 24 hour clock
A1MINs = %10000001 '$501 + $80 = %10000001, for A1M2 = 1
A1sec = $00 '$00 = %00000000, for A1M1 = 0
A1day = %10000111 '$07 + $80 = $10000111, for A1M4 = 1
'DY/_DT Bit6 = 0 for using Day of month alarm
' Per MAXIM TechSupport, reset control register for desired Alarm
' after setting alarms.
I2CWrite SDA, SCL, RTCdevice, ContReg,[%00000101]
PAUSE 20
'Set the main Time
I2CWrite SDA, SCL, RTCdevice, SecReg,[sec,MINs,hr,day,date,mon,yr]
Pause 20
'Set the Alarm1 Time
I2CWrite SDA, SCL, RTCdevice, Alm1sec,[A1sec,A1MINs,A1hr,A1day]
PAUSE 20
'DISABLED...Set the Alarm2 Time ' Alarm2 disabled for this application
'I2CWrite SDA, SCL, RTCdevice, Alm2min,[A2MINs,A2hr,A2day]
'Pause 20
' Clear STATUS and set CONTROL registers
I2CWrite SDA, SCL, RTCdevice, StatusReg,[$00] ' Clear STATUS register
PAUSE 20
I2CWrite SDA, SCL, RTCdevice, ContReg,[%00000101]
' Starts the oscillator,
' enables INTA interrupt from A1F.
Pause 20
'Post setup test to see if Time set correctly by reading EEPROM stored time
I2CREAD SDA, SCL, RTCdevice, SecReg,[sec,MINs,hr,day,date,mon,yr]
PAUSE 20
WRITE 13,sec 'Write time to EEPROM for check after post run test
I2CREAD SDA, SCL, RTCdevice, MinReg,[MINs]
PAUSE 20
WRITE 12,MINs
I2CREAD SDA, SCL, RTCdevice, HrReg,[hr]
PAUSE 20
WRITE 11,hr
'Post setup test to see if Alarm set correctly by readig EEPROM stored time
I2CREAD SDA,SCL,RTCdevice,Alm1sec,[A1sec,A1MINs,A1hr,A1day]
PAUSE 20
WRITE 14,A1hr
PAUSE 20
WRITE 15,A1MINs
Pause 20
Return

END

Darrel Taylor
- 17th February 2010, 01:17
Without the PAUSE, there's nothing to keep the Watch Dog Timer clear.

LOW and GOTO don't generate CLRWDT instructions.
<br>

jellis00
- 17th February 2010, 18:50
Without the PAUSE, there's nothing to keep the Watch Dog Timer clear.
Thanks for the answer, Darrell. However, your answer raises some questions that I would like to understand the "why" of as a PICBASIC programmer so that I am not just blindly implementing code:

1) How is a PICBASIC programmer supposed to know that the WDT must be kept clear during the Main loop of a program when using the INT2 external intterupt of the DT_INTS-18 include file? I went through the code/comments of DT_INTS-18 and couldn't find anything that advises that.

2) Must the WDT be kept clear during Main loop when using other interrupts supported by DT_INTS-18 or just for the external interrupts INT1 or INT2??

3) I did see the following note in the data sheet and am wondering if this implies that the WDT is an interrupt flag and must be cleared before using any interrupt???

"Interrupt flag bits are set when an interrupt condition occurs regardless of the state of its corresponding enable bit or the global
interrupt enable bit. User software should insure the appropriate interrupt flag bits are clear prior to enabling an interrupt.
This feature allows for software polling."



LOW and GOTO don't generate CLRWDT instructions.
<br>

4) How does the use of the PAUSE statement insure that CLRWDT has been executed, whereas use of LOW or GOTO do not? I went through the instruction set in the data sheet and couldn't find anything that would indicate that.

Darrel Taylor
- 17th February 2010, 20:07
1) How is a PICBASIC programmer supposed to know that the WDT must be kept clear during the Main loop of a program when using the INT2 external interrupt of the DT_INTS-18 include file? I went through the code/comments of DT_INTS-18 and couldn't find anything that advises that.Why would you be looking in DT_INTS to find out about the WDT?
DT_INTS does nothing with the WDT, and your problem has nothing to do with INT2.
It's resetting the processor because it's sitting in the main loop without clearing the WDT.


2) Must the WDT be kept clear during Main loop when using other interrupts supported by DT_INTS-18 or just for the external interrupts INT1 or INT2??
Same answer here ... The WDT has nothing to do with interrupts.

3) I did see the following note in the data sheet and am wondering if this implies that the WDT is an interrupt flag and must be cleared before using any interrupt???

There are no interrupt flags for the WDT. The WDT does not generate interrupts, it resets or restarts the processor.


4) How does the use of the PAUSE statement insure that CLRWDT has been executed, whereas use of LOW or GOTO do not? I went through the instruction set in the data sheet and couldn't find anything that would indicate that.
Anything that takes time like PAUSE, SERIN etc. will have CLRWDT's in it.

HIGH LOW or GOTO are only 1 or 2 instructions.
If it put CLRWDT's in every one of those ... it would fill 1/3 of the program space with CLRWDT's, and the Dog would be getting kicked so many times he'd start Biting. :eek:

Unless you are using SLEEP mode with WDT wake-up, just turn the thing off.<br>