PDA

View Full Version : Problem with RBC_INT unique to this codeset...HELP!



jellis00
- 9th October 2011, 00:32
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?


'--- 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:


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:


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):


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

mackrackit
- 9th October 2011, 05:17
I do not see where PORTB.2 is set to digital.

jellis00
- 9th October 2011, 06:22
Thanks Sooo Very Much, Dave, for looking at this! I thought you had found the problem. Per your input I added the following statement to the interrupt setup thinking that would solve the problem, because as much as I studied this code I failed to see that I hadn't made RB2 a digital input in the interrupt setup:
ANSELH.0 = 0 ' Set ANS8 (RB2) as digital pin

However, this didn't solve the problem. _INTA on RB2 pin still doesn't go back to HIGH after the 1st _INTA occurs, and all of my above description of the problem remains the same, as if RBC_INT wasn't recognizing the _INTA transition.

Any other ideas from you or others? This is a very frustrating problem that I have now spent over 18 hours trying to troubleshoot!!!

mackrackit
- 9th October 2011, 06:49
I am guessing..

Change

INT_Handler RBC_INT, _Alarm, PBP, yes
to
INT_Handler INT_INT, _Alarm, PBP, yes

That should see any change on PORTB and being your other PORTB pins are analog, from the data sheet:

Note 1:
Setting a pin to an analog input automatically disables the digital input circuitry, weak pull-ups, and
interrupt-on-change if available. The corresponding TRIS bit must be set to Input mode in order to allow
external control of the voltage on the pin.

Darrel Taylor
- 9th October 2011, 16:47
John,

One possiblility ...

Your MainLoop is talking to the RTC on every loop to check the time.
If an Alarm happens while the mainloop is using I2CWRITE, and it tries to use I2CWRITE to clear the status reg, it's probably going to confuse the RTC.

Since you have 1 minute till the next Alarm INT, try clearing status in the MainLoop or Logging routine.

jellis00
- 9th October 2011, 21:27
PROBLEM SOLVED via the following process!!

Followed Darrel's suggestion and put the following code block at the end of Logging routine instead of trying to clear status at end of handler.


' Clear STATUS and set CONTROL registers on RTC to prepare for
' next _INTA interrupt
I2CWRITE SDA, SCL, RTCdevice, StatusReg,[$00]
PAUSE 10
I2CWRITE SDA, SCL, RTCdevice, ContReg,[%00000101]
PAUSE 10


Still had same problem after doing above. Dave's comment caused me to back through ALL of my code looking for anything that effect PortB.2 where I am trying to use RBC_INT. I had forgotten that the subroutine I cut/pasted into this program to take an analog temperature measurement, that I have used before to take an analog readin,g had the following statements at the end of it to reset PortB back to digital and all outputs.


' Disable AD and go to all digital ops
ADCON0.0 = 0
TRISB = 0


Removing the above statements from my Temperature routine and making the below adjustments to the Interrupts setup at the beginning of my cod solved all the problem! Thanks so much Dave and Darrel....I wouldn't have found this for probably another 2 days or more if you hadn't cue'd me in the righ direction.


'--- Setup PORTB 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:
TRISB.2 = 1 ' RB2 set as input from RTC Alarm1
' PORTB.2 is also an interrupt from manual switch GND
TRISB.4 = 1 ' PORTB.4 is set for input as A/D Channel 11
ANSELH.0 = 0 ' Reset ANS8 (RB2) as digital pin
IOCB.2= 1 ' ENABLE IOC INERRUPT ON PORTB.2 (RB2) for Alarm1
WPUB = 0 ' DISABLE all PortB pull-ups
CM1CON0 = 0 ' DISABLE COMPARATORS
CM2CON0 = 0 ' DISABLE COMPARATORS