PDA

View Full Version : Problem with RAC_INT



Dick Ivers
- 3rd March 2010, 21:40
Hello again,
Thanks to DT's advice I was able to get my elapsed timer test program working well. I modified the original Elasped_INT routine in order to keep track of time in seconds and tenths of seconds to suit my purpose. My test circuit using this program worked perfectly, with good accuracy when checked against a stopwatch.

However, when adding another interrupt source there was no response from the breadboard circuit. The new source was RAC_INT, interrupt on portA change. The circuit has switches on several portA pins. Input changes on the pins was verified, but the test progarm did not respond as expected.


'device is PIC 16F684

'set registers
OPTION_REG.7 = 0 'enable porta pullups
CMCON0 = 7 'comparators off
ANSEL = 0 'porta pins all digital
TRISA = %111111 'set porta pins as input
TRISC = %001101 'set portc pins 0,2,3 as input, all others output
OSCCON = %1110000 'set internal osc. at 8 mhz, wait for stable freq.
OSCTUNE = 0 'internal osc. running at factory calibration

DEFINE OSC 8 '8 Mhz oscillator

while OSCCON.2 = 0 'wait for osc.to be stable
wend

'declare variables
led var portc.3 'led output on portc.3
DTtime var word
sum var word

start:
low led 'flash red LED for 0.5 sec
pause 500
input led

pause 2000 'pause 2 seconds

INCLUDE "DT_INTS-14 for F684.bas" 'Base interrupt with wsave selected for 16F684
INCLUDE "ReEnterPBP.bas" 'Using PBP interrupts
INCLUDE "Elapsed_INT_RI.bas" 'Elasped timer counting seconds and tenths seconds

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, _ClockCount, PBP, yes
INT_Handler RAC_INT, _RDT, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor

INT_ENABLE TMR1_INT ; Enable Timer 1 Interrupts
INT_ENABLE RAC_INT ; Enable PortA Change Interrupt
ENDASM

DTtime = 1800 ' 180.0 second test
Gosub ResetTime ' Reset Time to 0d-00:00:00.00
Gosub StartTimer ' Start the Elapsed Timer

Main:
low Led 'turn on led
sum = 10*Seconds + Tenths
if sum => DTtime then
high led 'turn off led
goto halt
endif
GOTO Main

'-------Interrupt Handler for RDT------------
RDT:
low led 'turn led on
pause 2000 'pause 2 seconds
@ INT_RETURN
'---------------------------------------------
halt: end


427 words

mark_s
- 3rd March 2010, 22:28
Your timer interrupt is firing 10 times a second, which means your "RDT" routine can never complete with a 2 second pause. Try polling the switches in your "main" loop, instead of using a second interrupt. You should have plenty of time.

Regards

Darrel Taylor
- 3rd March 2010, 22:31
'-------Interrupt Handler for RDT------------
RDT:
low led 'turn led on
pause 2000 'pause 2 seconds
@ INT_RETURN


With any of the PORT change interrupts, you have to Read the port inside the handler to end the "mismatch" condition.
Otherwise DT_INTS can't reset the int flag, and it will lock up in a continuous interrupt loop..
DUMMY = PORTA
<br>

Bruce
- 3rd March 2010, 23:25
Ditto - and you might want to have something in your interrupt handler that waits for the input pin to return to the idle state before exiting your interrupt handler.

I.E. if your button press takes the pin low, to generate the interrupt, wait for it to return high before exiting. Otherwise you'll have interrupts on button press & release.

Dick Ivers
- 4th March 2010, 16:48
Still not clear on how to end the mismatch in porta. Tried the following code, but it did not work on the breadboard. I'm looking for the the led to go off and stay off for 2 seconds, and then the timing to resume. This is just a demo tryout.

All of this is just testing to try to understand how instant interrupts work. Of course I know it's possible to just poll a porta pin in the main loop ... I do it that way with my non-interrupt software.


'device is PIC 16F684

