I have used RBC_INT many times before with no problems, but have encountered a problem with it as implemented in a unique code set that is driving me crazy.
Here is how it is supposed to work for comparison to code I will provide below:
1) DS1337 Real-time-clock generates an Alarm1 interrupt every minute on its _INTA pin which is connected to RB2 on my 16F886.
2) RBC_INT is supposed to recognize _INTA signal falling edge and go to handler labled "Alarm".
3) The ISR "Alarm" sets logflag=1 which is recognized by IF statement in main loop and calls subroutine "Logging" to log date/time stamped data.
I have extensive LED blinking codes embedded at various places in my code so I can see what is going on at run time. I also am writing key values to EEPROM to help in post-run troubleshooting. From these test techniques I can see very clearly what is going on but can't figure out how to correct it. Here is what is happening:
a) EEPROM entries show the clock has the correct Alarm1 time and is keeping good time and generates _INTA falling edge at correct Alarm1 time.
b) Lack of LED flashes indicate no entry to the Alarm handler...hence RBC_INT is not recognizing the _INTA signal change.
c) Therefore, the code in the Alarm Handler is not setting the logflag, resetting the _INTA on the RTC, or reading PortB to eliminate the mismatch.
d) With no set of the logflage, no triggering of the Logging subroutine in the mainloop.
d) Hence no further _INTA signals are generated by the RTC and the _INTA signal stays low as confirmed by a voltmeter.
e) With no further _INTA signals there are no further RTC_INT actions and my code malfunctions.
Hopefully with these code excerpts someone out there can tell me where I am going wrong and why the RBC_INT is not recognizing the _INTA. ANY HELP GREATLY APPRECIATED!!
Here is the code that I think sets up the RBC_INT correctly...can anyone see anything wrong with this?
Code:
'--- Setup Interrupts ----------------------------------------------------
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler RBC_INT, _Alarm, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
' Per DT, DT_INTS already takes care of setting INTCON register
' but this code doesn't work unles below registers also set as indicated:
IOCB.2= 1 ' ENABLE IOC INERRUPT ON PORTB.2 (RB2) for Alarm1
TRISB = %00010100 ' RB2 set as input from RTC Alarm1
' PORTB.2 is also an interrupt from manual switch GND
' PORTB.4 is set for input as A/D Channel 11
WPUB = 0 ' DISABLE all PortB pull-ups
CM1CON0 = 0 ' DISABLE COMPARATORS
CM2CON0 = 0 ' DISABLE COMPARATORS
Here is my mainloop code to show how things happen while waiting for RBC_INT occurence...LED blinks indicate it is operating correctly. but call to Logging subroutine is never triggered, indicated the logflag was never set in the RBC_INT handler:
Code:
mainloop:
' Blink Green LED 1x short at start of mainloop as heart beat
TOGGLE LED_GRN
PAUSE 250
TOGGLE LED_GRN
PAUSE 2000
' Read current time/date
I2CREAD SDA, SCL, RTCdevice, SecReg,[sec,MINs,hr,day,date,mon,yr]
PAUSE 20
' Display current Date/Time if LCD installed
IF LCD_Flag = 1 THEN ' Display only if LCD installed
LCDOUT $fe,1 ' Clear Display
LCDOUT $fe,Line1,HEX2 mon,"/",HEX2 date,"/", HEX2 yr
LCDOUT $FE,Line2,HEX2 hr,":",HEX2 MINs,":",HEX2 sec
ENDIF
' Read temperature & log to EEPROM for test readout
GOSUB Temperature
WRITE 6, temp 'COMMENTED OUT DURING OPS TO SAVE EEPROM
'Check to see if Alarm1 Interrupt occured and service if it did
IF logflag = 1 THEN ' Alarm1 interrupt has occured
;@ INT_DISABLE RBC_INT ' Disable RBC interrupts during routine
GOSUB Logging ' Log the interrupt
;@ INT_ENABLE RBC_INT ' Re-enable RBC interrupts after routine
ENDIF
' Send Email if temperature below/above threshold
IF (temp <= $28) THEN ' If temp <= 40 deg F send email
GOSUB Email
ELSEIF (temp >= $55) THEN ' If temp >= 85 deg F send email
GOSUB Email
ENDIF
'ADCON1 = %00001110
' Write current temperature to EEPROM ....Uncomment FOR TEST ONLY
WRITE 10, temp
GOTO mainloop
END
Here is my handler for the RBC_INT that is not being entered the way it should and hence actions required to reset flags and interrupts aren't happening:
Code:
Alarm:
' Blink Red LED 3x at start of Alarm interrupt...Uncomment FOR TEST ONLY
'THIS IS NEVER SEEN TELLING ME RBC_INT DIDN'T RECOGNIZE _INTA from RTC!
FOR I = 0 TO 2
TOGGLE LED_RED
PAUSE 250
Toggle LED_RED
PAUSE 250
NEXT
logflag = 1 ' Set flag to log this RB2 interrupt in mainloop
dummy = PORTB ' Read PortB to eliminate mismatch on interrupt
' Clear the Alarm flags to be ready for next RTC interrupt
' Reset Alarm1 (INTA) interrupt by clearing STATUS register
I2CWRITE SDA, SCL, RTCdevice, StatusReg,[$00]
PAUSE 1000
' Resume Main Program where Interrupt happened
@ INT_RETURN
And here is my logging subroutine that should be executed after each interrupt causes logflag to be set in handler (which obviously isn't happening):
Code:
Logging:
' Blink the RED LED 1 sec 3x
FOR I = 0 TO 2
TOGGLE LED_RED
PAUSE 1000
TOGGLE LED_RED
PAUSE 1000
NEXT
PAUSE 1000
IF J > 220 THEN ' If EEPROM logging space is full, reset logging
J = 0 ' index to start of logging space.
' Logging space covers time stamps for 220 interrupts
ENDIF
' Log date/time stamped temperature from LM34 sensor to EEPROM
WRITE 16+J, hr
WRITE 17+J, MINs
WRITE 18+J, sec
WRITE 19+J, temp
J = J+4
' Put code here to send email of current temperature
logflag = 0 ' Reset logflag before returning to mainloop
RETURN
Bookmarks