PDA

View Full Version : DT_INTS-14 , Elasped_INT, and 16F87 code not working



BrianS
- 21st July 2014, 18:23
This code is written to choose between two time durations of 5 minutes and 30 seconds. A hardware switch is wired to RB4 which is pulled high. In one position the switch is open and the port is high. The other position pulls RB4 to ground. RB4 is coded for Interrupt on change. This switch will determine the time duration to use.

Ports RB0 and RB3 are outputs to leds. One will be on while the other is the off state. They switch states every time the timer reaches it's elapsed time of either 30 seconds or 5 minutes. whatever is set by RB4.

I had this code working for an 18F device and trying to get this same code to work for a 16F87 using DT_INTS-14. Nothing happens when running on the pic. The pic's clock it running fine. MCLR is pulled high as it should be. Would be appreciate it if someone could help.


DEFINE OSC 20
'Include "Modedefs.bas"
Include "DT_INTS-14.bas"
Include "ReEnterPBP.bas"
Include "Elapsed_INT.bas"

'#CONFIG
' __config _HS_OSC & _WDT_ON & _PWRTE_OFF & _BODEN_OFF & _LVP_OFF & _CPD_OFF
'#ENDCONFIG




TRISB = %11110110
TRISA = %111111
wsave VAR BYTE $70 SYSTEM
wsave1 VAR BYTE $A0 SYSTEM
wsave2 VAR BYTE $120 SYSTEM
wsave3 VAR BYTE $1A0 SYSTEM
PortsToggled var bit
Sel_Min var bit
Sel_Sec var bit



ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, _ClockCount, PBP, yes
INT_Handler RBC_INT, _RBC_INT_HANDLER, PBP, yes ; use for PBP type interrupts
endm
INT_CREATE ; Creates the interrupt processor
ENDASM


@ INT_ENABLE TMR1_INT ; Enable Timer 1 Interrupts
@ INT_ENABLE RBC_INT

Gosub InitialState
Start:
if Sel_sec = 1 then
if SecondsChanged = 1 then
SecondsChanged = 0
If seconds = 30 then
Gosub TogglePorts
Gosub StopTimer
GoSub StartClock
endif
endif
else
if MinutesChanged = 1 then
MinutesChanged = 0
If Minutes = 5 then
Gosub TogglePorts
Gosub StopTimer
GoSub StartClock
endif
endif
endif
goto Start
end


RBC_INT_HANDLER:
PAUSE 10
Gosub StopTimer
GOSUB ResetTime
READ_SWITCH:
if Portb.4 = 0 then
Sel_Sec = 1
GoSub StartTimer
else
Sel_Sec = 0
GoSub StartTimer
endif
GOTO END_RBC_INT
PAUSE 5
GOTO READ_SWITCH
END_RBC_INT:
PAUSE 10
@ INT_CLEAR RBC_INT
@ INT_ENABLE RBC_INT
@ INT_RETURN

StartClock:
GOSUB ResetTime ' Reset Time to 0d-00:00:00.00
GOSUB StartTimer ' Start the Elapsed Timer
return


InitialState:
MinutesChanged = 0
SecondsChanged = 0
PortsToggled = 0
PortB.0 = 0
PortB.3 = 0
if Portb.4 = 0 then
Sel_Sec = 1
else
Sel_Sec = 0
endif
GoSub StartClock
return



TogglePorts:
if PortsToggled = 1 then
PortB.0 = 1
PortB.3 = 0
PortsToggled = 0
else
PortB.0 = 0
PortB.3 = 1
PortsToggled = 1
endif
return

Dave
- 22nd July 2014, 11:33
Maybe it's my eyes but I see NO "Gosub StopTimer, or any GOSUB ResetTime" routines. Also you should NOT be using GOSUB's inside an interrupt.

Archangel
- 22nd July 2014, 18:39
Try WDT_OFF WDT will reset everything if ISR takes too long, at least that's what I read once upon a time.

HenrikOlsson
- 22nd July 2014, 23:24
Hi,

Also you should NOT be using GOSUB's inside an interrupt.
This is one of my pet peeves.... I see it being mentioned "all the time" but never ever does anyone give an explanation to why.

I mean, I CAN see reasons for it not being a good idea but to just generally advising against it is a bit strong IMO.

One reason for it not being a good idea is, for example, if you're GOSUB'ing a routine (from within the ISR) that you ALSO may be GOSUB'ing from somewhere in your main program loop - if an interrupt occurs while the main program loop is within the subroutine. If that happens the "instance" of the routine that the main program is executing may be "corrupted" by the ISR executing the same piece of code.

I'm not saying I'm correct here, what I'm asking for it to please explain WHY you should NOT do it. Doing so will help us UNDERSTAND and not just painstakingly follow an advice that we do not understand the reasoning behind.

/Henrik.

richard
- 22nd July 2014, 23:41
the problem is with the stack . core 14 devices have a 8 level hardware stack , 4 levels can be used by pbp leaving 4 for your program. an interrupt will use 1 of these , a gosub in the interrupt uses another .
its not impossible to do but you need to be mindful of the limitations

mark_s
- 23rd July 2014, 01:06
I seem to remember when using pic16F's and interrupt on change you had to read portb to clear a mismatch?



dummy = portb
@ INT_RETURN

Dave
- 23rd July 2014, 15:23
Mark_s, You are correct, But who reads the data sheets anyways? Henrick and Richard, you are both correct, Also there are the extra cycles used up in the stack execution.