'set registers
OPTION_REG.7 = 0 'enable porta pullups
CMCON0 = 7 'comparators off
ANSEL = 0 'porta pins all digital
TRISA = %111111 'set porta pins as input
TRISC = %001101 'set portc pins 0,2,3 as input, all others output
OSCCON = %1110000 'set internal osc. at 8 mhz, wait for stable freq.
OSCTUNE = 0 'internal osc. running at factory calibration

DEFINE OSC 8 '8 Mhz oscillator

while OSCCON.2 = 0 'wait for osc.to be stable
wend

'declare variables
led var portc.3 'led output on portc.3
DTtime var word
sum var word
dummy var byte

start:
low led 'flash red LED for 0.5 sec
pause 500
input led

pause 2000 'pause 2 seconds

INCLUDE "DT_INTS-14 for F684.bas" 'Base interrupt with wsave selected for 16F684
INCLUDE "ReEnterPBP.bas" 'Using PBP interrupts
INCLUDE "Elapsed_INT_RI.bas" 'Elasped timer counting seconds and tenths seconds

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, _ClockCount, PBP, yes
INT_Handler RAC_INT, _RDT, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor

INT_ENABLE TMR1_INT ; Enable Timer 1 Interrupts
INT_ENABLE RAC_INT ; Enable PortA Change Interrupt
ENDASM

dummy = porta ' initialize dummy variable
DTtime = 1800 ' 180.0 second test
Gosub ResetTime ' Reset Time to 0d-00:00:00.00
Gosub StartTimer ' Start the Elapsed Timer

Main:
low Led 'turn on led
sum = 10*Seconds + Tenths
if sum => DTtime then
high led 'turn off led
goto halt
endif
GOTO Main

'-------Interrupt Handler for RDT------------
RDT:
high led 'turn led off
dummy = porta 'needed to end mismatch in porta
pause 2000 'pause 2 seconds
@ INT_RETURN
'---------------------------------------------
halt: end
431 words

Bruce
- 4th March 2010, 17:39
You may need to enable the on-change interrupt for the input pin you're using to trigger
the interrupt. Say you're using RA0, then IOCA0=1 would enable on-change interrupt for
this pin.

Then in your interrupt handler, wait for the pin to return to the idle state before exiting.

Something like WHILE PORTA.0 = 1:WEND. Assuming RA0 was held low, and a switch press
taking it high caused the on-change interrupt.

Interrupt happens on RA0 going high, jumps to int handler, waits for pin to return low before
exiting & re-enabling interrupts.

Dick Ivers
- 4th March 2010, 21:21
Thanks Bruce, your suggestion worked. Setting IOCA.4 = 1 enabled the change on porta interrupt to function properly. I have a switch on porta pin 4. The interrupt works for both on-switching and off-switching.

Of course, each time the interrupt is used 2 seconds is added to the clocked time because of the delay inside the handler. In the real program I don't want this happening. This interrupt will only be used once. After it occurs this interrrupt can be disabled. I then want to jump to another program loop. I'll try some experiments to see if this can be done ...

Bruce
- 4th March 2010, 21:37
Hi Dick,

If the user will not be pressing & holding the switch, then read the port pin after the 2 sec
pause.

Otherwise you need to wait for the pin to return to the non-button-pressed state or it just
interrupts again after the port read & switch release.

If it's a one-shot deal, just disable it by clearing IOCA.4.

lugo.p
- 5th March 2010, 15:54
I intend to use the IOC too, but i'm not sure if i need those:

DT_INTS-14 for F684.bas
ReEnterPBP.bas
Elapsed_INT_RI.bas


if so, where i find this .bas files?

Dick Ivers
- 5th March 2010, 22:07
Files attached. Rename without .txt to use.

lugo.p
- 8th March 2010, 15:15
Thanks Dick but i'm still having troubles with IOCA over 16f684.

Because i have not much experience with PicBasic, i have been reading about IOC but don't understad how to implement a basic interrupt on change