PDA

View Full Version : Simple ISR?



MOUNTAIN747
- 9th March 2010, 02:30
My project is a 24hr temp logger. Which logs every 15 minutes for the 24hr period. The 15 minute timer is the PBP “SLEEP” command. After 24 hours the application goes to sleep” @sleep”. I want an interrupt on GP2 external interrupt pin to stop the 15min. timer or the “@sleep” and send the program to a PBP routine to RS232 dump to PC. At that time the job is done, unit goes to low power state until power disconnect. I don’t want to use ON INTERRUPT, can’t wait 15min. to print. Once interrupted I don’t need to save any variables, or STATUS or PCLATH (<2k) logging is done, I only need a “goto _printout” placed at location 04. So how do I accomplish that? AND have I missed something of the process?



@ DEVICE PIC12F683,MCLR_OFF,INTRC_OSC_NOCLKOUT ,WDT_ON,BOD_OFF
@ DEVICE PWRT_ON,FCMEN_OFF,IESO_OFF,PROTECT_ON
OSCCON=%1110000
Define OSC 8

VRCON = 0
ADCON0 = 0
OPTION_REG = %01000000 ;rising edge
ANSEL = 0 ;digital all
CMCON0 = 7
INTCON = %10010000 ;Globle set, GP2 ext int, flg clr
GPIO=0
TRISIO=%00001100 ;GPIO.2 input
;GPIO.2 held low until button push +5v
Blink var GPIO.4

GOTO Start
define INTHAND myint
asm
myint goto _printlog
endasm
Start:
----- LOG DATA for 24hrs
Printlog:
----- RS232 to PC
INTCON = %10010000 ;in the case another print out is needed
@sleep


I’ve written a small INT test program to work this out but I’m not having any luck. On compile I get the error “undefined symbol myint” & “opcode expected instead of myint”
I remove the myint from the asm line and the opcode error goes away. However I think this is needed as it is the ASM label. This ASM method is right out of the 2.60 manual. What is it I’m not getting? Comments Please!

Jerson
- 9th March 2010, 04:58
I tried out your code. The only change that needs to be done is in how you define myint

myint goto _printlog

myint should start in the 1st column of your file.

MOUNTAIN747
- 9th March 2010, 12:16
Thank you Jerson for your reply. I did not understand the relevance of the first column positions of the instruction. As a matter of fact the manual has the instruction on the first column. This should get me up and running. Thank you again for your response

MOUNTAIN747
- 9th March 2010, 14:25
I have written this short piece of code to test the interrupt. IT Works! but only ONCE... For some reason it will not interrupt the second time unless I reset the processor with the power. I can't see a problem. I am resetting INTCON before return to main program. ???

[
@ DEVICE PIC12F683,MCLR_OFF,INTRC_OSC_NOCLKOUT ,WDT_ON,BOD_OFF
@ DEVICE PWRT_ON,FCMEN_OFF,IESO_OFF,PROTECT_OFF
OSCCON=%1110000
Define OSC 8

VRCON = 0
ADCON0 = 0
OPTION_REG = %01000000 ;rising edge
ANSEL = 0 ;digital all
CMCON0= 7
INTCON = %10010000 ;GlE set, INTE set, INTF clr
GPIO=0
TRISIO = %00001100 ;GPIO.2 input
Avar var byte
Blink var GPIO.4
TX var GPIO.5
GOTO Main
define INTHAND myint

asm
myint goto _printlog
endasm

Main:

Blinkled:
pause 1000
for Avar=1 to 4
HIGH blink
pause 100
low blink
pause 200
next Avar

Serout2 tx, 84, [" This is a test, This is only a test",13,10,13,10] ;print to PC
goto Blinkled
printlog:
Serout2 tx, 84, [" An Interrupt has occured on GP2",13,10,13,10]
INTCON=%10010000 ;set GIE, INTE and clear INTF
goto Main
end

Jerson
- 9th March 2010, 15:57
your printlog is an ISR (interrupt service routine) and should end with a return not a goto main. Try that

MOUNTAIN747
- 9th March 2010, 22:01
Jerson,
Yes, I had forgotten about the address that was pushed on the stack by the interrupt. I tried a RETURN and @RETFIE , the micro locked up for a couple of seconds then restarted, I think by WDT, and would not re-interrupt. I know I have to deal with the stack but RETURN will load an address I don’t want to use. So my challenge it to find a way to POP the stack, discard the address and load a new address while still resetting interrupt bits. It looks like there is NO easy way to do this. I’m sure that is why DT_INT is so popular. By the way thanks again for lending a helping hand to the struggling hobbyist, mainly me. I’ll keep working on this problem and post any success.
WANTED: easy way to use Ext Interrupt to change the course of a program.

MOUNTAIN747
- 12th March 2010, 22:48
My solution for a quick and easy one shot interrupt to send the main body of my program to a completion routine to send data to the PC is as follows.

goto Start
define INTHAND myint

asm
myint goto _printlog
endasm

That’s it! On completion of data logging the unit goes to low power state “@sleep”. When the user is ready to log to the PC, a GP2 ext int button is pushed. Unit goes to printlog and uploads data then goes to low power.

With GIE clear from interrupt INTF does not have to be cleared and no Return or Retfie is needed if the program is not going back to the position of interrupt, I am not concerned with anything on the stack since the main program is finished so if data is pushed off the stack during the upload routine, who cares. The only thing I was not able to do was reset the interrupt function to operate again without resetting the processor. INTCON was reset but it just didn’t work without a reset. (?) SO, for a one shot interrupt to a last short routine, this works great.

Final note of interest: The program uses SLEEP and @sleep. PBP SLEEP uses WDT to time the sleep period indicated. @sleep is used to go to a low power state indefinitely if the WDT is turned off. My program uses WDT under software control (WDTCON) to give me the ability to use both instructions. PBP SLEEP will not function properly under software control unless you set WDTCON.WDTPS =100. It took me a while to figure out why SLEEP60 was timing out in 5sec. rather than 1min.