12F683 and DT Instant Interrupts
I am trying to use Darrel Taylor's great Instant Interrupts (thank you!) on a 12F part. Originally, I was using a 12F635. I changed to a 12F683 after reading posts about doing this, because I was under the impression it would work O.K. However, I still get the following message when compiling:
ERROR:Variable wsave2 position request 288 beyond RAM_END 191.
Do I still need to comment out some lines?
@ device pic12f683, INTRC_OSC_NOCLKOUT, WDT_OFF, MCLR_OFF, PROTECT_OFF
OPTION_REG = %11000000
OSCCON = %01100001
TRISIO = %001100
CMCON0 = %00000111
ANSEL = 0
CCP1CON = 0
RATESW VAR BYTE
HIGH GPIO.0
HIGH GPIO.1
HIGH GPIO.4
HIGH GPIO.5
pause 100
RATESW = 0
INCLUDE "DT_INTS-14.bas" ' Base Interrupt System
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler INT_INT, _SWINT, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
INT_ENABLE INT_INT ; enable external (INT) interrupts
ENDASM
Main:
if ratesw = 1 then Rate1
if ratesw = 2 then rate2
if ratesw = 3 then rate3
if RATESW > 3 then RESET
GOTO Main
Rate1:
while ratesw = 1
LOW GPIO.0
low GPIO.1
pause 150
high GPIO.0
high GPIO.1
low GPIO.4
low GPIO.5
PAUSE 150
high GPIO.4
high GPIO.5
wend
Rate2:
while ratesw = 2
LOW GPIO.0
low GPIO.1
pause 100
high GPIO.0
high GPIO.1
low GPIO.4
low GPIO.5
PAUSE 100
high GPIO.4
high GPIO.5
wend
Rate3:
while ratesw = 3
LOW GPIO.0
low GPIO.1
pause 50
high GPIO.0
high GPIO.1
low GPIO.4
low GPIO.5
PAUSE 50
high GPIO.4
high GPIO.5
wend
RESET:
RATESW = 0
GOTO Main
GOTO Main
'---[INT - interrupt handler]---------------------------------------------------
SWINT:
while GPIO.2 = 0:wend
pause 100
if GPIO.2 = 1 then
RATESW = RATESW + 1
endif
@ INT_RETURN
Thank you
Reload the TMR1H:TMR1L properly ?
Now my code compiles fine thankyou, barring a overwriting previous address warning from my config settings (I understand why that is). But I have a small question regarding reloading the timer for anyone.
Must I stop the timer while reloading it with a hex value of A823 in the interrupt handler code (which is all it needs to do) ?
T1CON = %0
TMR1H = $A8
TMR1L = $23
T1CON = %1
Or can I ignore the stop-start safely. Given I can tweak the timer value by trial and error to get my 22.5mS @ 4Mhz ?
The only examples I've dug out on the forum are using ASM code and I'm not strong on interpreting it.
Elegent way to exit the handler and goto main code
In my code I do a bunch of stuff then wait doing nothing for an interrupt some mS later, then when that happens I want to run my bunch of stuff again, forever and ever. Rather than return to where the interrupt occurred in my 'wait doing nothing'....
I see the obvious way is to put my 'bunch of stuff code in the interrupt handler subroutine, but that makes the int handler routine very big and the 'main' code very small. Looks all wrong to me. Is that the way to do it or is there a proper way to get the int handler to go to my 'bunch of stuff' rather than return to where it was interrupted from ?
Code:
LED1 VAR GPIO.1
INCLUDE "DT_INTS-14.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, _ToggleLED1, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
T1CON = $01 ; Prescaler = 1, TMR1ON
@ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts
Main:
Big bunch of stuff
wait_here:
pause 1
Goto wait_here 'wait for an interrupt here
(Return from Interrupt would hang here ?)
GOTO Main 'should never happen
'---[TMR1 - interrupt handler]--------------------------------------------------
ToggleLED1:
T1CON = %0
TMR1L = $23
TMR1H = $A8
T1CON = %1
TOGGLE LED1
@ INT_RETURN
Generate PPM frames at 22.5mS rate
Quote:
Originally Posted by
Acetronics
Hi, Mr Sneezy
I do not know what's your final project ... BUT :
Alain
but you're very very close Alain.....
Except in my application I'm needing to generate an 8ch PPM pulse frame at 22.5mS rate from scratch.
To cut to the chase what I want to do is build a simple RC TX radio eliminator so I can test prototype 2.4Ghz transmitter modules in the field (range tests etc etc) without needing a second person to wiggle the sticks on the radio (it uses Futaba compatible TX modules). I did the obvious thing and looked for existing projects but they all seem to decode PPM frames not create them...
The app will change the PPM period for two channels (at least) slowly so the servos move at the RX end while I move away doing testing (sometimes Km's). The remaining channels will just be 1.5mS center position all the time.
Sorry for the apparently newbie programming questions, I've actually written some quite large complex code in the past (way way past) but I do it so infrequently now I have to go back to basics at the start of a new project like a beginner. I never seem to do a similar project twice which doesn't help.
I guess another way of asking my question is can I have a lot of code in the interrupt handler subroutine ? Or could that bugger up the interrupt code ?
Thanks,
Martin
Hanging the interrupt registers ?
Getting back on topic with DT int code. Is it a bad thing to put GOTO's or GOSUB'S inside the interrupt handler ? Therefore maybe never seeing the @ INT_RETURN
'---[TMR1 - interrupt handler]--------------------------------------------------
ToggleLED1:
T1CON = %0
TMR1L = $23
TMR1H = $A8
T1CON = %1
TOGGLE LED1
GOTO MAIN 'is this dangerous ?
@ INT_RETURN
You've asked for it ... do not cry, now !!!
Hi, Martin
Darrel will love it, for sure !!! ( Lol ...)
Code:
'*****************************************************************************
'FRAMEGEN.BAS
'*****************************************************************************
'
' Générateur de Trame R/C Graupner/Multiplex sur 12F675
'
' 4,7,8 ou 9 Canaux - Neutre 1.5 ms
'
' Oscillateur interne 4 Mhz
'
' Trames déclenchées par interruptions TMR0 : PS = 1/128 Pl = 80
'
' Sortie sur GPIO.5
' Choix 4,7,8 ou 9 voies sur GPIO.3 et 4
'*****************************************************************************
'*****************************************************************************
'
@ __config _INTRC_OSC_NOCLKOUT & _WDT_ON & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _BODEN_ON
DEFINE OSC 4
DEFINE OSCCAL_1K 1
DEFINE INTHAND _Marker
ADCON0 = 0
ANSEL = 0
CMCON = 7
OPTION_REG = %10000110 'Disable Pull-Ups - PSA = 128
INTCON = %00100000 'TMR0 interrupt
PIE1 = 0
PIR1 = 0
'*****************************************************************************
' Constantes
Mark CON 400
Reload CON 80
Neutral CON 1500
GR CON 8
MPX CON 9
'*****************************************************************************
' Variables
PROGRAM var byte
PROGRAMOLD var byte
FRAME4 var bit
FRAME7 var bit
FRAME8 var bit
CLEAR
'*****************************************************************************
' I/Os
GPIO =%00100000 'GPIO.5 = 1 at startup
TRISIO =%00011000 'set GPIO3 GPIO4 as input GPIO.5 as Output
'*****************************************************************************
GOTO INIT
'*****************************************************************************
'*****************************************************************************
Marker: ' Interruption - Génération de la trame
TMR0 = Reload
GPIO.5 = 0
PAUSEUS Mark
GPIO.5 = 1 ' Voie 1
PAUSEUS 696
GPIO.5 = 0
PAUSEUS Mark
GPIO.5 = 1 ' Voie 2
PAUSEUS 796
GPIO.5 = 0
PAUSEUS Mark
GPIO.5 = 1 ' Voie 3
PAUSEUS 896
GPIO.5 = 0
PAUSEUS Mark
GPIO.5 = 1 ' Voie 4
PAUSEUS 992
IF FRAME4 THEN Selection
@ NOP
GPIO.5 = 0
PAUSEUS Mark
GPIO.5 = 1 ' Voie 5 - 1500µS
PAUSEUS 1096
GPIO.5 = 0
PAUSEUS Mark
GPIO.5 = 1 ' Voie 6
PAUSEUS 1196
GPIO.5 = 0
PAUSEUS Mark
GPIO.5 = 1 ' Voie 7
PAUSEUS 1290
IF FRAME7 THEN Selection
@ NOP
GPIO.5 = 0
PAUSEUS Mark
GPIO.5 = 1 ' Voie 8
PAUSEUS 1392
IF FRAME8 THEN Selection
@ NOP
GPIO.5 = 0
PAUSEUS Mark
GPIO.5 = 1 ' Voie 9
PAUSEUS 1496
Selection:
GPIO.5 = 0
PAUSEUS Mark
GPIO.5 = 1
'*****************************************************************************
'Lecture des Jumpers
PROGRAM = GPIO & %00011000
IF PROGRAMOLD <> PROGRAM THEN INIT
'*****************************************************************************
Start: 'Fin d'Interruption
INTCON.2 = 0
INTCON.7 = 1
'*****************************************************************************
CYCLE: 'Boucle de fonctionnement
WHILE 1
WEND
'*****************************************************************************
INIT: 'Lecture des Jumpers
PROGRAM = GPIO & %00011000
SELECT CASE Program
CASE 24
FRAME4 = 1 : FRAME7 = 0 : FRAME8 = 0
CASE 16
FRAME4 = 0 : FRAME7 = 1 : FRAME8 = 0
CASE 8
FRAME4 = 0 : FRAME7 = 0 : FRAME8 = 1
CASE ELSE
FRAME4 = 0 : FRAME7 = 0 : FRAME8 = 0
END SELECT
PROGRAMOLD = PROGRAM
GOTO Start
END
If you want to have variable pulse length... just inc or dec the PAUSEUS value before the "START" Label
And ... if you find something strange ... it is NOT an error !!!
( I told you Darrel would love it ....)
Alain