PDA

View Full Version : Instant Interrupts - Revisited



Pages : 1 2 [3] 4

Ioannis
- 14th October 2009, 16:13
I think next one Darrel has to answer, but if anyone knows...

How fast will the DT-INTS 14 interrupts (with PBP service) respond to a PORTB Interrupt on change?

Or better put, how many cycles will it take?

I am testing a Wiegand-26 reader the has 48uSec pulses every 2ms and at 4MHz the 16F628 chip does not feel it at all.

Another reader the has 0,38ms pulse is OK with the 16F628. The PIC is running rather slow at 4MHz.

I'd prefer a way to calculate the time it takes to respond on an Interrupt.

My service test routine is something like this:



CardReader:
if d0=0 then
array[index]=0
index=index+1
endif

if d1=0 then
array[index]=1
index=index+1
endif
@ INT_RETURN


Ioannis


P.S. After some testings I found that the pulse must stay at more that 150uSec for the PIC to grab it. Thats it at 4MHz.

Ioannis
- 14th October 2009, 17:17
Sorry I missed the Edit window time.

The 150uSec is really 115uSec...

Ioannis

circuitpro
- 3rd November 2009, 22:44
DT,

I have only used interrupts once, (using Instant Interrupts) based on your clock routine. I am starting a design in which I want to again use your interrupt routines, (and I admit I haven't read all your examples and documentation yet). I'm at the point where I'm making a first guess at pin assignments on a PIC18F67J60. I know I'm going to have to use the clock output of a rotary encoder as one interrupt source, and a generic 'some button has been pushed' kind of interrupt from a bunch of PCF8574's as another. Being really new at interrupts, which would more straightforward to implement... the PortB 'onchange interrupts', or individual B0 (Int0), and B1 (Int1) dedicated interrupts?

Thanks much,
Len G.

Darrel Taylor
- 4th November 2009, 01:42
It really depends on what you need to catch.

If you only need to catch either the Rising or Falling edge of a signal, then it's much easier to use INT1, INT2 and INT3.

But it you need to catch both edges, then the best route is RBC_INT (PORTB Change) on PORTB.4-7.

So I'd guess buttons on INT?, and encoders on RBC.
<br>

circuitpro
- 4th November 2009, 01:59
Thank you.

ralfmayr
- 4th November 2009, 08:39
Hi Darrel,
i use your instant interrupts on a 18F6722.
A question to the interrupts:
I want to use a timer which shall make 1sec ticks and i have both uarts receving commands from other devices. I also have two subs writing and reading via I2C-Bus to some internal devices. Problem: If having more and more activity on the i2c bus and also interrups are coming via the uarts, the timer is getting slower (2 - 3 sec) depending on the activity.
All interrups are defined as high priority interrups.
Any idea?

Regards,
Ralf

Darrel Taylor
- 4th November 2009, 18:16
I want to use a timer which shall make 1sec ticks and i have both uarts receving commands from other devices. I also have two subs writing and reading via I2C-Bus to some internal devices. Problem: If having more and more activity on the i2c bus and also interrups are coming via the uarts, the timer is getting slower (2 - 3 sec) depending on the activity.
All interrups are defined as high priority interrupts.
Any idea?
Hi Ralf,

Do you have PAUSEs in your handlers?
Interrupt handlers should be as fast as possible, get in - do only what needs to be done - and get out.

If for instance it were writing to I2C EEPROM then sitting around waiting 10mS for each write to complete, then no other interrupts can occur during that time that it's doing nothing.

If you have pauses, or long strings of data being sent or received, then those handlers should be LOW PRIORITY. Then with the Timer still in High Priority, it won't miss a beat.

hth,

ralfmayr
- 5th November 2009, 08:40
Hi Darrel,
thanks for the answer.
I don't have any pauses, the i2c bus writes and reads ad-converters and io-expanders, no eeproms.

I think the main problem is the handler for the uarts. The interrups for the uarts are handled as fast as possible, i read back the RCSTA registers and then i put the data in an array, by triggering on "{" and "}" for start of text and end of text. When "}" was received the serial command is valid and then i parse the string.
After that i handle my i2c bus and so on....
Maybe it is more effective to make a ring buffer, and when ever there is time then i check this buffer and parse the data in it. But i never made such a ring buffer.....

Regards,
Ralf

Darrel Taylor
- 5th November 2009, 20:55
Receiving data 1-byte at a time is always the best way to do it with USARTs and interrupts.

No Timeouts, no WAIT(), and no long strings.

For a simple Ring buffer, check out Joe S.'s Serial Backpack program, modified for DT_INTS.

http://www.picbasic.co.uk/forum/showthread.php?p=28336#post28336
<br>

circuitpro
- 10th December 2009, 01:17
I hope this hasn't been answered already but,

What about using Instant Interrupts with PBPL? Should they work? I'm really hoping I'm just doing something wrong cause I'm gonna need them!! (I'm using Ver 2.50 and 2.60 is in the mail)
:-|

Darrel Taylor
- 10th December 2009, 02:22
What about using Instant Interrupts with PBPL? Should they work?
Yes they should.
<br>

circuitpro
- 10th December 2009, 02:46
With the PBPL box checked in the compiler options, when I put in your
3 INCLUDE statements:

INCLUDE "DT_INTS-18.bas"
INCLUDE "ReEnterPBP-18.bas"
INCLUDE "Elapsed_INT.bas"

I get a compile error saying:

Error [113] c:\blue1\pbp\pbppi18l.lib 1465: Symbol not previously defined (INT_ENTRY_H)

Does that mean anything to you? No errors without those INCLUDES. No errors if I change to PBP instead of PBPL. (except my LONG variable errors, of course!)

Darrel Taylor
- 10th December 2009, 02:51
By themselves, the include files will not compile.

There must be an INT_LIST and INT_CREATE in your program.

INCLUDE "DT_INTS-18.bas"
INCLUDE "ReEnterPBP-18.bas"
INCLUDE "Elapsed_INT-18.bas" ; Elapsed Timer Routines

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

@ INT_ENABLE TMR1_INT ; Enable Timer 1 Interrupts


You'll need the -18 version of the Elapsed Timer too.
http://darreltaylor.com/DT_INTS-18/downloads.html

circuitpro
- 10th December 2009, 02:54
O. Well, u know I'm a newbie at this. sorry to bother you.

AndrewC
- 4th January 2010, 08:34
You should NOT set INTCON, PIEx, PIRx, IPRx or any other interrupt related registers manually. DT_INTS handles all of those bits for you.



So where in D_INTS do you configure if you want to trigger off a rising or falling edge for something like INT0 ?

Thanks, Andrew

Ioannis
- 4th January 2010, 09:35
This is supposed to be done in the option register, isn't it?

DT-INTS are not for settings.

Ioannis

AndrewC
- 4th January 2010, 09:47
This is supposed to be done in the option register, isn't it?

DT-INTS are not for settings.

Ioannis

See my first post - Darrel says not to set the interrupt registers manually.

Andrew

Ioannis
- 4th January 2010, 12:43
This one you should set it yourself. Otherwise how would the system know what you want?

Ioannis

Ioannis
- 7th January 2010, 10:14
WOW!

5 - 16F1937
5 - 16F1936
1 - 16F1934
Time to update DT_INTS-14. :)
<br>

Hi Darrel. Did you had any luck with these new chips?

Ioannis

Darrel Taylor
- 8th January 2010, 05:21
I have.
But they haven't been tested very thoroughly..

The update also includes every interrupt source I could find for 14-bit cores. (including F1's).

This page shows the added sources.
If you use the menu on the left, it will take you back to the old version. So don't.
http://www.darreltaylor.com/DT_INTS-14/intro2.html

Download the file at the bottom of the page. Not the one from the Download page.
DT_INTS-14 version 1.0

Woohoo! It's 1.0 finally. :)
But consider it still beta.

Ioannis
- 8th January 2010, 09:47
I like smiling faces!

Amazing! Thanks.

I have to test them on the new PICs. Wonder whenthey are coming...

Ioannis

alanmcf
- 11th January 2010, 01:28
Hey Darrel--

I've been trying to reach you re: the consulting I'd hired you to do. I've sent three emails with no response. If you need more money, I'm happy to pay it, and you also have $2200 of my company's equipment... won't you please reply to me?

Thanks--

--Alan McFarland
www.nila.tv

Darrel Taylor
- 11th January 2010, 01:47
That's just wrong, on so many levels.
I have no Public response. But I will leave this post here. :p
<br>

Nupass
- 31st January 2010, 15:33
Hi,
I want to start my home project to control ventilation fan by time period ON and time period OFF and to use LCD out for interface.
I have just started to write a code in Micro Code studio Plus v.3.0.0.5 with compiler PICBasic PRO v2.50C.

I made a starting (main) interrupt code as a basis for rest algorithm later. It is based on some desired info I have looked on the internet pages. Seems to be workable and started to compile this code. When compiling I have got some results like assembler errors as following:
Error xxx.asm 125[225] undefined symbol 'halfsec'
Error xxx.asm 126[225] undefined symbol 'halfsec'
Error xxx.asm 128[225] undefined symbol 'halfsec'
Error xxx.asm 129[225] undefined symbol 'unsec'
Error xxx.asm 137[225] undefined symbol 'interr'

As for me I can not understand those results at this stage and have no idea what was wrongin my code. Would you be so kind to look at my sourse code and help me to fix this problem in order to continue my project. Thank you inadvance and any ideas are appresiated.

Here is the code example for my project:

@ DEVICE pic16F628A, XT_OSC
@ DEVICE pic16F628A, WDT_ON
@ DEVICE pic16F628A, PWRT_ON
@ DEVICE pic16F628A, MCLR_OFF
@ DEVICE pic16F628A, BOD_ON
@ DEVICE pic16F628A, LVP_OFF
@ DEVICE pic16F628A, CPD_OFF
@ DEVICE pic16F628A, PROTECT_OFF

DEFINE OSC 4
define INTHAND Myint ' Define interrupt handler

counter var word 'to operate with unsec variable in main program

wsave var byte $20 system
ssave var byte bank0 system
psave var byte bank0 system

halfsec var byte
unsec var word
interr var byte

halfsec = 0 'clear the time variables
unsec = 0
interr = 0

INTCON = %11000000 'enable GIE and PEIE
T1CON = %00110101 'Configure TMR1 with clock/4 and prescaler 1/8
PIE1.0 = 1 'enable interrupt TMR1 overflow

goto Main ' Skip around interrupt handler

ASM ; Assembly language interrupt handler
; Save W, STATUS and PCLATH registers
Myint MOVWF wsave
SWAPF STATUS,W
CLRF STATUS
MOVWF ssave
MOVF PCLATH,W
MOVWF psave
; Interrupt code
MOVLW 221
MOVWF TMR1L
MOVLW 11
MOVWF TMR1H
BCF PIR1,0
INC halfsec
BTFSS halfsec,1
GOTO xxx
CLRF halfsec
INC unsec
; Restore PCLATH, STATUS and W registers
xxx MOVF psave,W
MOVWF PCLATH
SWAPF ssave,W
MOVWF STATUS
SWAPF wsave,F
SWAPF wsave,W
BSF interr,0 ;just a flag...
RETFIE
ENDASM

Main: 'Start of the main program

counter = unsec ' Or do something else...

goto Main ' Return to the main program
end ' End

mackrackit
- 31st January 2010, 15:44
Hi nupass,
welcome to the forum.

First, you really should start a new thread for this as it does not seem to have much to do with this one.

mark_s
- 31st January 2010, 17:04
Nupass,

Try putting under scores in front of your variable within the asm routine

halfsec var byte
unsec var word
interr var byte

Asm

_halfsec
_unsec
_interr

endasm

It's in the manual

Nupass
- 31st January 2010, 18:25
Dear Mark_S,
Thank you for your welcome, I'am appresiated.
So, I was followed by your suggestion, and put underscore at the beginning of my variables... ;)

... then ... success!!! :cool:

It is easier than to make a koffee, just you need some skills... Assembler for me it's a horroble thing...

Well, you have been very helpfull and I have learned some...
Thank you a lot ones again.

To be conitue...

younesmaia
- 6th February 2010, 14:43
Hi,

Iīm not being able to access Darrellīs website to download DT_INTS-14 (I already use INTS-18, which is great, but Iīm working on a project which runs on a 16F628A this time). Can someone please attach the latest version of both INTS-14 and INTS-18 to this thread, so people can download even if the site is down?

Thanks!

ScaleRobotics
- 6th February 2010, 15:02
Here is the latest version 1.00 of DT_INTS-14. The link is to is site, which is back up. http://www.darreltaylor.com/DT_INTS-14/NEW_DT_INTS.zip

More info on above:http://darreltaylor.com/DT_INTS-14/intro2.html
Older version of above:http://darreltaylor.com/DT_INTS-14/intro.html

and here is the latest version of DT_INTS-18 http://www.picbasic.co.uk/forum/showthread.php?p=82871
More info on DTS_INTS-18: http://darreltaylor.com/DT_INTS-18/home.html

Besides the webpages above, this post contains info about the time re-enter takes, which I did not see details of on Darrel's site.
http://www.picbasic.co.uk/forum/showthread.php?p=17587#post17587

younesmaia
- 6th February 2010, 15:04
Here is the latest version 1.00 of DT_INTS-14. The link is to is site, which is back up. http://www.darreltaylor.com/DT_INTS-14/NEW_DT_INTS.zip

More info on above:http://darreltaylor.com/DT_INTS-14/intro2.html

and here is the latest version of DT_INTS-18 http://www.picbasic.co.uk/forum/showthread.php?p=82871

Still down for me here in Brazil... Even tried do flush my DNS cache to make sure... Would you be kind enough to attach INTS-14 to your post, so I can continue working?

Thanks!

younesmaia
- 6th February 2010, 15:25
Thanks. Now only the only file I still need is elapsed_int-14. Could you please upload that one as well?

Thanks again!

ScaleRobotics
- 6th February 2010, 15:44
Now only the only file I still need is elapsed_int-14. Could you please upload that one as well?

I think the latest version of that is still this one: http://www.picbasic.co.uk/forum/showthread.php?p=17473#post17473

Michael Wakileh
- 7th February 2010, 06:11
Am I the only one confused by the "ALL_INT -- Global Interrupts" interrupt source?

Darrel Taylor
- 7th February 2010, 18:52
ALL_INT references the GIE bit (Global Interrupt Enable).
You can use it like this ...

@ INT_ENABLE ALL_INT
@ INT_DISABLE ALL_INT

Someone here wanted it, but frankly I think it's easier to just alias the bit, then do GIE = 1.

You can not assign a Handler to ALL_INT as an Interrupt Source.
<br>

ultiblade
- 11th February 2010, 10:44
Darrel,

Thanks for the DT-INTS modules, it's an awesome piece of work. It makes interrupt handling so much easier !

I found this topic because i got stuck using the DT-INTS-18 within code that i was compiling using the 8.43 version of mplab. I got the same error116 over and over again, except when i commented out DT-INTS includes and ASM piece. Microcode studio compiles the exact same code without any error ...

However removing the -K# parameter did the trick, it compiles flawless, exept for the fact that the Mplab SIM can't SIM anymore.

Did you ever discover a workaround or did you get some more info from melabs ?

Best regards,

UB

Darrel Taylor
- 11th February 2010, 18:32
Yes I did.

See this post for the MPLAB fix.
http://www.picbasic.co.uk/forum/showpost.php?p=82826&postcount=3
<br>

ultiblade
- 11th February 2010, 20:48
wohoo Darrel, Thanks !

mr.sneezy
- 19th February 2010, 02:57
I like the 683 too. If for nothing more than the CCP module. Of course the extra RAM and program space is also handy.

With the 629 only having 64 bytes of RAM,
PBP uses 24-26 bytes
and DT_INTS-14 and ReEnterPBP want 31 bytes of it (without T? vars)

Which only leaves about 6-7 bytes for the program. Not much you can do with that.

But, when using ASM interrupt handlers, DT_INTS-14 only needs 7 bytes of RAM, leaving around 38 bytes for the users program. Now that, is workable. It also uses less program space that way.

You mentioned earlier that you only needed to toggle a pin in the interrupt, so you might take a look at this page...

DT_INTS-14 (Assembly Language Interrupts)
http://www.darreltaylor.com/DT_INTS-14/asm_ints.html

The ToggleLED1: handler does just that. And if the other handlers aren't too tuff, you might still fit it in a 629.

HTH,
&nbsp; DT
Hi Darrel,
I tried this above tip to get back some RAM space to try put my old 12F683 code into a 12F629, but I get a persistent PBP error when I try to compile it.

error[101] d:temp\8chppm~3.asm 450: Error: (ReEnterPBP must be INCLUDEd to use PBP type interrupts)

I also fiddled the wsave value to get past other errors, but this one escapes me, due to not being very familiar with assembly I'd expect.

Heres my ASM code at the start of the program, what did I mess up ?
Thanks Martin

'Interrupt driven 20mS timer for PPM frame timing. See also "my_handler". Uses Timer 1 interrupts.
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, _my_handler, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
INT_ENABLE TMR1_INT ; Enable Timer 1 Interrupts

ENDASM

T1CON = $1 ; TMR1ON
'@ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts

Darrel Taylor
- 19th February 2010, 03:07
error[101] d:temp\8chppm~3.asm 450: Error: (ReEnterPBP must be INCLUDEd to use PBP type interrupts)

'INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts
\<-- commented

INT_Handler TMR1_INT, _my_handler, PBP, yes

Ahhh chuew ...

WOZZY-2010
- 19th February 2010, 03:52
Hi,

I've been trying vary to fully understand the RBC_INT interrupt handler in DT_INTS-18.pbp.

So I wrote this little program, Created a simulator circuit model and also a similar hardware circuit.

Here is the Code:

' RBC TEST.BAS
' PIC 18F6480
' MPLAB IDE V8.40
' PBP V2.60
' Build Options: [-ampasmwin]
' RB4 Momentary Contact Button Goes High on Press, 10K Resistor to Ground
' RB5 Momentary Contact Button Goes High on Press, 10K Resistor to Ground
' RB6 Momentary Contact Button Goes High on Press, 10K Resistor to Ground
' RB7 Momentary Contact Button Goes High on Press, 10K Resistor to Ground
' RC6 22K ohm to RX on 57600-N-8-1 Serial Terminal

INCLUDE "DT_INTS-18.bas" ; Include Darrel Taylor's Base Interrupt System for PIC18F [Version:3.4 (NOV 04, 2009)]

DEFINE OSC 20
DEFINE DEBUG_REG PORTC
DEFINE DEBUG_BIT 6
DEFINE DEBUG_BAUD 57600
DEFINE DEBUG_MODE 1
DEFINE SHOWDIGITAL 1

TRISB=%11111111
ADCON0=%00000000
ADCON1=%00001111

BTN VAR BYTE

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler RBC_INT, _DO_RBC_INT, ASM, yes
endm
INT_CREATE
ENDASM

@ INT_ENABLE RBC_INT

DEBUG "INTERRUPT CREATED",10,13
DEBUG "INTERRUPT ENABLED",10,13

HOLD_HERE:
DEBUG "WAITING FOR INTERRUPT",10,13
PAUSE 2500
GOTO HOLD_HERE

DO_RBC_INT
DEBUG "############### RBC INTERRUPT ACTIVATED #################",10,13

MENU:
PAUSE 200
DEBUG "MENU - READ BUTTONS",10,13
If PORTB.4 = 1 Then PAUSE 250: Goto DO_ENABLE
If PORTB.5 = 1 Then PAUSE 250: Goto DO_DISABLE
If PORTB.6 = 1 Then PAUSE 250: Goto DO_RETURN
If PORTB.7 = 1 Then PAUSE 250: Goto DO_CLEAR
GOTO MENU

DO_ENABLE:
DEBUG "RUNNING DO_ENABLE",10,13
@ INT_ENABLE RBC_INT
Pause 250
GOTO HOLD_HERE

DO_DISABLE:
DEBUG "RUNNING DO_DISABLE",10,13
@ INT_DISABLE RBC_INT
PAUSE 250
GOTO HOLD_HERE

DO_RETURN:
DEBUG "RUNNING DO_RETURN",10,13
@ INT_RETURN
PAUSE 250
GOTO HOLD_HERE

DO_CLEAR:
DEBUG "RUNNING DO_CLEAR",10,13
@ INT_CLEAR RBC_INT
PAUSE 250
GOTO HOLD_HERE

END


Here is the Circuit:
http://www.picbasic.co.uk/forum/attachment.php?attachmentid=4018&stc=1&d=1266549072

There are 4 buttons connected to PORT B <4.7>
Here are my observations:

The first press of any button activates the RBC Interrupt and sends program to DO_RBC_INT subroutine, then on to MENU where it checks for button presses. This behaves exactly as I would expect it to.

Now...After that....

Pressing Button RB.4 [ENABLE] Runs the DO_ENABLE subroutine then the HOLD_HERE subroutine. At this point, the Interrupt handler seems to shut down as no Port B inputs activate the interrupt handler. I would expect the Interrupt to remain active.

Pressing Button RB.5 [DISABLE] Runs the DO_DISABLE subroutine then the HOLD_HERE subroutine. The Interrupt handler is now disabled as expected.

Pressing Button RB.6 [RETURN] Runs the DO_RETURN subroutine then the HOLD_HERE subroutine. It then sends program to DO_RBC_INT subroutine, then on to MENU. I would expect it to return to HOLD_HERE which is wherr the interrupt was originally activated

Pressing Button RB.7 [CLEAR] Runs the DO_CLEAR subroutine. At this point, the Interrupt handler seems to shut down as no Port B inputs activate the interrupt handler. I would expect this to just clear the interrupt then await another RBC trigger.

So it seems I can only activate the interrupt one time.

It doesn't seem to matter whether I use ASM or PBP types or set Resetflag to yes, or no

Can anyone shed light on what I'm doing wrong, or am I simply misinterpreting the function of the INT_* utilities.

I'm just not sure if I've got a mistake, am staying up too late working on this stuff, or just really don't get it.

Thanks,
Bob

Darrel Taylor
- 19th February 2010, 04:29
The idea of an Interrupt, is that it Stops the normal flow of the program ... executes an Interrupt Service Routine (ISR) ... then RETURNs back to the same point it was at when it was Interrupted.

You can't go back to the Main Loop without INT_RETURN'ing.
In other words ... no GOTO HOLD_HERE.
<br>

WOZZY-2010
- 19th February 2010, 04:47
Darrel,

Thanks for the quick reply.

I made a cut & paste error in my last post.

It should have stated:
Pressing Button RB.6 [RETURN] Runs the DO_RETURN subroutine. It then sends program to DO_RBC_INT subroutine, then on to MENU. I would expect it to return to HOLD_HERE which is where the interrupt was originally activated.

Pressing Button RB.7 [CLEAR] Runs the DO_CLEAR subroutine Then the HOLD_HERE. At this point, the Interrupt handler seems to shut down as no Port B inputs activate the interrupt handler. I would expect this to just clear the interrupt then await another RBC trigger.

I agree that it should never get to the GOTO HOLD_HERE statement, at the end of DO_RETURN:, but should still end up in HOLD_HERE since that is where the program was was when the RBC_INT interrupt was initially activated.

mr.sneezy
- 19th February 2010, 08:25
error[101] d:temp\8chppm~3.asm 450: Error: (ReEnterPBP must be INCLUDEd to use PBP type interrupts)

'INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts
\<-- commented

INT_Handler TMR1_INT, _my_handler, PBP, yes

Ahhh chuew ...

Hi,
Sorry Darrel I'm even more confused from the reply. I interpreted your old post and the website info to mean that if I wasn't using PBP interrupts e.g. 'On Interrupt' that I could rem out the ReEnterPBP.bas include. I see I'm interpreting that post wrong.
Can I take that reply to mean that in this case I can't do that, or does this mean I need to write the handler in ASM ?

That's MR Ahhh Cheuw :-)

HenrikOlsson
- 19th February 2010, 16:18
Hi,
You can use Darrels routines with interrupt service routines written in assembly and/or BASIC. If the interrupt service routines you write are written in BASIC (PBP) you should declare them as type PBP in the INT_LIST AND you must INCLUDE ReEnterPBP.bas. If you write your interrupt service routines in assembly you declare them as Type ASM in in the INT_LIST and then ReEnterPBP file is NOT needed because you're not using ISR's written in BASIC. Anytime one or more of you ISR's are written in BASIC the ReEnterPBP file must be included, only when all handlers are in ASM can it be left out.

ON INTERRUPT is the compilers own way of handling interrupts and has nothing to do with DT_Ints. You use either ON INTERRUPT or Darrels routines.

/Henrik.

mr.sneezy
- 20th February 2010, 03:02
Thanks Henrik, that explanation is clear, concise, and fully understood now.

cheers,
Martin

WOZZY-2010
- 20th February 2010, 05:52
Well I think I've finally figured out some of the nuances of RBC_INT.
I think the last example I tried to use was not a very good way to test it out.

I tried to document this working code example in a way that's understandable and can be used as a template to build on.

This is setup with PBP type interrupts using ReEnterPBP-18.bas, since I'm using PBP in the Interrupt handler, but ... it seems to work just fine when run as ASM type, and not including ReEnterPBP-18.bas. You can just uncomment out the appropriate lines to suit your needs.

The thing that was giving me so much of a headache before was the need to read one of the Port B <4-7> registers prior to exiting the Interrupt handler. This ends the mismatch condition and allows the RB Port Change Interrupt Flag Bit to be cleared. Even though I was reading the Port B <4-7> registers frequently, it seems that using GOTO to enter the Interrupt handler exit subroutine, caused the Interrupt Flag Bit to reset.

Program operation:
This Program uses DEBUG to send status comments to a 9600 Buad Serial ASCII Terminal on PORTC.6
On first press of any of the PORTB<4-7> buttons, the program enters the interrupt handler.
The Interrupt Handler, continuously reads the buttons.
Buttons 1,2 & 3 just display a status message. You could put any subroutine in place of the DEBUG Statement.
Button 4 gracefully exits the interrupt handler.
At this point, RBC_INT is reset and awaiting any PORTB<4-7> button press again to reenter the Interrupt handler.


Anyway here's the Code and a schematic of the setup... I hope this helps someone who's struggling with RBC_INT like I was.
The ZIP file attachment has the code, and copies of the version of DT_INTS-18.bas and ReEnterPBP-18.bas that are included.

Bob W.


' RBC TEST.BAS
' Bob Wozniak
' PIC 18F6480 @ 20 MHZ
' MPLAB IDE V8.40 / PBP V2.60 / Build Options: [-ampasmwin]
' RB4 Momentary Contact Button Goes High on Press, 10K Resistor to Ground
' RB5 Momentary Contact Button Goes High on Press, 10K Resistor to Ground
' RB6 Momentary Contact Button Goes High on Press, 10K Resistor to Ground
' RB7 Momentary Contact Button Goes High on Press, 10K Resistor to Ground
' RC6 22K ohm to RX on 57600-N-8-1 Serial Terminal
' This program created to check Port-B Change Interrupts

INCLUDE "DT_INTS-18.bas" ; Include Darrel Taylor's Base Interrupt System for PIC18F [Version:3.4 (NOV 04, 2009)]
INCLUDE "ReEnterPBP-18.bas" ; Need to include if using PBP type interrupts

DEFINE OSC 20

DEFINE DEBUG_REG PORTC ' SETUP DEBUG to view output on 9600 BAUD ASCII Terminal on PORTC.6
DEFINE DEBUG_BIT 6
DEFINE DEBUG_BAUD 9600
DEFINE DEBUG_MODE 1

I VAR WORD
X VAR BYTE

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
; INT_Handler RBC_INT, _RBC_INT_HANDLER, ASM, no ; use for ASM type interrupts
INT_Handler RBC_INT, _RBC_INT_HANDLER, PBP, no ; use for PBP type interrupts
endm
INT_CREATE
ENDASM
@ INT_ENABLE RBC_INT



HOLD_HERE: ' **** This subrouting loops continuously and waits for button press to activate RBC interrupt handler
IF I = 0 THEN DEBUG 10,13,10,13,"HOLDING FOR PORTB <4-7> BUTTON PRESS to ACTIVATE INTERRUPT",10,13 : I = 1
PAUSE 10
GOTO HOLD_HERE



RBC_INT_HANDLER: ' **** Program jumps here when ANY PORTB.4 thru PORTB.7 are changed ****
DEBUG "############### RBC INTERRUPT ACTIVATED #################",10,13
PAUSE 250 ' This pause allows time for button debounce - needs to be here unless immediate read of interrupt button req'd


READ_BUTTONS: ' **** Program cycles reading buttons, until button 4 is pressed ****
If PORTB.4 = 1 Then DEBUG "BUTTON 1 PRESSED",10,13
If PORTB.5 = 1 Then DEBUG "BUTTON 2 PRESSED",10,13
If PORTB.6 = 1 Then DEBUG "BUTTON 3 PRESSED",10,13
If PORTB.7 = 1 Then DEBUG "BUTTON 4 PRESSED - EXITING",10,13 : I = 0 : GOTO END_RBC_INT
PAUSE 5
GOTO READ_BUTTONS


END_RBC_INT: ' **** this subroutine gracefully exits the interrupt handler and resets for next RBC event ****
PAUSE 250 ; This pause allows time for button debounce - needs to be here or interrupt will immediatly reactivate
DEBUG "################ EXITING RBC INTERRUPT HANDLER ############",10,13

X = PORTB.7 ; NOTE: Prior to returning from RBC Interrupt, you MUST read at least 1 PORTB <4-7> to end
; the mismatch condition and allow the RB Port Change Interrupt Flag Bit to be cleared.
; If not here, the interrupt will immediatly reactivate if using the GOTO END_RBC_INT statement.
@ INT_CLEAR RBC_INT
@ INT_ENABLE RBC_INT
@ INT_RETURN
END


http://www.picbasic.co.uk/forum/attachment.php?attachmentid=4024&stc=1&d=1266644561

Ioannis
- 20th February 2010, 12:32
Hi Bob.

I think you must be very quick on the 4th button to exit (less that 250ms plus the debug delay). If you hold the button longer the ISR will activate again,won't it?

Also the:

@ INT_CLEAR RBC_INT
@ INT_ENABLE RBC_INT

at the end of the ISR are not necessary as they are handled by the DT_Ints, right?

Ioannis

WOZZY-2010
- 20th February 2010, 16:23
I think you must be very quick on the 4th button to exit (less that 250ms plus the debug delay). If you hold the button longer the ISR will activate again,won't it?

Ioannis...You're right about this. the 250 mS delay is fine on the simulator, but is a little too short to be reliable with real hardware buttons. 400-600 is a better number for use on the hardware.


Also the:
@ INT_CLEAR RBC_INT
@ INT_ENABLE RBC_INT
at the end of the ISR are not necessary as they are handled by the DT_Ints, right?

Thanks for pointing this out...it seems to be somewhat dependent on the value of the DT_INT ResetFlag Here's what I found:

Disabling @ INT_CLEAR RBC_INT
ResetFlag = yes - no change to program operation
ResetFlag = no - Interrupt reactivates again immediately
So the @ INT_CLEAR RBC_INT is dependent on the ResetFlag setting

Disabling @ INT_ENABLE RBC_INT
ResetFlag = yes - no change to program operation
ResetFlag = no - no change to program operation
So the @ INT_ENABLE RBC_INT is not necessary.

I also now realize that I still haven't quite figured out the how INT_DISABLE RBC_INT effects the Interrupt handler in it's different states.

Thanks,
Bob W.

Ioannis
- 20th February 2010, 18:33
Why do you care so much about Enable/Disable flags? All these are taken care by Darrel in his routines, so normally you don't have to deal with them.

Just do as his examples show and you are OK.

In the extreme case you want some control as to when the interrupts are re-enabled, just use the @INT_ENABLE or @INT_DISABLE commands locally.

Also the simplistic debouncing of a button with time delay is not very elegant and is not recommended as it can delay the program execution.

Ioannis

WOZZY-2010
- 20th February 2010, 19:24
Ioannis,


Why do you care so much about Enable/Disable flags? All these are taken care by Darrel in his routines, so normally you don't have to deal with them.

I'm really just trying to fully understand this particular interrupt. It's a good learning exercise for me before I go on to other interrupts. I am learning that Darrel's routines are actually much easier to use and sensible than I thought, before I thoroughly confused myself by looking at it in this much detail.


Also the simplistic debouncing of a button with time delay is not very elegant and is not recommended as it can delay the program execution.

As I'm really pretty new to this, I'd be very interested to know what is your recommendation for debouncing. Are you talking about a hardware, or a software solution?

For my current application, the interrupt is just used to jump out of the main program to enter a set up menu. So the main program is on hold and nothing is time critical. This whole RBC_INT study is just a tangent that I went off on, when I didn't understand why the stuff that I had cut & paste from the examples didn't behave as I expected.

Thanks again,
Bob W.

Ioannis
- 20th February 2010, 21:33
Well, the idea is to use the interrupts, both with Port Interrupt on Change and Timer.

On the first interrupt from your button, you start the timer. If you have multiple interrupts from the same button and the timer stil runs, just drop them.

If the timer interrupt occurs, and the button is still pressed, then you can confirm that is really pressed, setting a flag.

Hope this helps a little.

Ioannis

vamtbrider
- 25th March 2010, 19:16
I have a small test board that has an ICSP and a USB connection to a pic 18f4550. I have a reset button on the MCLR and a second button on portb.1. An led is connected to portb.0

The ICSP is used to program a bootloader onto the chip. Then USB is used to add the user program.

I have loaded the Diolan bootloader (http://www.diolan.com/pic/bootloader_dwn.html) onto this chip and it is working.

I can make a test program in PBP 2.6 that flashes the LED on port b.0
like this: The Bootloader required code to start at 0x800


DEFINE OSC 48
DEFINE RESET_ORG 0x800
' Example program to blink an LED connected to PORTB.0 about
' once a second

Main:
High 0 ' Turn on LED connected to PORTB.0
Pause 500 ' Delay for .5 seconds

Low 0 ' Turn off LED connected to PORTB.0
Pause 500 ' Delay for .5 seconds

Goto Main ' Go back to loop and blink LED forever
End

The above program works as expected. So the next step was to try the DT_INTS-18 with the bootloader...the code appears to load into the PIC fine, but after reset there is a pause of about 5 seconds then the chip shows up as an un-recognized USB device but does not enter the bootloader mode. To enter bootloader mode the PB on portb.1 is held down during power-on/reset. OR the user application can branch to 0x0016.

It appears the program is branching somewhere to restart the bootloader code since the pic shows up as an unrecognized USB device. It should not show up at all after the code is loaded since I don't have any usb code in the user app listed below.

Here is my test program with the DT_INTS-18 that is not working...

DEFINE OSC 20
DEFINE RESET_ORG 0x800

INCLUDE "DT_INTS-18.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP-18.bas" ' Include if using PBP interrupts

LED1 VAR PORTB.0

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

T1CON = $31 ; Prescaler = 8, TMR1ON
@ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts

Main:
PAUSE 1
GOTO Main

'---[TMR1 - interrupt handler]--------------------------------------------------
ToggleLED1:
TOGGLE LED1
@ INT_RETURN


Any thoughts on why it's not blinking the led using the DT_INTS-18 code and running off into la la land?

ADDED: I am using the MPASM assembler as well.

Thanks
Tom

Bruce
- 25th March 2010, 20:26
Does it work if you disable A/D on RB0?

vamtbrider
- 25th March 2010, 21:00
I added the port configuration and acon register configs. That has an effect...
The bootloader never leaves the bootloader mode to run the user app.

if I comment out the Hardware configuration section and compile I can load the code via the bootloader, the device disappears from the USB list and then ~10seconds later I get the USB device not recognized.

I have reloaded the led test program just to make sure the bootloader and chip are still working and they are. Very puzzling, but the registers do seem to have an effect.

Nothing in the DT_INT writes to EEPROM 0x00? If there is a 5A there then the bootloader thinks its still in boot mode.


LED1 VAR PORTB.0

DEFINE OSC 20
DEFINE RESET_ORG 0x800

INCLUDE "DT_INTS-18.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP-18.bas" ' Include if using PBP interrupts

' Hardware configuration
' ======================
'
' I/O and PORTs
' -------------
PORTB = 0
PORTC = 0
PORTD = 0
PORTE = 0
TRISB = %00000000 '<2-1> Inputs
TRISC = 0
TRISA = 0
TRISD = 0
TRISE = 0
'
' A/D converter
' -------------
ADCON0 = %00000000 ' A/D converter off
ADCON1 = %00001111 ' All Digital Inputs
' ADCON2 = %00000000



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




T1CON = $31 ; Prescaler = 8, TMR1ON
@ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts

Main:
Pause 10
GOTO Main

'---[TMR1 - interrupt handler]--------------------------------------------------
ToggleLED1:
TOGGLE LED1
@ INT_RETURN


Still puzzled...

vamtbrider
- 25th March 2010, 21:13
This hardware config give the same results as the original issue...ie the LED does not blink and the code appears to run off into la la land. Not sure how it is being detected as a usb device with the DT_INTS-18 code.



' Hardware configuration
' ======================
'
' I/O and PORTs
' -------------
PORTB = 0
PORTC = 0
PORTD = 0
PORTE = 0
TRISB = %11111110 '<7:1> Inputs
TRISC = 0
TRISA = 0
TRISD = 0
TRISE = 0
'
' A/D converter
' -------------
ADCON0 = %00000000 ' A/D converter off
ADCON1 = %00001111 ' All Digital Inputs
ADCON2 = %00000000

I have two port b pins connected together as part of the ICSP and 2 others connected for inputs off a single PB. Setting the TRISB to FE is what got me back to the original problem.

Bruce
- 25th March 2010, 21:15
I've never used this loader, but I did take a quick peek at the source files.

Try this;


DEFINE OSC 20
DEFINE RESET_ORG 0x800

INCLUDE "DT_INTS-18.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP-18.bas" ' Include if using PBP interrupts

LED1 VAR PORTB.0

' Hardware configuration
' ======================
ADCON1 = %00001111 ' All Digital Inputs


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


T1CON = $31 ; Prescaler = 8, TMR1ON
@ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts

Main:
Pause 10
GOTO Main

'---[TMR1 - interrupt handler]--------------------------------------------------
ToggleLED1:
TOGGLE LED1
@ INT_RETURN
Remove power. Place a jumper from PORTE.0 to ground. Power up & load the above after compiling it.

After programming it with the loader, power down. Move the jumper on PORTE.0 to Vcc, and power up.

Does it work now?

vamtbrider
- 25th March 2010, 21:47
If I don't have the TRISB config the bootloader never enters the user program mode.

I added the TRISB = %1111110 and it enters the user program but still shows an undetected USB device after a few seconds and the LED on PORTB.0 is still not blinking.

One more piece of info, I am getting power from the USB port on my laptop. Even though the user program is not using USB I am "stealing" power for this test setup from the USB port. i.e. I download the program to the bootloader through the PIC USB and leave the cable connected to power the board for testing.

It doesn't look like anything in the DT_INTS would be triggered from activity on the USB port since I have not explicitly configured the USB_INT. The PIC is certainly seeing a request from the PC since its connected to the PIC circuitry and that could be why I get the USB device not recognized...although I don't get that when i am running just the Blink program using PAUSE 500 statements.

When I get home later tonight I will load this program directly on the PIC through the ICSP without the bootloader to verify my setup is happy. Then I will try the bootloader again and use an external power supply instead of the USB power.

ADDED: I have reconfigured the Bootloader to use PORT B.1 instead of Diolan's default of PortE.0. My end application will use Port B.1 so I built this test board assuming portb.1 would work.

Darrel Taylor
- 25th March 2010, 22:16
Try adding ...

DEFINE LOADER_USED 1

Bruce
- 26th March 2010, 00:53
Pheeeewwww! I do NOT like that loader at all.

I put one together for you here using the Microchip USB HID boot-loader. Give this one a shot. It works 100% with DT_INTS-18.

I modified the original C18 loader file so you can switch between the external crystal & internal osc at run-time to switch back-and-forth to various speeds.

Use a 20MHz crystal, 18F4550, and you should have no problems at all with the loader or DT_INTS-18.

Of course you'll need to download & install the Microchip HID USB loader PC app, but I find that one WAY nicer, and easier to use than the Diolan thing.


'************************************************* ***************
'* Name : USB_TST.BAS *
'* Author : B. Reynolds *
'* Notice : Copyright (c) 2010 http://www.Rentron.com *
'* : All Rights Reserved *
'* Date : 3/25/2010 *
'* Version : 1.0 *
'* Notes : Using the Microchip USB HID Boot-Loader with PBP *
'* : and DT_INTS. *
'************************************************* ***************

' Using the Microchip MCHPFSUSB v2.1 HID USB Bootloader with PBP & DT INTS.

' Place a 10K pull-up on RB4 with a switch to ground RB4 when pressed.

' Loader mode. Press & hold switch on RB4, then press/release reset switch on /MCLR.
' Now release switch on RB4.

' LEDs on PORTD.0 & D.1 will blink on/off quickly showiing you're in loader mode
' and the MCHPFSUSB v2.1 HID PC bootloader software should now recognize your board.

' Open & load your compiled code, with the loader software, then press/release
' the switch on /MCLR, or click Reset Device on the loader software.

' Your code should now be running.

DEFINE OSC 48 ' Loader configured for 20MHz OSC on USB board
DEFINE RESET_ORG 0x1000 ' User code start location for HID loader

INCLUDE "DT_INTS-18.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP-18.bas" ' Include if using PBP interrupts

LED1 VAR PORTD.0
Loops VAR BYTE

' Hardware configuration
' ======================
ADCON1 = %00001111 ' All Digital


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


T1CON = $31 ; Prescaler = 8, TMR1ON
@ INT_ENABLE TMR1_INT ; Enable Timer 1 interrupts

OSCCON = %01110000 ; Switch to internal whenever you want by just
; flipping OSCCON.1 to 1.
; To run at 48MHz, flip OSCCON.1 back to 0..
Main:
FOR Loops = 1 TO 6 ' we'll run at 48MHz here
TOGGLE PORTD.1
Pause 500
NEXT Loops

OSCCON.1 = 1 ' we'll run at 8MHz on internal osc here
FOR Loops = 1 TO 6
TOGGLE PORTD.1
Pause 500
NEXT Loops

OSCCON.1 = 0 ' flip switch back to 48MHz
GOTO Main

'---[TMR1 - interrupt handler]--------------------------------------------------
ToggleLED1:
TOGGLE LED1
@ INT_RETURN

END

Some day when I have time I might figure the other one out, but this took a fraction of the time to change & test.

vamtbrider
- 26th March 2010, 06:37
I think I have two problems.

One the jumper for bootloader mode is a PB that will tie portb.1 and 2 to ground when pressed. Walking through the bootloader code with the MPLAB debugger the portb inputs are not always on. Some times they are and sometimes they are not. I enabled the pull ups through the INCON2<7> but that doesn't seem to help. So I need to figure that out first.

A few times I have been able to get the DT_INTS-18 code with the blinky light to load into the PIC via the bootloader while still in debug mode in MPLABS. This has lead to the second problem.

When the interrupt comes in the code jumps to 0x008 which has a GOTO 0x808.
At 0x808 is another GOTO 0x998

running through the interrupt eventually gets to the code below:


1122 08C2 C017 MOVFF usb_sm_state, 0x90
1123 08C4 F090 NOP
1124 08C6 C018 MOVFF usb_sm_ctrl_state, 0x91
1125 08C8 F091 NOP
1126 08CA C019 MOVFF usb_active_cfg, 0x92
1127 08CC F092 NOP
1128 08CE C01A MOVFF usb_alt_intf, 0x93
1129 08D0 F093 NOP
1130 08D2 8022 BSF [0x22], 0
1131 08D4 B414 BTFSC [0x14], 0x2
1132 08D6 EF74 GOTO 0x8e8
1133 08D8 F004 NOP
1134 08DA C021 MOVFF 0x21, PCLATU
1135 08DC FFFB NOP
1136 08DE C020 MOVFF 0x20, PCLATH
1137 08E0 FFFA NOP
1138 08E2 501F MOVF [0x1f], W
1139 08E4 6AE0 CLRF BSR, ACCESS
1140 08E6 6EF9 MOVWF PCL, ACCESS
1141 08E8 C01E MOVFF pSrc, PCLATU
1142 08EA FFFB NOP
1143 08EC C01D MOVFF 0x1d, PCLATH
1144 08EE FFFA NOP
1145 08F0 501C MOVF [0x1c], W
1146 08F2 6AE0 CLRF BSR, ACCESS
1147 08F4 6EF9 MOVWF PCL, ACCESS
1148 08F6 0004 CLRWDT
1149 08F8 A022 BTFSS [0x22], 0
1150 08FA EFB4 GOTO 0x968

the program resets after executing the instruction at 08F4 - MOVWF PCL, ACCESS. It looks like the WREG has a value of 0xDC that it is trying to stuff into PCL.

Basically the debugger stops stepping at that line, I click on the next line below it and select run to cursor the code restarts at 0x00. The bootloader checks the jumper, which is not there and then runs the app.

So basically it looks like the code keeps running to the first interrupt and then resetting the PIC.


I have attached a capture of the PIC Program Memory for what its worth.


I also loaded just the DT_INTS blinky light program onto the PIC without the bootloader. Using the MPLABS debugger i am able to see that when the code gets to the MOVWF PCL, ACCESS instruction it moves 0x34 from WREG into the PCL and the program jumps to 0x0234. The code at 0x0234 looks like the TOGGLELED1: code to actually toggle port b.0.
The code runs great without the bootloader.

Comparing the two pieces of code it looks like the bootloader version should be branching to 0x9DC...but instead I think its running off the stack and resetting the PIC.

I am now going to try and reload the DT_INTS with the bootloader and see if I can capture the PCL, PCLATH and PCLATU registers when the code attempts to move 0xDC into PCL. Hopefully I can see where it is really trying to go.

Its kind of late here in VA so I may have to tackle this tomorrow night.

Thanks for all the ideas so far.
Tom

vamtbrider
- 26th March 2010, 07:27
Ok, it looks like the code is trying to goto 0xa34 in the attached file.
It gets to 0x091C - MOVWF PCL, ACCESS and resets the PIC.

Here are the values for PC:

Update Address Symbol Name Value Binary Char

FE8 WREG 0x34 00110100 '4'
FF9 PCL 0x1C 00011100 '.'
FF9 PCLAT 0x0A341C 00001010 00110100 00011100 '.4.'
FFA PCLATH 0x34 00110100 '4'
FFB PCLATU 0x0A 00001010 '.'

The code should be going to 0x0A34 but instead resets...It never actually moves the 0x34 from Wreg into the PCL.

Any thoughts?

Thanks
Tom

Bruce
- 26th March 2010, 07:45
With the Diolan USB loader;

I would contact the author of your loader for help. His loader has extended instruction set enabled, and I don't think you're going to get PBP working on it with this enabled.

If you're having problems with the Microchip HID loader I posted, it's something specific to your setup. It works rock-solid on the Microchip PICDEM FS USB board I tested it on.

vamtbrider
- 26th March 2010, 16:06
I will have to explore the Microchip bootloader a little more. I strayed away from it because I think it requires a .dll and I wanted a usb bootloader that would work with the standard microsoft drivers. The Diolan also uses encryption which is a very nice feature and the code size is slightly smaller.

Plus I like a challenge...maybe if I can get this working it will give others another option for bootloaders and DT_INTS.

So, on to what I have found today.

From section 26.2.4 of the 18f4550 manual:


Additionally, the Indexed Literal Offset Addressing
mode may create issues with legacy applications
written to the PIC18 assembler. This is because
instructions in the legacy code may attempt to address
registers in the Access Bank below 5Fh. Since these
addresses are interpreted as literal offsets to FSR2
when the instruction set extension is enabled, the
application may read or write to the wrong data
addresses.

If I look at the .LST file for the blinky led program I see this:

00037 FLAGS EQU RAM_START + 000h
00000001 00038 GOP EQU RAM_START + 001h
00000002 00039 R4 EQU RAM_START + 002h
00000004 00040 R5 EQU RAM_START + 004h
00000006 00041 R6 EQU RAM_START + 006h
00000008 00042 R7 EQU RAM_START + 008h
0000000A 00043 R8 EQU RAM_START + 00Ah
0000000C 00044 INT_Flags EQU RAM_START + 00Ch
0000000D 00045 RM1 EQU RAM_START + 00Dh
0000000E 00046 RM2 EQU RAM_START + 00Eh
0000000F 00047 RR1 EQU RAM_START + 00Fh
00000010 00048 RR2 EQU RAM_START + 010h
00000011 00049 RS1 EQU RAM_START + 011h
00000012 00050 RS2 EQU RAM_START + 012h
00000013 00051 wsave EQU RAM_START + 013h
00000014 00052 RetAddrH EQU RAM_START + 014h
00000017 00053 RetAddrL EQU RAM_START + 017h

Looking at the 2nd Capture.txt file I attached yesterday there are lots of MOVWF statements that reference the RAM areas above which are in RAM at locations under 0x5F.

So a statement like MOVWF [0x14] is really MOVWF [FSR2+0x14] with the extended instruction enabled. This may then explain why the code jumps off into la la land and resets.

I did not think to capture FSR2 last night during my debugging. I will do that tonight and see if it matches my theory. If it does then I think I will try to change the RAM_START to 0x060 so that the extended instruction engine will not use the FSR2 on the Ram addresses.

Am I on the right path?

ScaleRobotics
- 26th March 2010, 17:38
I will have to explore the Microchip bootloader a little more. I strayed away from it because I think it requires a .dll and I wanted a usb bootloader that would work with the standard microsoft drivers.

I think there are two usb bootloaders from microchip. One is a HID Bootloader. I don't think it requires any dll's. It is located inside the huge files that you download as a group. Once all the Microchip Application Libraries v2010-02-09 is installed, the .hex file is located here: C:\Microchip Solutions\USB Device - Bootloaders\HID - Bootloader

I believe you can just bring the hidbootloader exe to a different computer, and program over the usb. But I have not fully tried it yet. I have only got to the point where my chip was regognized by a computer that has never had any microchip software loaded on it.

I need to try the executeable.

vamtbrider
- 26th March 2010, 18:08
The Diolan bootloader works as a HID USB device and my end app will eventually be a HID devices as well. If I get time this weekend I will try the Microchip HID bootloader, as Bruce indicated that maybe the more solid solution.

I am looking at changing the statement in MPASM P18F4550.inc from


ACCESS EQU 0

to


ACCESS EQU 1

This will allow the RAM definitions to stay the same and get past the extended instruction issues with f<0x5F. The draw back will be a lot of BSR changes. We'll see how that works out.

Bruce
- 26th March 2010, 18:16
The major issue you have with the Diolan loader is that it has Enhanced CPU mode
enabled. I.E. XINST = ON.

So code compiled with PBP simply is not compatible, and will not run on the PIC as
expected unless you disable Enhanced CPU mode.

Here's a simple example you can try. Make sure you set XINST = OFF, then run this;



MyVar VAR WORD
LED VAR PORTD.0

Loops:
FOR MyVar = 0 TO 100
High LED
GOSUB BLINK

Low LED
GOSUB BLINK
NEXT MyVar

Goto Loops

BLINK:
PAUSE 200
RETURN

End
Now run the exact same code, but set XINST = ON and give it a whirl.

Once you flip that switch to enable Enhanced CPU mode, ALL your code needs to be using
the extended instruction set. Try it with ACCESS EQU 1 as well. Still no go.

vamtbrider
- 29th March 2010, 14:40
What I found interesting is that PicBasicPro compiles this code correctly for XINT on. Using brackets and leaving out the access parameter for addresses under 0x5F.

The blinky light code I originally posted now runs fine with the Diolan bootloader. The trick I found was to clear the FSR2L and FSR2H registers as the first instructions in my program. I also set Access equ 1.

I think the main issue was that I never initialized the FSR2 register to zero in my code. The Diolan bootloader uses FSR2 and it could have any value in it when the app code runs.

Since that is the register used for indexed addressing when XINST is on it must be set to zero to allow legacy code to run. Setting FSR2 to zero places the access bank and SFR's in memory just as if XINST was 0. I found this info in the data sheet. Had to read it about 10 times to make sure I was following it correctly.

The next challenge I am working on is to get the USB interrupts working with DT_INTS and the Diolan Bootloader. The USB_DEV.ASM and USB_HID.ASM use FSR2/INDF2 for indirect addressing and as a general register in several routines. Those will need to be modified to use FSR0/1 and INDF0/1 instead.

Ioannis
- 20th April 2010, 13:59
OK. I am pulling my hair off. Cannot think what might be wrong here.

I get errors like Found label after column 1 (INT_CREATE) or Illegal opcode (RBC_INT) or Address label duplicated in second pass (INT_RETURN).

The PICŪ is F819, with DT-INTS-14 and MPASM of course. Also commented the confg line in the *.inc file as it can be seen on the attached files.

Ioannis

Bruce
- 20th April 2010, 14:45
Did you forget these?

INCLUDE "DT_INTS-14.bas"
INCLUDE "ReEnterPBP.bas"

Ioannis
- 20th April 2010, 16:07
No Bruce. They are in pbp directory and the project too.

It is not the first time I use these excellent routines.

That is why I post here. I am almost driving myself in the la-la land with this!

Ioannis

Bruce
- 20th April 2010, 16:13
Hi Ioannis,

Strange. It compiles fine for me. Tried it with the old & new versions of DT_INTS!

ScaleRobotics
- 20th April 2010, 16:24
Did you forget these?

INCLUDE "DT_INTS-14.bas"
INCLUDE "ReEnterPBP.bas"

Compiles here as well, but I do get the same errors IF I leave the above lines out of the code. Are you sure the include lines are in your water?

Acetronics2
- 20th April 2010, 16:31
Hi, Ioannis

Compiles fine adding ...



@ __CONFIG _LVP_OFF & _BODEN_ON & _CP_ALL & _MCLR_OFF & _PWRTE_ON & _WDT_ON & _INTRC_IO


to the top of your code ...

and



'************************************************* ****************************
'Includes
'************************************************* ****************************

INCLUDE "DT_INTS-14.bas"
INCLUDE "ReEnterPBP.bas"

'------------- INTERRUPTS SETUP ---------------------
ASM
INT_LIST macro; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, _timer, PBP, yes
INT_Handler RBC_INT, _in_triger, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM


just BEFORE the Interrupts setup ... ( why ??? good question !!!)

It DIDN'T Compile placed at the top of program ... that's it

- also think to uncomment Wsave, Wsave1 .... etc. in DT INTs listing ....



Alain

Ioannis
- 20th April 2010, 17:25
Alain, there is no problem here where the lines of includes are placed. Either on the very top or just before the macros... Are you sure about that?

Ioannis

Acetronics2
- 20th April 2010, 19:55
Alain, there is no problem here where the lines of includes are placed. Either on the very top or just before the macros... Are you sure about that?

Ioannis

Hi,

Yess .. I'm pretty sure !!!

I had an error raising ( Vars_Saved not defined ... but it was correctly defined in the listing ) .

but now I've also uncommented Wsaves and compiler has compiled fine once ... no more compiler errors appears, whatever line the "includes" are placed ...

a bit strange, but not the first strange thing I see with MCS ...

Alain

Ioannis
- 20th April 2010, 20:25
Have tried to compile from command line and it went OK?

Ioannis

comwarrior
- 5th May 2010, 13:02
I'm looking at a possible necessity to need to upgrade to PIC24's and above...
I use DT INST INT's with my PIC16's and PIC18's however it would be a royal pain to have to write my own interrupt system for PIC24's and above...

Is their any work being done on DT Ints at the moment?
Is their any plans for DT Int's?
Anyone working on DT int's in a team?

Thanks

bcd
- 5th May 2010, 14:02
I have done a lot of work on the PIC24F series using MikroElektronika dsPIC Basic compiler, and have had no issues with Interrupt or having to implement a DT_INT style system. Interrupts are handed well in the compiler, which I think is due to the way the improved architecture handles them. One you try the Peripheral Pin mapping in the 24 series its hard to go back !

The only issue I had was changing my coding style after years of working with PBP ! I still use PBP for all my 16F and 18F stuff, so don't shoot me down for promoting other peoples products !

Bill.

wjsmarine
- 7th May 2010, 18:53
Hi Folks,

I don't have a lot of experience with using DT's Int's (thank you Darrel!) and had no problems until recently needing to selectively Disable them...

I have an application measuring wind which requires a rolling (3 x 1 second) update easily taken care of by a For Next loop. At any time a master logger can interrogate this separate wind acquisition unit and request the processed data, but I want the ISR to only occur at the end of the loop so the math can complete as a set.

The abbreviated code below shows what I am using but I have no Int's when the @ INT_DISABLE INT_INT is inserted. With this removed I do have them but immediately following the Debug data sent from within the ISR the remaining T loop count completes before Clearing and restarting i.e math is performed and data is sent from an incomplete routine.



16F88, PBP 2.60, MPASM 5.20

Include "MODEDEFS.BAS" ' Include Shiftin/out modes
Include "DT_INTS-14.bas" ' Darrel's routines.
Include "ReEnterPBP.bas" ' Only needed if Pbp Interrupts used.

Define LCD_DREG PORTB ' Port for LCD Data.
Define LCD_DBIT 4 ' Use upper 4 bits of Port.
Define LCD_RSREG PORTA ' Port for RegisterSelect (RS) bit.
Define LCD_RSBIT 7 ' Port Pin for RS bit.
Define LCD_EREG PORTA ' Port for Enable (E) bit.
Define LCD_EBIT 6 ' Port Pin for E bit.
Define LCD_BITS 4 ' Using 4-bit bus.
Define LCD_LINES 2 ' Using 2 line Display.
Define LCD_COMMANDUS 2000 ' Command Delay (uS).
Define LCD_DATAUS 50 ' Data Delay (uS).

DEFINE DEBUG_REG PORTB ' Debug pin port
DEFINE DEBUG_BIT 1 ' Debug pin bit
DEFINE DEBUG_BAUD 9600 ' Debug baud rate
DEFINE DEBUG_MODE 1 ' Debug mode: 0 = True, 1 = Inverted

DEFINE ADC_BITS 10 ' Set number of bits in result
DEFINE ADC_CLOCK 3 ' Set clock source (rc = 3)
DEFINE ADC_SAMPLEUS 50 ' Set sampling time in microseconds

' DEFINE OSC 8 ' Needed if oscon set for 8Mhz.
' OSCCON = %01110010 ' 8Mhz (F88).

OPTION_REG.6=0 ' 0=Falling-Edge Trigger.
OSCCON = %01100010 ' 4Mhz (F88).
TRISA = %00101111 ' A.5 Set, A.3 WD2, A.2 WS2, A.1 WD1, A.0 WS1.
TRISB = %00001101 ' B.3 -, B.2 +, B.0 Sin.
ANSEL = %00001010 ' PORTA.1,3 analog, remainder digital (F88).
ADCON0 = %11001101 ' Set A/D to Frc, Channel 1, On (F88).
ADCON1 = %10000000 ' R justify (where the 6 MSB of ADRESH read as 0 i.e. 10 bit), Vdd for Vref.
CMCON = 7 ' Comparators off.
pause 100 ' Let everything settle...
RedLED = 0 ' Red LED Off.
clear
debug 10,13,"I'm Alive!",10,13 '

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler INT_INT, _MyInt, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
'@ INT_ENABLE INT_INT ; enable external (INT) interrupts (enabled further down).

GOTO Satu ' Jump over the subroutines area.

' Subroutines here in the first page...

' Program area...
Satu: ' Operation when system first powered up.

Running: ' Normal running routine.
if x=1 then ' Returning from 1Min Rollover or Interrupt.
gosub ResetAll ' Start fresh count - Clear and reset all.
gosub Read_offsets ' Retrieve stored values.
endif '

@ INT_DISABLE INT_INT ; No Ints during the For/Next loop - ensures complete set for math.
for T = 0 to 2 ' 3 event sliding window.
gosub Blinky ' LED shows sampling.
gosub Get_revs ' Run the count routine.
ch = 1 ' Second channel for direction 1 (ch0 for S1).
gosub Get_Dirn ' Read the realtime direction.
LCDOUT $FE,$CF,Dec T ' Second line, last position - indicates present count.

' This section averages the speed of the latest three samples i.e. derives Gust.
' This section deals with Wind Direction.
' Get instant Wind Direction value.
' Update Max and Min Direction
' Update Sigma Theta
' 1min period report.
if Wsmpls=60 then '
debug 10,10,13,"S1i ",#S1i,", S1x ",#S1x,", Gu1x ",#Gu1x,", Gu1av ",#Gu1av,13,10,_
"AD ",#AD_res,", WD1av ",#WD1d,", Max ",#D1x,", Min ",#D1n,", ST1av ",#ST1av,10,10,13 ' ****
x=1
goto Running ' Reset all and start again.
endif

Continue:
pause z ' This plus sensor 1 count period should equal 1 second
next ' Back to loop testing.
@ INT_ENABLE INT_INT ; enable external (INT) interrupts only after For/Next loop is completed.
goto Running ' Repeat the whole cycle.

'---[INT - interrupt handler]---------------------------------------------------
MyInt:
toggle RedLED ' Blink the LED on interrupt.
' Report the Av wind speed, Maximum Gust, Maximum Speed, Av dirn and Sigma Theta since last interrupt.
debug 10,13,dec3 S1av,".",dec1 S1avr,",",dec3 Gu1x,",",dec3 S1x,",",dec3 WD1d,",",dec3 ST1,13,10
LCDOUT $FE,$C0,"Data out, Reset!" ' Second line.
pause 1000 ' Time enough to read.
x=1 ' Flag the interrupt.
@ INT_RETURN ; Return to point of Interrupt and resume.


Can anyone offer some advice or point out where I am going wrong please?

Thanks and regards to all,
Bill

Darrel Taylor
- 7th May 2010, 20:16
Hi Bill,

Are you using version 1.00 of DT_INTS-14.
http://www.darreltaylor.com/DT_INTS-14/intro2.html (bottom of page)

If so, try adding this define ...
DEFINE INT_ENABLECLEARFIRST 0

By default, the INT_ENABLE command clears the flag first before enabling.
So, if there is an interrupt pending, it will be discarded.

Adding the define tells it to NOT clear the flag first.
It's only available in the 1.00 version.

hth,

wjsmarine
- 7th May 2010, 21:15
Hi Darrel,

Thanks for your help.

I am using ver 1.00 and added the new Define per your instructions - same result (no Int's).

It compiles without errors (as before) and runs correctly in all other respects apart from an Interrupt taking place no matter how many times I trigger (or even hold the pin low).

I'm not desperate for the fix so if it's not convenient for you I can wait, no problem.

Kind regards,
Bill

Darrel Taylor
- 7th May 2010, 21:37
When I fixed your
tags, something stuck out.

The INT_CREATE line is in column 1.
Is it like that in your program?
It should be indented.
<br>

wjsmarine
- 8th May 2010, 05:44
Hi Darrel,

I don't know how that wasn't indented... anyway it made no difference.

I also added


debug "x=",#INTCON.7,13,10

in there to see if the GIE was being set - it was. Still no INT's.

I may go back to blinky and add small sections one at a time to get my mind around this.

Thanks and regards,
Bill

Darrel Taylor
- 8th May 2010, 23:08
Don't know why it's not working for you. I can't run it in ISIS cause there's too much missing.

But I think this is one of those instances where you don't really need interrupts to do what you want.

The INTF flag will be set when the INT input is triggered, whether you are using interrupts or not. And it stays latched until cleared in software.

So at the end of your loop, after the FOR/NEXT, just check the INTF flag and if it's set, call the subroutine, and clear the flag before returning. No interrupts needed.

hth,

wjsmarine
- 9th May 2010, 19:05
Hi Darrel,

Yes, it helped a lot - thank you.

It is now fully functional and exactly what I want. Certainly was a case of me trying to over-engineer the requirement and overlooking the obvious, no interrupts needed only a check of the appropriate flag, as you diagnosed.

I learnt a few things on the way - bonus! I expect your DT_INTS will now be a large part of my projects in future, I see how they can make things so much more efficient.

Thanks again and best regards,
Bill

Darrel Taylor
- 9th May 2010, 22:32
i learnt a few things on the way - bonus!
SWEET!


i expect your dt_ints will now be a large part of my projects in future, i see how they can make things so much more efficient.
&nbsp;SWEET--ER! :D

Cheers,
&nbsp; &nbsp; DT

Squibcakes
- 27th May 2010, 00:57
Darrel,

What I have is a timer1 servicing an interrupt every 10msec and a Usart RX interrupt when ever data comes in. Problem is that when the pic is off dealing with the usart interrupt, my timer1 is ignored until the usart interrupt is finished.

Do you have a low priority interrupt version for 14Bit pics? eg ReEnterPBP-14LP.bas
This could be the answer to my problem...



Squib

Darrel Taylor
- 27th May 2010, 01:35
Nope.
The ability to have Low Priority interrupts depends on the hardware, and 14-bit cores don't have it.

I would suspect that you are using the RX interrupt to start reading a long string of bytes using HSERIN in the handler.
If so, then it's sitting in the handler doing nothing while waiting for data to come in.

For best speed, an RX interrupt should only retrieve 1 byte at a time, then exit the handler.
It only takes a few uS that way.

Squibcakes
- 28th May 2010, 07:47
Nope.
For best speed, an RX interrupt should only retrieve 1 byte at a time, then exit the handler.
It only takes a few uS that way.

I'm waiting for a string of NMEA chars to arrive into a huge data array.

I'm not quite sure how to code the above interrupt process into a [wait(" "),data] style command. This is what I am using at the moment when the RX_INT interrupt fires....



WAIT_GLL:
HSERIN 100,WAIT_GLL,[WAIT("GLL"), STR DATAIN\40\13]


If I receive each byte and then do some byte checks to simulate the above syntax will the pic be fast enough to catch the sentance when it actually arrives or is the a better way?
Squib

Darrel Taylor
- 30th May 2010, 18:44
Squib,

Sorry, I was trying to see if I could finish an NMEA sentence parser I've been toying with.
But there's too much left to do. :o

Are you only looking at the GLL sentence?

My RX_INT handler for it is double buffered, so it can work on one sentence while receiving another.
If it's only looking for the GLL sentence, it won't need the double buffer.

Squibcakes
- 9th June 2010, 00:26
Squib,
My RX_INT handler for it is double buffered, so it can work on one sentence while receiving another.


Hi DT,

Is that in the current version of inst_ints or the one your working on now?

I got my progy working by using the @ INT_DISABLE RX_INT command in the handler but is that really kosha or just sloppy programming? ;-)

Yes I'm just looking for the one nea sentance at this time.

ScaleRobotics
- 14th July 2010, 22:05
Is there a way to use an assembly lookup table from within a DT INTS ASM interupt? When I try, the interrupt locks up on me. If I comment out the CALL SineTable, all is fine. I have tried it a few different ways, but no go so far.



INCLUDE "DT_INTS-18.bas" ; Base Interrupt System
LOW LED1
high led2
ASM

INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, ToggleLED1, ASM, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM

T1CON = $31 ; Prescaler = 8, TMR1ON
@ INT_ENABLE TMR1_INT ; Enable Timer 1 Interrupts

Main:
@ NOP
GOTO Main

'---[TMR1_INT - interrupt handler]------------------------------------------
ASM

ToggleLED1
btg _LED1 ; toggle the pin
btg _LED2
StepLoop
movf _STEPCOUNT,W ; Pass table offset via W
call SineTable ; Get table value
movwf CCPR1L
decfsz _STEPCOUNT,F ; Next step
goto $+6
movlw d'32'
movwf _STEPCOUNT ;_STEPCOUNT ; Load counter for 32 steps
NOP
NOP
NOP
NOP
INT_RETURN
SineTable
addwf WREG ;added for pic18f each address is 16 bits
addwf PCL,F
retlw d'0' ; Dummy table value
retlw d'128' ; 0 degree, 2.5 volt
retlw d'148'
retlw d'167'
retlw d'185'
retlw d'200'
retlw d'213'
retlw d'222'
retlw d'228'
retlw d'230' ; 90 degree, 4.5 volt
retlw d'228'
retlw d'222'
retlw d'213'
retlw d'200'
retlw d'185'
retlw d'167'
retlw d'148'
retlw d'128' ; 180 degree, 2.5 volt
retlw d'108'
retlw d'89'
retlw d'71'
retlw d'56'
retlw d'43'
retlw d'34'
retlw d'28'
retlw d'26' ; 270 degree, 0.5 volt
retlw d'28'
retlw d'34'
retlw d'43'
retlw d'56'
retlw d'71'
retlw d'89'
retlw d'108'
ENDASM

Darrel Taylor
- 14th July 2010, 23:12
You should be able to do that.

But I think you need to initialize the STEPCOUNT variable, or put a CLEAR at the top.
If it powers up with a value higher than 32, the table jump will throw it outside of the interrupt code.

hth,

ScaleRobotics
- 14th July 2010, 23:28
Thanks for the help Darrel.

I will look into it further. I had initialized stepcount to 32, then later to 8. Seems to get stuck after about two flashes of the led's.

Walter

Darrel Taylor
- 15th July 2010, 00:22
Maybe you need to set PCLATH before changing PCL?

Bruce
- 15th July 2010, 22:22
Walter,

Try this. It gives you a lot smaller table by packing two bytes into each word space. If you stick with the RETLW approach just uncomment the addwf WREG.



ASM
SineTable
movlw UPPER Table1
movwf TBLPTRU
movlw HIGH Table1
movwf TBLPTRH
movlw LOW Table1
movwf TBLPTRL
movf _STEPCOUNT,W
;addwf WREG ; uncomment only if using RETLW tables VS db
addwf TBLPTRL
TBLRD*
movf TABLAT, W
return

Table1
db 0,128,148,167,185,200,213,222,228,230,228,222,213, 200,185,167
db 148,128,180,108,89,71,56,43,34,28,26,28,34,43,56,7 1,89,108
ENDASM

circuitpro
- 3rd September 2010, 05:01
I've been trying to use DT_INTS-14 with a 16F877A. I'm getting errors when trying to compile. Code is as follows:

DEFINE OSC 4

'Define LCD registers and bits
Define LCD_DREG PORTD
Define LCD_DBIT 4
Define LCD_RSREG PORTE
Define LCD_RSBIT 0
Define LCD_EREG PORTE
Define LCD_EBIT 1

'OPTION_REG.6 = 0
OPTION_REG.7=0 'ENABLE PORTB PULLUPS
ADCON1 = 7
Low PORTE.2
Pause 100

'INCLUDE FILES FOR DT INTERRUPTS
INCLUDE "DT_INTS-14.bas"
INCLUDE "ReEnterPBP.bas"

X VAR BYTE
Y VAR BYTE
Z VAR BYTE
COUNTER VAR BYTE
TAG VAR BYTE[26]

INIT:
'INITIALIZE INTERRUPTS
ASM
INT_LIST macro ;IntSource,Label,Type,ResetFlag?
INT_Handler RBC_INT, _BChange, PBP, yes
endm
INT_CREATE
ENDASM

@ INT_ENABLE RBC_INT

START:
COUNTER=0

MAIN:
IF COUNTER=>26 THEN
LCDOUT $FE,1,"COUNTER: ",DEC COUNTER
LCDOUT $FE,$C0,STR TAG\15
COUNTER=0
ENDIF
GOTO MAIN

BChange:
COUNTER=COUNTER+1
IF PORTB.0=0 THEN
TAG[COUNTER]=0
ENDIF
IF PORTB.1=0 THEN
TAG[COUNTER]=1
ENDIF
@ INT_RETURN


The errors I'm getting are:
Error [113] c:(path)pbppic14.lib 1181: Symbol not previously defined (wsave)
Error [101] c:(path)code\lab-x1.asm 194: Error: (wsave variable not found,)
Error [101] c:(path)code\lab-x1.asm 258: Error: (" Add:" wsave VAR BYTE $70 SYSTEM)
Error [101] c:(path)code\lab-x1.asm 315: Error: (Chip has RAM in BANK1, but wsave1 was not found.)
etc
etc

Can somebody tell me what's wrong?

Thanks

ScaleRobotics
- 3rd September 2010, 06:00
Yes, it is asking you to change the include file here:



wsave VAR BYTE $20 SYSTEM ' location for W if in bank0
;wsave VAR BYTE $70 SYSTEM ' alternate save location for W
' if using $70, comment out wsave1-3

' --- IF any of these three lines cause an error ?? ----------------------------
' Comment them out to fix the problem ----
' -- It depends on which Chip you are using, as to which variables are needed --
wsave1 VAR BYTE $A0 SYSTEM ' location for W if in bank1
wsave2 VAR BYTE $120 SYSTEM ' location for W if in bank2
wsave3 VAR BYTE $1A0 SYSTEM ' location for W if in bank3
It needs to be adjusted for a few different chips. Comment out the wsave at $20, and uncomment the wsave at $70, and try commenting out the wsave1-3.

circuitpro
- 3rd September 2010, 20:25
scalerobotics - Thanks very much.

HankMcSpank
- 12th September 2010, 17:15
Just wondering if doing something like this is a 'no no' wrt to the interrupt handlers...




CPM1_Interrupt_Handler:

@ INT_DISABLE CMP1_INT
[do some stuff here]
@ INT_ENABLE CMP2_INT

@ INT_RETURN


CPM2_Interrupt_Handler:

@ INT_DISABLE CMP2_INT
[do some stuff here]
@ INT_ENABLE CMP1_INT

@ INT_RETURN


....essentially 'toggling' between each comparator being 'interrupt' enabled (& where the other comparator enables/disables itself & its partner). I'm getting weird results, but that's probably cos the rest of my code isn't robust :D - but just wanted to establish if it's ok to do this (especially if the comparators are interrupting rapidly due to them both rx'ing a rapidly changing input - and also each comparator potentially interrupting very closely in time)

Also, not having a clue about this kinda stuff, just wondering what's going on 'under the hood' so to speak....ie when an interrupt enable &/or disable is actioned as per the above? (does enabling/disabling in such a manner use a lot of processor clock cycles? Or is it pretty swift?)

Thanks.

Darrel Taylor
- 12th September 2010, 21:33
Nothing wrong there.

There are two different actions that can change the way INT_ENABLE works with version 1.10.

DEFINE INT_ENABLECLEARFIRST 1 ; (default)
With the above define, which is also the default, whenever you INT_ENABLE, the flag is automatically cleared before the interrupt is enabled.

DEFINE INT_ENABLECLEARFIRST 0
Whith this define, the flag is NOT cleared.
This can dramatically change the results and cause immediate interrupts if the flag is already set.

If INT_ENABLECLEARFIRST is 0, then INT_ENABLE takes one instruction cycle.
If INT_ENABLECLEARFIRST is 1, then INT_ENABLE takes two instruction cycles.

INT_DISABLE always takes one instruction.

reik6149
- 13th September 2010, 04:29
hi all, i face a problem here.

why when im trying to compile the dt_ints-18 file without changing anything, it shows

Error[113] c:\picbas~1.47\pbppic18.lib 1170 : symbol not previously defined (int_entry_H)

im using 18f2680

Ioannis
- 13th September 2010, 07:36
I suppose you did commend the 4 lines starting with __CONFIG in the xxx.inc file inside your PBP directory, right?

Ioannis

reik6149
- 13th September 2010, 08:00
huh?? do you means 18f2680.inc ? but i dint change anything with it..below is the inc file



;************************************************* ***************
;* 18F2680.INC *
;* *
;* By : Leonard Zerman, Jeff Schmoyer *
;* Notice : Copyright (c) 2006 microEngineering Labs, Inc. *
;* All Rights Reserved *
;* Date : 06/05/06 *
;* Version : 2.47 *
;* Notes : *
;************************************************* ***************
NOLIST
ifdef PM_USED
LIST
"Error: PM does not support this device. Use MPASM."
NOLIST
else
LIST
LIST p = 18F2680, r = dec, w = -311, w = -230, f = inhx32
INCLUDE "P18F2680.INC" ; MPASM Header
__CONFIG _CONFIG1H, _OSC_XT_1H
__CONFIG _CONFIG2H, _WDT_ON_2H & _WDTPS_512_2H
__CONFIG _CONFIG3H, _MCLRE_ON_3H & _PBADEN_OFF_3H
__CONFIG _CONFIG4L, _XINST_OFF_4L & _LVP_OFF_4L
NOLIST
endif
LIST
EEPROM_START EQU 0F00000h
BLOCK_SIZE EQU 64

ScaleRobotics
- 13th September 2010, 08:19
hi all, i face a problem here.

why when im trying to compile the dt_ints-18 file without changing anything, it shows

Error[113] c:\picbas~1.47\pbppic18.lib 1170 : symbol not previously defined (int_entry_H)

im using 18f2680

It's not really clear, but it sounds like you might be trying to compile the include file, rather than including it in your code. You are supposed to compile something like this:



LED1 VAR PORTB.1

INCLUDE "DT_INTS-18.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP-18.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 = $31 ; Prescaler = 8, TMR1ON
@ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts

Main:
PAUSE 1
GOTO Main

'---[TMR1 - interrupt handler]--------------------------------------------------
ToggleLED1:
TOGGLE LED1
@ INT_RETURN

reik6149
- 13th September 2010, 08:22
yea !! it works !!!! thank you very much ! im too busy body and trying to compile the file each of it.zzzz

HankMcSpank
- 13th September 2010, 11:41
Nothing wrong there.

There are two different actions that can change the way INT_ENABLE works with version 1.10.

DEFINE INT_ENABLECLEARFIRST 1 ; (default)
With the above define, which is also the default, whenever you INT_ENABLE, the flag is automatically cleared before the interrupt is enabled.

DEFINE INT_ENABLECLEARFIRST 0
Whith this define, the flag is NOT cleared.
This can dramatically change the results and cause immediate interrupts if the flag is already set.

If INT_ENABLECLEARFIRST is 0, then INT_ENABLE takes one instruction cycle.
If INT_ENABLECLEARFIRST is 1, then INT_ENABLE takes two instruction cycles.

INT_DISABLE always takes one instruction.


thanks for the clarification Darrel!

I look forward to the day where I don't have to read something 10 times ...and still not be 100% sure what it means! Until then please humour me - I'm using V1.1 of your interrupts ...when you mention the default is for your code to clear any interrupt flag (ie prior to enabling) , but then I got confused when seeing this accompanying snippet....

DEFINE INT_ENABLECLEARFIRST 1 ; (default)

So, Pop quiz, should I....

a) should I be putting such a line at the top of my program?
B) modifying DT_INTS-14.BAS?
c None of the above (it's erhm..... done by default!)

thanks!

reik6149
- 13th September 2010, 12:15
finally i could done with the code, hereby special thanks to darrel taylor and scalerobotics !!!:D

Ioannis
- 15th September 2010, 17:35
I downloaded the latest version 1.10 for the DT-INTS14 and now I get a lot of errors.

Does anyone else has the same problem? With v1.0 had no error (but nothing was working either.... :( )

I want to use IOC of a F887 device.

The test code is this:



DEFINE OSC 4

;----- Configuration bits ------------------------------------------------
@Line1 = _DEBUG_OFF & _LVP_OFF & _FCMEN_OFF & _IESO_OFF & _BOR_OFF
@Line2 = _CP_OFF & _MCLRE_ON & _PWRTE_ON & _WDT_ON & _XT_OSC

@ __CONFIG _CONFIG1, Line1 & Line2
@ __CONFIG _CONFIG2, _WRT_HALF & _BOR40V

OPTION_REG.0=1 'PSA0 PRESCALER SELECT 1:1 TO 1:256
OPTION_REG.1=1 'PSA1
OPTION_REG.2=1 'PSA2
OPTION_REG.3=1 'PRESCALER TO: 1->WDT, 0->TMR0
OPTION_REG.4=0 'T0SE SOURCE EDGE 1->H TO L, 0->L TO H
OPTION_REG.5=0 'T0CS 1->FROM RA4, 0->FROM INT. CLOCK
OPTION_REG.6=0 'INT EDGE SELECT 0->H TO L, 1->L TO H
OPTION_REG.7=0 'PULL UP 1->DISABLE, 0->ENABLE

adcon0=%01000001 '0 off
adcon1=$80'6 off (all digitals)
ansel=$01
anselh=$00

PORTA=%00000001:PORTB=%00010000:PORTC=%10000001:PO RTD=0:PORTE=0

TRISC=$80:TRISD=0:TRISE=0

TRISA = %00000001:TRISB = %00010000

WPUB=%00010000 'Enable weak pull up on PortB.4

while 1
wend

ASM
INT_LIST macro; IntSource, Label, Type, ResetFlag?
INT_Handler RBC_INT, _IOC2, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM

@ INT_ENABLE RBC_INT ; Enable Port B on change
'------------- INTERRUPTS SETUP ---------------------

IOC2:
if portb.4=1 then
high portb.0
else
low portb.0
endif
@ INT_RETURN


The errors are like ERROR: (" Add:" wsave1 VAR BYTE $A0 SYSTEM, Or change to wsave BYTE $70 SYSTEM)

or

ERROR: (Chip has RAM in BANK3, but wsave3 was not found.) etc

Ioannis

Darrel Taylor
- 15th September 2010, 18:28
Everyone seems to do that.....

What you need to do is contained in the error messages.
Follow the directions, and they will go away.

Ioannis
- 15th September 2010, 18:42
Sorry I did not fully understood what you mean...

With the old (version 1.00) there is no problem in compiling with RBC_INT interrupt. With 1.10 I get various errors like the ones posted.

Of course I made a mistake in interrupt selection. IOC_INT should be used and not RBC_INT.

With the old version 1.00, after compiling I get

ERROR: ("INT_Handler" - Interrupt Flag (INTCON,IOCIF ) not found.)

and

ERROR: ("INT_ENABLE" - Interrupt Flag (INTCON,IOCIF ) not found.)

Ioannis

ScaleRobotics
- 15th September 2010, 19:24
Hey Iannis,

This may be a dumb question, but are you including the includes? I don't see them in your code.

if you are getting the wsave, wsave1, wsave2, or wsave3 errors, change the wsave settings in the DT_INTS-14.bas, like it shows you.

Ioannis
- 15th September 2010, 19:29
Hi. Yes I did included them. The sample was stripped down from the obvious.

Well, the new DT-INTs have changed a little I suppose.

OK, Darrel pointed what to do. I did uncomment the wsave1,2,3 lines and put on the main program the lines:



wsave VAR BYTE $20 SYSTEM ' location for W if in bank0
;wsave VAR BYTE $70 SYSTEM ' alternate save location for W
' if using $70, comment wsave1-3


It seems that it doesn't matter which one I un-comment as it compiles both.

But with version 1.10 of the DT-INTs I have a new error about the INTCON,IOCIF flag...

Ioannis

ScaleRobotics
- 15th September 2010, 19:44
Your code compiles here without errors. PBP 2.60A

Ioannis
- 15th September 2010, 19:53
DT-INTS version 1.00 or 1.10?

Ioannis

ScaleRobotics
- 15th September 2010, 20:03
I used DT-INTS 1.10 on a 16f887

Ioannis
- 15th September 2010, 20:38
When compiling the attached file I get the attached error.

It drives me crazy....

Ioannis

aratti
- 15th September 2010, 21:18
Hi Ioannis, you cannot use the wsave variable outside the DT interrupt since such a variable is in use within the routine.



wsave VAR BYTE $20 SYSTEM ' location for W if in bank0
;wsave VAR BYTE $70 SYSTEM ' alternate save location for W
' if using $70, comment wsave1-3
clear
INCLUDE "c:\projects\picdem2\DT_INTS-14.bas"
INCLUDE "c:\projects\picdem2\ReEnterPBP.bas"



You have to comment/uncomment the variable within DT int routine.

Al.

ScaleRobotics
- 15th September 2010, 21:19
Are you still compiling for a 16f887? Because that chip doesn't even have a IOCIF. I think only the 16f1827's and such have one of those. So that is pretty weird.

Darrel Taylor
- 15th September 2010, 21:28
For a 16F887, it's RBC_INT.
You can tell that from the datasheet which specifies "PORTB change" interrupts.

And with DT_INTS-14 you'll see some comments in the file ...

;-- Place a copy of these variables in your Main program -------------------
;-- The compiler will tell you which lines to un-comment --
;-- Do Not un-comment these lines --
;---------------------------------------------------------------------------
;wsave VAR BYTE $20 SYSTEM ' location for W if in bank0
;wsave VAR BYTE $70 SYSTEM ' alternate save location for W
' if using $70, comment wsave1-3

' --- IF any of these three lines cause an error ?? ------------------------
' Comment them out to fix the problem ----
' -- Which variables are needed, depends on the Chip you are using --
;wsave1 VAR BYTE $A0 SYSTEM ' location for W if in bank1
;wsave2 VAR BYTE $120 SYSTEM ' location for W if in bank2
;wsave3 VAR BYTE $1A0 SYSTEM ' location for W if in bank3
' --------------------------------------------------------------------------

The idea is that wsave variables should be in your main program.
The old way, when you compile for a different chip, it may not have had the correct variables, and it would not have warned you.

Now it will always tell you when the wrong variables are commented.
And you can just change them in your code, and NEVER have to edit DT_INTS-14.

Some people get carried away with the editing and screw everything up.
Now there's NO REASON to edit DT_INTS-14

ScaleRobotics
- 15th September 2010, 22:30
Your code compiles here without errors. PBP 2.60A

To be clearer, your code in post 609 compiles using the code shown. I had not tried it with the IOC_INT, only with the code listed in post 609. I guess you meant that when you changed it to IOC, you got the errors.....

Sorry

Walter

Ioannis
- 15th September 2010, 23:13
Thanks all for the support.

Al.: We are testing the new DT-INTs version 1.10. Here as Darrel pointed out the wsave are set in the main program.

Darrel: You are correct in the Port change Interrupts. Ok, I have them corrected and the two errors went away. But no joy on Interrupts. It seems that they are never triggered.

The latest test code is this:



DEFINE OSC 4

@Line1 = _DEBUG_OFF & _LVP_OFF & _FCMEN_OFF & _IESO_OFF & _BOR_OFF
@Line2 = _CP_OFF & _MCLRE_ON & _PWRTE_ON & _WDT_ON & _XT_OSC

@ __CONFIG _CONFIG1, Line1 & Line2

@ __CONFIG _CONFIG2, _WRT_HALF & _BOR40V

OPTION_REG.0=1 'PSA0 PRESCALER SELECT 1:1 TO 1:256
OPTION_REG.1=1 'PSA1
OPTION_REG.2=1 'PSA2
OPTION_REG.3=1 'PRESCALER TO: 1->WDT, 0->TMR0
OPTION_REG.4=0 'T0SE SOURCE EDGE 1->H TO L, 0->L TO H
OPTION_REG.5=0 'T0CS 1->FROM RA4, 0->FROM INT. CLOCK
OPTION_REG.6=0 'INT EDGE SELECT 0->H TO L, 1->L TO H
OPTION_REG.7=0 'PULL UP 1->DISABLE, 0->ENABLE

adcon0=%01000000 '0 off
adcon1=$80'6 off (all digitals)
ansel=$01
anselh=$00

PORTA=%00000001:PORTB=%00010000:PORTC=%10000001:PO RTD=0:PORTE=0

TRISC=$80:TRISD=0:TRISE=0

TRISA = %00000001

TRISB = %00010000

wsave VAR BYTE $20 SYSTEM ' location for W if in bank0
;wsave VAR BYTE $70 SYSTEM ' alternate save location for W
' if using $70, comment wsave1-3
clear
INCLUDE "c:\projects\picdem2\DT_INTS-14.bas"
INCLUDE "c:\projects\picdem2\ReEnterPBP.bas"

'------------- VARIABLES ---------------------

code_in var portb.4

'------------- VARIABLES ----------------------

t1con=%00000000 '65,535ms interrupt time base

clear
goto main

'------------- INTERRUPTS SETUP ---------------------

IOCB=%00010000 'Enable IOC on PortB.4
WPUB=%00010000 'Enable weak pull up on PortB.4

ASM
INT_LIST macro; IntSource, Label, Type, ResetFlag?
INT_Handler RBC_INT, _IOC2, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM

@ INT_ENABLE RBC_INT ; Enable Port B on change

'------------- INTERRUPTS SETUP ---------------------

IOC2:
if code_in then
high portb.0
else
low portb.0
endif
@ INT_RETURN


main:
while 1
toggle portb.2
pause 100
wend

End


Ioannis

Darrel Taylor
- 16th September 2010, 01:29
Ioannis,

Remove the second CLEAR statement, and move the GOTO Main after the interrupt declaration, just before the IOC2: handler.

The interrupt declaration and the IOCB/WPUB must be allowed to execute.

Ioannis
- 16th September 2010, 08:57
Hi Darrel.

Well, with 3 toddlers running around till 10.30 pm sure I will have double CLEAR commands to clear my mind!

OK I moved the IOCB/WPUB before GOTO main but still no Interrupts occur.

In fact is second or third try with different controller that I cannot make an interrupt on change to work... Not lucky I guess.

The latest test code is this:



t1con=%00000000 '65,535ms interrupt time base
IOCB=%00010000 'Enable IOC on PortB.4
WPUB=%00010000 'Enable weak pull up on PortB.4

goto main

'------------- INTERRUPTS SETUP ---------------------
ASM
INT_LIST macro; IntSource, Label, Type, ResetFlag?
INT_Handler RBC_INT, _IOC2, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM

@ INT_ENABLE RBC_INT ; Enable Port B on change
'------------- INTERRUPTS SETUP ---------------------

IOC2:
high portb.1
if portb.4 then
high portb.0
else
low portb.0
endif
@ INT_RETURN


main:
while 1
toggle portb.2
pause 1000
wend


Thanks for the efforts.

Ioannis

Ioannis
- 16th September 2010, 09:39
OK. I got it. Was the goto main before Interrupt setup.

Sorry for my careless... A cupof coffee did the job!

Ioannis

HankMcSpank
- 21st September 2010, 16:57
I'm needing to use DIV32 in my program, this from the compiler manual...

"...blah, blah, blah...........ON INTERRUPT must be
DISABLEd from before the multiply until after the DIV32. If ON
INTERRUPT is not used, there is no need to add DISABLE to the
program. Interrupts in assembler should have no effect on the internal
variables so they may be used without regard to DIV32."

Now I'm blissfully unaware how DT's interrupts work 'under the hood' ...so could someone put a layman's spin on whether DT's interrupts are "interrupts in Assembler" (& therefore whether I'm free to use DIV32or not?)

Thanks.

Darrel Taylor
- 21st September 2010, 17:34
DIV32 only has a problem with ON INTERRUPT.

ASM interrupts and DT_INTS has no problem with it.

HankMcSpank
- 21st September 2010, 21:00
DIV32 only has a problem with ON INTERRUPT.

ASM interrupts and DT_INTS has no problem with it.

Excellent news....and thanks for the quick response (I'm off to divide 2147483647 by 32767 .....just because)

mark_s
- 24th September 2010, 16:23
Hello,

I was trying to experiment with HankMcSpank's comparator interupt code. But am having problems getting it to compile.

I am using,
PIC18f4480
PBP 2.60A
DT_INT-18 3.3
ReEnter-18 v?
MPASM 5.2

It is giving me "missing argument", Interupt(FlagReg,Flagbit) not found etc
Error ("Int_handler"..... Error (Int_Enable

If anyone has any ideas, I would be greatfull.

Thanks

Darrel Taylor
- 24th September 2010, 17:52
The 18F4480 only has 1 interrupt flag for both comparators.

You would use CMP_INT, then check the C1OUT/C2OUT bits in CMCON to determine which one triggered the interrupt.

mark_s
- 24th September 2010, 18:45
The 18F4480 only has 1 interrupt flag for both comparators.

You would use CMP_INT, then check the C1OUT/C2OUT bits in CMCON to determine which one triggered the interrupt.

Thank you, Darrel!

Had the same issue with the PIC16f877A- Will revisit tonight.

HankMcSpank
- 25th September 2010, 13:44
Hello,

I was trying to experiment with HankMcSpank's comparator interupt code.


Be warned...it's still very much a work in progress, I've just revisited this one & noticed a whopping proble. On the basis that a picture is worth a thousand words, I just posted up a youtube video, which illustrates my last remaining problem - there appears to be bit of an ssue measuring smaller phase shifts...

Have a look at my video on this thread...

http://www.picbasic.co.uk/forum/showthread.php?t=13690&p=94382#post94382

mark_s
- 25th September 2010, 18:32
Be warned...it's still very much a work in progress, I've just revisited this one & noticed a whopping proble. On the basis that a picture is worth a thousand words, I just posted up a youtube video, which illustrates my last remaining problem - there appears to be bit of an ssue measuring smaller phase shifts...

Have a look at my video on this thread...

http://www.picbasic.co.uk/forum/showthread.php?t=13690&p=94382#post94382

Hank,

I got my code working last night , thanks to Darrel. The pic chips I am using only have one comparator interupt. By reading the output bits on each comparator and putting an IF statement in the ISR, I can read the frequency and phase like your code. My test so far is with a fixed 180 deg. I need to wire up a variable phase shifter, so that I can compare my results with yours. Not sure why you can't read below 33 deg? Maybe phase locking between the two comparators or interupt house keeping? What happens if you halve the frequency?

HankMcSpank
- 25th September 2010, 18:59
Hank,

I need to wire up a variable phase shifter, so that I can compare my results with yours. Not sure why you can't read below 33 deg? Maybe phase locking between the two comparators or interupt house keeping? What happens if you halve the frequency?

It all works well above a certain phase shift (depending on the signal frequency)...just when you get to the lower regions that this quirk kicks in.

I'm sure you're sorted for a phase shift cct, there's a simple one here....

http://www.werewoolf.org.je/graphics/apf1.gif

....make R1 & R2 the same value -I used 10k - the cap about 100nf & R4 a 10k pot (wired with the wiper to the ground end)....this gives about 90 degrees of phase shift @ 159Hz...if you want more phase shift,cascade a few together & use this designer http://www.aleph.co.jp/~takeda/radio/psDesigner.swf

just be sure that the signals into your PIC comparator are identical (I square them up first - remember ...different edge 'slopes' equals different triggering points for the PIC comparators which translates into a phase measurement error - and I also check on a scope to make sure there aren't any edge timing errors intrduced prior to the PIC)

If I half the incoming frequency (or double it), the Comp2 count remains the same (ie it won't go below 336, as I phase shift to the lower regions)...so I'm inclined to think it's housekeeping 'can't avoid' timing issue of some sort.

there maybe one fly in my particular ointment - my PIC supply is 4V...the datasheet says that 4.5V is the minimum when using a 20Mhz External clock. (& annoyingly, I don't appear have any 5V regulators handy so now looking at dropping the clock back to 8Mhz)

I look forward to your results so get a move on!

mark_s
- 25th September 2010, 20:52
If I half the incoming frequency (or double it), the Comp2 count remains the same (ie it won't go below 336, as I phase shift to the lower regions)...so I'm inclined to think it's housekeeping 'can't avoid' timing issue of some sort.

there maybe one fly in my particular ointment - my PIC supply is 4V...the datasheet says that 4.5V is the minimum when using a 20Mhz External clock. (& annoyingly, I don't appear have any 5V regulators handy so now looking at dropping the clock back to 8Mhz)


Thats strange that halving the frequency does not change the minimum phase reading. The interupt process of saving and restorring variables should take the same amount of time weather your input frequency is 1hz or 1khz. So halving your frequency, should double your count on tmr1 while the interupt processing time remains constant. As a ratio, the lower the input frequency, the less effect processing delays have on your final value.

Example
Input 500Hz = 2ms or 5.5us/deg with a 33 degree lag = 183us

Then at 250Hz = 4ms or 11.1us/deg with a 33 degree lag = 366us

So for argument sake, lets say it takes minimum of 183us to process the interupt (not likely). If
we plug this into the 250hz case, we get 183us/11.1us or a minimum of 16.4 degrees.

I think there is something else going on, 183us is a long time. The power supply is pretty important and could cause havic in the analog circuits (Vref) if not regulated. If you're feelin lucky you can get 5v regulated off your USB port.

HankMcSpank
- 25th September 2010, 21:08
Thats strange that halving the frequency does not change the minimum phase reading. The interupt process of saving and restorring variables should take the same amount of time weather your input frequency is 1hz or 1khz. So halving your frequency, should double your count on tmr1 while the interupt processing time remains constant. As a ratio, the lower the input frequency, the less effect processing delays have on your final value.

Example
Input 500Hz = 2ms or 5.5us/deg with a 33 degree lag = 183us

Then at 250Hz = 4ms or 11.1us/deg with a 33 degree lag = 366us

So for argument sake, lets say it takes minimum of 183us to process the interupt (not likely). If
we plug this into the 250hz case, we get 183us/11.1us or a minimum of 16.4 degrees.

I think there is something else going on, 183us is a long time. The power supply is pretty important and could cause havoc in the analog circuits (Vref) if not regulated. If you're feelin lucky you can get 5v regulated off your USB port.


We're straying off (probably better to visit the ongoing related thread - http://www.picbasic.co.uk/forum/showthread.php?t=13690), but just to clarify....I'm not even calculating phase wrt to this specific problem (other than on a spreadsheet)...this is more to do with an apparent timing overhead/problem, where once comp1 interrupt has finished, it takes a minimum count of 336 clocks (@20mhz Osc) to store the comp2 timer1 count.

Sequence is...
comp1 interrupts - (timer1 was reset earlier and is therefore is already at zero)
comp1 interrupts again (timer1 value is stored, timer 1 is cleared)
comp2 interrupts - timer1 value is stored into another variable & is used against the above to glean the delay - ie phase shift.(it's this one that won't go below 336 - whatever audio frequency I'm feeding in)


Since comp2 count time won't go below a count of 336 - @ 500hz, that represents the first 12 degrees of phase shift not being 'capturable'. If I take the frequency up to 1.4kz...once again, I cant get the comp2 count down below 336 - but now, this represents something nearer the first 32 degrees of phase shift not being capturable.

It's plausible that the vcc is to blame but in such a scenario, I would have expected the comp1 interrupt count to be all over the place (& comp2's count too!)... I more wonder that when comp2 interrupts if there isn't some delay going on, eg while it parks up some registers (housekeeping) prior to actually doing what's being asked of it in the interrupt handler? I know the pic comparators are firing right (cos I presented the output of both PIC comparators on a physical output pin - they scoped the same as the inputs looked)...so IMHO, this has something to do with the internal PIC proceedings ....or the way I'm approaching this, hence posting my interrupts on the related thread (incidentally, such is the sensitivity of the timings, I'm not able to do much else in those interrupt handlers..else the counts go bananas! It's literally get in, store to a variable , get out asap! I'm only wanting to measure up to 1.4khz...which equates to a waveform cycle period of 700us - a veritable eon in processing time?!)

I guess I'll have to mull learning a little more about assembly?

edit: It couldn't be the hserout bogging the interrupts down could it? That's a fair amount of text being piped down a 9600 line, so I'd imagine there'll be some associated USART registers to store away with each and every frequent interrupt!? (but how else can I see what the timer1 count numbers going on inside the pic are?!)

retepsnikrep
- 20th October 2010, 05:23
This is my first try with DT interrupts to implement a 4hz timer ticks.

I'm probably being a bit thick but do the instant interrupts preserve all the variables and return to exactly the same place in program after execution?

Also i have some serin2 code that i don't want interrupting, i can't find the command that enables/disables the interrupts temporarily?



SERIN2 Bcm, 8276, 250, Main, [WAIT($87), STR BCM87\11] 'Receive $87 (12) byte data packet on BCM Bus


I don't want the above interrupted. ? Thanks

Darrel Taylor
- 20th October 2010, 05:38
I'm probably being a bit thick but do the instant interrupts preserve all the variables and return to exactly the same place in program after execution?Yes it does.


Also i have some serin2 code that i don't want interrupting, i can't find the command that enables/disables the interrupts temporarily?



INTCON.7 = 0
SERIN2 Bcm, 8276, 250, Main, [WAIT($87), STR BCM87\11] 'Receive $87 (12) byte data packet on BCM Bus
INTCON.7 = 1


But that will throw off your 4hz timing.

If possible, use the USART with HSERIN, and you won't need to disable anything.

retepsnikrep
- 20th October 2010, 06:12
I think i'll have to go back to something which leaves the timer running in the background i can poll the timer overflow flag and just count 4 ticks myself. Hmm?

Does your intcon just stop/start the timer?

I can't use hserin as chip is 12F683

Darrel Taylor
- 20th October 2010, 06:39
Polling the timer won't help, since it's the time it takes to execute the SERIN2 statement that causes the delay in responding to and reloading the timer. It can't do anything else until that statement is finished, and with a WAIT() in there, who knows how long it will take.

And INTCON.7 is the GIE bit (Global Interrupt Enable).
Setting it to 0 disables ALL interrupts, but does not affect the timer other than delaying the Interrupt Service Routine (ISR), which needs to reload the time to keep it accurate.

Depending on what your 4hz interrupt is doing, ... you may not need to worry about it interrupting the SERIN2. If the ISR is fast enough, it won't cause a problem.

ScaleRobotics
- 13th November 2010, 20:28
Hey Darrel, I have a question about N-Bit math as it relates to DT_INTS ASM type interrupt.

Would the ASM part of the N-Bit Math qualify as an assembly interrupt? for instance, can I do math like this in the middle of an asm type interrupt handler, without having to worry? I am not really talking about this code (your degree conversion example) but doing math like this inside an assembly interrupt handler. Or since it is using an include file, I have to worry?



ASM
MOVE?WP _degree_Total, _Temp1 ; copy degrees to a PVAR
MOVE?CP 65535, _Temp2 ; put multiplier in a PVAR
MATH_MUL _Temp1, _Temp2, _Temp1 ; Temp1 = DEG * 65535
MOVE?CP 35999, _Temp2
MATH_DIV _Temp1, _Temp2, _Temp1 ; Temp1 = Temp1 / 35999 (16-bit result)
MOVE?PP _Temp1, _Temp2 ; copy result to Temp2
MATH_ROR _Temp2 ; rotate right 4 times
MATH_ROR _Temp2
MATH_ROR _Temp2
MATH_ROR _Temp2 ; Temp2 is now 12-bits
MOVE?PW _Temp1, _Decimal_value_16bit ; copy PVAR's to WORDs
MOVE?PW _Temp2, _Decimal_value_12bit
ENDASM


Thanks,

Walter

Darrel Taylor
- 13th November 2010, 20:35
> Would the ASM part of the N-Bit Math qualify as an assembly interrupt?
Absolutely!

The math routines don't use any of PBP system variables.
But they do use an FSR, so that must be saved/restored at the beginning/end of the ISR.

There are two macro's included in N-Bit_Math that do the FSR save/restore ...

@ FSRSAVE
; -- math code here --
@ FSRREST

ADD: DT_INTS already saves/restores the FSR's, so if you're using DT_INTS, there's nothing to worry about.

hth,

ScaleRobotics
- 13th November 2010, 20:43
That is awesome, just opened a ton of possibilities with the speed of ASM, and the ease of DT_INTS and N-Bit Math. Thanks Darrel!

HankMcSpank
- 21st November 2010, 02:03
Just a quickie, re IOC interrupts....how do I know which one to use? (previously I was using IOC with a 16f690 & used RABC_INT then, but the PIC I'm using now doesn't have a PORT B)

From DT's site...

Several new interrupt sources have been added in version 1.00. GPC_INT, IOC_INT, RAC_INT, RABC_INT and the original RBC_INT are all forms of Port Change Interrupts. The chip being programmed determines which one you need to use.

Where do I look to establish this info?

I'm using one of the newer 14 pin 16F1823 PICs.

Darrel Taylor
- 21st November 2010, 02:25
The key is to look in the INTCON register.

For the 16F690, INTCON.0 is RABIF. So you would use RABC_INT.

With the 16F1823, INTCON.0 is IOCIF, so it's IOC_INT.

I could probably make it so IOC_INT works for all of them. :rolleyes:
They are all "Interrupt On Change".

HankMcSpank
- 21st November 2010, 17:08
Many thanks Darrel.

I have a problemetette - my program runs fine, but then when I press a switch (to generate an IOC), an interrupt *is* triggered, but it then seems to loop in my interrupt handler (it's actually becuase the INTCON.0 bit seems to be staying at 1, which keeps it jumping to the interrupt handler constantly)

Any ideas, why the IOC_FLAG = 0 entry towards the end of the interrupt handler doesn't appear to be taking affect?



IOC_FLAG VAR INTCON.0 ' Alias RABIF interrupt flag bit
debug_out var byte
SW1 VAR PORTA.5
on_status var byte
Green_LED VAR PortC.1

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler IOC_INT, _Switch_Interrupt, PBP, YES
endm
INT_CREATE ; Creates the interrupt processor
ENDASM

Check:
'Check switches before enabling/re-enabling IOC
WHILE SW1 = 0 : WEND ' Wait until all switch inputs = 1
IOC_FLAG = 0 ' Clear the int-on-change flag bit

@ INT_ENABLE IOC_INT ; Enable 'Int On Change' interrupts
on_status = 0
Low GREEN_LED


'+++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++
Switch_Interrupt:
hserout ["trap ", dec IOC_FLAG, 13, 10]

@ INT_DISABLE IOC_INT ; Disable further IOC interrupts


pause 10
IF sw1 = 0 THEN
if on_status = 1 then
on_status =0
Low GREEN_LED
else

High GREEN_LED
on_status =1
endif
endif
pause 20


WHILE SW1 = 0 : WEND
pause 25
IOC_FLAG = 0
@ INT_ENABLE IOC_INT
@ INT_RETURN




This is almost certainly something I'm doing wrong, but then again, it's pretty much a direct what was working fine my functioning 16F690 IOC routine?

Darrel Taylor
- 21st November 2010, 20:39
On these Enhanced chips, the Interrupt On Change works much better than on the older chips.

You can specify wether you want Rising edges, Falling edges or both by enabling them in the IOCAP and IOCAN.

Then each Pin has it's own interrupt flag in IOCAF. And you need to clear those bits.

It's described better in section 13.0 in the datasheet.
http://ww1.microchip.com/downloads/en/DeviceDoc/41413A.pdf

HankMcSpank
- 21st November 2010, 21:05
Yet again, you've come up trumps - worse still I knew about the positive edge/falling edge for triggering an interrupt ...since I'm using weak internal pullups, I selected negative, but I never made the connection that I'd have to clear the flag you mentioned....I've now modified my code to clear IOCAF ..... & it works a treat.

You've made a happy man very old. :D

R.G.Keen
- 10th March 2011, 19:51
I have a fair amount of experience with MPLab and PBP. I'm trying to hook up instant interrupts, and have run into an odd situation. I've pored through the ASM file, source file, compiler and assembler manuals, and the MPLab info, and searched on line, including here. I'm sure it's simple and I'll slap my own forehead when someone points it out, but ... well, if you can supply a pointer, I'd be grateful.

I'm trying to compile the instant interrupts "BlinkyLight" program, which is as follows:


' ================================
' this Blinky Light program will continue Blinking at the same rate, no
' matter what else you add to the Main: program loop.
LED1 VAR PORTB.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 = $31 ; Prescaler = 8, TMR1ON
@ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts

Main:
PAUSE 1
GOTO Main

' ---[TMR1 - interrupt handler]--------------------------------------------------
ToggleLED1:
TOGGLE LED1
@ INT_RETURN
' ======================================

I'm running MPLab v8.60 with PBP 2.60a. I have used this setup to successfully compile to HEX other programs in PBP. MPASM is the assembler, and I'm using the 110 level of instant interrupts.

I get this odd error from the assembler that it cannot continue, as follows:

Executing: "C:\PBP\PBPMPLAB.BAT" -p16F628A -ampasmwin -k# "BlinkyLight1.bas"
Executing: "C:\PBP\PBPW.EXE" -p16F628A -ampasmwin -k# "BlinkyLight1.bas"
PICBASIC PRO(TM) Compiler 2.60A, (c) 1998, 2010 microEngineering Labs, Inc.
All Rights Reserved.

ERROR: Unable to execute mpasmwin.Error[101] E:\AVS\V2 DEVT\DUAL DELAY\BLINKYLIGHT1.ASM 231 : ERROR: (wsave variable not found,)
Error[101] E:\BLINKYLIGHT1.ASM 195 : ERROR: (" Add:" wsave VAR BYTE $70 SYSTEM)
Error[101] E:\BLINKYLIGHT1.ASM 252 : ERROR: (Chip has RAM in BANK1, but wsave1 was not found.)
Error[101] E:\BLINKYLIGHT1.ASM 202 : ERROR: (" Add:" wsave1 VAR BYTE $A0 SYSTEM, Or change to wsave BYTE $70 SYSTEM)
Error[101] E:\BLINKYLIGHT1.ASM 268 : ERROR: (Chip has RAM in BANK2, but wsave2 was not found.)
Error[101] E:\BLINKYLIGHT1.ASM 209 : ERROR: (" Add:" wsave2 VAR BYTE $120 SYSTEM, Or change to wsave BYTE $70 SYSTEM)
BUILD FAILED: Thu Mar 10 13:21:14 2011

It looks like the problem is in assembling the instant interrupts code - I think. I clearly have something set up wrong, but what?? Just point me in the direction and I'll go find it.

mackrackit
- 10th March 2011, 20:23
Read the error message. It tells you what to do.

Ioannis
- 10th March 2011, 20:32
You have error messages that tell you exactly what to do:

Add wsave etc...

Look into your DT-INT-14.bas file at the first section that says:

;-- Place a copy of these variables in your Main program -------------------
;-- The compiler will tell you which lines to un-comment --
;-- Do Not un-comment these lines --

and follow the instructions of the errors you get.

Ioannis

R.G.Keen
- 10th March 2011, 20:46
Got it. Thanks very much. Somehow I missed that the error message was the cure.

I understand the issue now. It seems to work Now got to go burn chips... :)

Ioannis
- 10th March 2011, 21:49
Darrel has changed the way DT-INTs work now.

It may surprise but is far better now.

Happy burning :)

Ioannis

R.G.Keen
- 10th March 2011, 22:18
Darrel has changed the way DT-INTs work now.

It may surprise but is far better now.

Just so I don't miss anything, can you direct me to more information on how they have changed? Is that on line?

Ioannis
- 11th March 2011, 10:11
For the practical side, users just get a descriptive message as of what to do in the main program. This errors,that are instructions really, may scare a little. But they just tell you what to do.

Regarding the setup there is no change for the users.

Ioannis

R.G.Keen
- 13th March 2011, 15:52
Thanks for taking the time to point this out for me.

Like many things, it seems obvious now that you say it, and I get to slap myself on the forehead again. :)

It's working fine.

ralfmayr
- 31st March 2011, 11:43
Hi Darrel,
i found a problem which is not clear to me:
I hava a 18(L)F25K22 and want to use SSP1_INT for my I2C handler, but after compiling the source, i get this error:

....test.asm 1052 : Symbol not priveiously defined (SSP1IF)

When defining SSP2_INT there is no error.

Regards,
Ralf

Darrel Taylor
- 31st March 2011, 14:34
Ralf,

What version of MPLAB are you using?
I don't get the error when compiling for SSP1_INT here.

When dealing with new chips like the 25K22, you should always keep up to date.
Current MPLAB version is 8.66.
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en019469&part=SW007002

ralfmayr
- 31st March 2011, 16:05
Hi Darrel,
yes you are right, i had 8.56, now 8.66 and it works.

BTW: For all I2C Slave progger:
To get the I2C Slave running on a 25K22, use SSP1_INT or SSP2_Int, and, very important, you must set ANSC4 & ANSC3 = 0 for SSP1 and ANSB1 & ANSB0 = 0.

Regards,
Ralf

helloo
- 3rd April 2011, 16:57
Hey there,
I'm trying to code a portb change interrupt routine with DT's Inst Ints, but it does very weird stuff, and I can't find out why.

The setup:
PIC 16F876 @ 20 MHz
I have connected LEDs to the ports c0, c3, c4 and c5 to check what happens
The input switches are connected to ports b1-b4

The code looks something like this:


define OSC 20

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 RBC_INT, _PortBInterrupts, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM

@ INT_ENABLE RBC_INT ; enable PortB change interrupts

main:
toggle led ' Toggles a LED that indicates if the program still runs :-)
pause 250
low portc.0
low portc.3
low portc.4
low portc.5
goto main

PortBInterrupts:

if portb.1 = 1 then
high input1
endif

if portb.2 = 1 then
high input2
endif

if portb.3 = 1 then
high input3
endif

if portb.4 = 1 then
high input4
endif

@ INT_RETURN


What happenes is the following:

If I press any button except of b4, nothing happens.
If I press only button b4 nothing happens

If I press b1 just before b4 then the LED according to b4 lits.
If i press any other button along with b4, the right LEDs light up.

It seems that button b4 is the mainswitch for all other buttons within the interrupt routine. Without b4 nothing happens.

So to verify the code I wrote something like this without interrupts:


main:
if portb.1 = 1 then high portc.0
if portb.2 = 1 then high portc.3
if portb.3 = 1 then high portc.4
if portb.4 = 1 then high portc.5
pause 250
low portc.0
low portc.3
low portc.4
low portc.5
goto main


With this code everything works fine. Every input lits the according output LED. So it must be a interrupt handling issue that makes the errors...

any ideas?

Pls. Excuse my bad english, it's not my mother tongue...

Darrel Taylor
- 3rd April 2011, 19:59
The 16F876 only has "Interrupt On Change" on RB4-7.

helloo
- 3rd April 2011, 21:05
Hm, thanks Darryl. The datasheet isn't really clear in this case (written in the datasheet is only PORTB<7:4>). I always thought portb change is the whole portb as the name says.
I'll check this out tomorrow. Hope it works.

That complicates my circuit a little 'cause I wanted the rb7 and rb6 only for ICSP. Now I have to solder in some jumpers :-)

Ioannis
- 3rd April 2011, 21:28
A couple of resistors maybe are enough to isolate the ICSP from the rest of the circuit without need of any jumpers.

Ioannis

rayzrocket
- 7th April 2011, 07:47
DT, you have given the PBP & PIC users a great gift with your instant interrupts!
My application can't wait for the current statement execution to complete for 'ON INTERRUPT' use.
I've implemented your latest creations after reading your website on DT_INTS-14.
Also, have studied many similar threads with similar problem & tried the posted solutions, but I still get compile errors:
(using PIC16F1826 / PBP2.60C / MPASM )
Error[113]c:\pbp\pbppi14e.lib 1182 : Symbol not previously defined (INT_ENTRY)
Error[113]c:\pbp\pbppi14e.lib 1182 : Symbol not previously defined (INT_ENTRY)
Error[113]c:\pbp\pbppi14e.lib 720 : Symbol not previously defined (INT_EXIT)
Error[113]c:\pbp\pbppi14e.lib 733 : Symbol not previously defined (INT_EXIT)
Error[113]c:\pbp\pbppi14e.lib 737 : Symbol not previously defined (INT_EXIT)
Warning[207]c:\microc~2\pi34cc~1.asm 720: Found label after column 1. (INT_Create)

complete code:


'******************************
OSCCON = $73 'or %01110011 is for use intosc of 8Mhz
'OSCCON = %11110000 '32Mhz intosc use
Define OSC 8 'define the timing for PBP timing such as pause & serout
'*********************************************
'
'Tris register 1=input(PORdefault) 0=output
'Ansel register 1=analoginput(PORdefault, digital reads are 0) 0=digitalinput
ANSELA = %00001100 '1 = Analog used / Vref+(A3) and Vref-(A2)
ANSELB = %00100000 '1 = Analog used / ADC in (B5 / AN7)
TRISA = %00111100 '0 is output ; 1 is an input(POR Default)
TRISB = %10111111 'Port B
'OPTION_REG.6 = 1 'INT interrupt acts on RISING EDGE
'CLKRCON = %11010000 'Turn on ref clock output BE SURE TO DISABLE "CLOCK OUT" IN MEPROGRAMMER
'
'
'*******Variables*************************
'HeadUnit Connections
HUdat var PORTB.0 'Headunit communications Input or Output
'Strain Gage Connections
GagePwr var PORTA.1 'PowertoStrainBride Output
ADCPin VAR PORTB.5 'StrainSample AN7 Input
'Hall Effect Sensor Connections
SpdDat var PORTB.3 'HallSensor Input
'Digital Pot Connections
PotCS var PORTA.0 'CS DigiPot Output
PotClk var PORTA.7 'SCK DigiPot Output
PotDat var PORTA.6 'SDI DigiPot Output
'Temperature Sensor Connections
TmpSDA var PORTB.4 'SDA Data TempSensor Input
TmpSCL var PORTB.6 'SCL Clock TempSensor Output
'**
wsave VAR BYTE $20 SYSTEM ' location for W if in bank0
'**
'****************************************
Y var byte
Neg var byte
Pos var byte
X var word '16bit variable for PULSIN, 0 to 65,535
SData1 var word 'Speed data
SData2 var word 'Speed data to be sent (Use prior pulse)
WiprPos var byte 'Digipot Command
WiprNeg var byte 'Digipot Command
Mark var byte
Space var byte
Strain var word 'Sampled Strain Value from WheatstoneBridge
'****************************************
wiprneg=%00100000 'Wiper0 v 0000 0000 (nv 0010 0000) write
wiprpos=%00110000 'Wiper1 v 0001 0000 (nv 0011 0000) write
mark=60
Y=0
neg=0
pos=0
x=0
input hudat 'start HUdat as an input pin
'*********************************************
'Interrupt system works on "INT" pin B.0 that is named "HUdat" in the above
include "DT_INTS-14.bas" ;Interrupt System
INCLUDE "ReEnterPBP.bas" ;to use with PBP Interrupt handlers
'*********************************************
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag
INT_Handler INT_INT, _HandleInt, PBP, yes
endm
INT_Create ;create interrupt processor
endasm
@ INT_ENABLE INT_INT ;enables external interrupts
'*****************************************
Start:
'Set Digital Pots
pause 10
neg=240 '257 is ground
pos=60 '0 is full +V supply
low potcs 'Use Digital Pot's mode 0,0 and its MSB first & Clk idles low
shiftout potdat, potclk, 1, [wiprneg, neg] '8bit digi pot
high potcs
pause 50
low potcs 'Use Digital Pot's mode 0,0 and its MSB first & Clk idles low
shiftout potdat, potclk, 1, [wiprpos, pos] '8bit digi pot
high potcs
pause 10
'***********************
Main:
pauseus 10
pulsin spddat,1,sdata1
sdata2 = sdata1 'store speed data into another var as keep-safe vs. INT
'if hudat then
'' pauseus 2100
' output hudat
' serout2 hudat,16530,[strain.highbyte,strain.lowbyte]
'endif
goto Main
'********************************************
HandleInt:
output hudat 'make HUdat an output pin to send data
strain=24650 'test value
serout2 hudat,16530,[strain.highbyte,strain.lowbyte]
input hudat 'switch HUdat back to an input pin to receive interrupt
@ INT_RETURN
'* * * * * * * * * * * * * * * * * *

Your help would be greatly appreciated, since my application must have an 'instant interrupt'.

[ In this application I have a sensor-unit(code shown above) connected to a head-unit. HUdat pin is on the sensor-unit and awaits a simple signal from the head-unit to activate an interrupt and send data on the same connection. ]

You guys are the best & thanks in advance!
-ray

rayzrocket
- 8th April 2011, 04:48
:o
My code had
INT_Create
instead of
INT_CREATE
I suppose I should wear my glasses more often.
DTaylor's instant interrupt works great now in my application.
thanks for your patience,

picone
- 12th August 2011, 19:19
Sorry if I'm in the wrong thread but this is the only one that came up when I searched for PWPS.

This question is for Darrel, but if anyone else can answer I would appreciate the response just as much.

The PWPS servo code is almost ideal for what I need........I only want 0.5us resolution instead of 1us. Am I able to get 0.5us resolution by simply defining my code to use an 8 MHz OSC and then changing the 4 value in the code snippet below to 8?

GetOsc: ' Retreive defined OSC value on Reset
asm
ifdef OSC
MOVE?CB OSC, _PicOSC
else
MOVE?CB 4, _PicOSC
endif
endasm

Sorry if my terminology isn't 100% correct....I'm a bit of a NOOB to picbasic.

mister_e
- 13th August 2011, 01:00
DEFINE OSC 8 will do but also alter everything based on timing such as HSEROUT/HSERIN/PAUSE etc etc.

OSC is always defined anyways, even if you don't type the DEFINE OSC line. If you don't type the DEFINE OSC, PBP assume 4MHz.

Darrel Taylor
- 13th August 2011, 02:10
Yes, use DEFINE OSC 8 just like you always should.
But if you change PicOSC, it will change all parts of PWPS including the 50Hz pulse frequency.

If you only want to change the resolution, you can modify one line in the .inc file ...

; W1 = TicksPeruSx100 * Position ; original line
W1 = TicksPeruSx100 * Position / 2

Then instead of 0-900, the position variable will be 0 - 1800

1uS resolution (0.1 degrees) was already better than the maximum performance of hobby servo motors.
A resolution of 0.5uS will not have any affect if that's what you are doing.

picone
- 13th August 2011, 16:18
Thank you for the quick reply.

I'm actually working with an ESC that has 11 bit resolution so that is why I was looking for 0.5us steps. I'm not sure how much difference it will make but I wanted to try it out anyway.

I really appreciate the help!

cncmachineguy
- 13th August 2011, 18:05
Really? Who makes the ESC? On the other hand, I doubt you will notice a difference, but hey go for it!! :)

picone
- 14th August 2011, 01:16
Really? Who makes the ESC? On the other hand, I doubt you will notice a difference, but hey go for it!! :)

It is a Castle Creations ESC........when I spoke to one of their engineers they said all of their ESCs have 2048+ speed steps. I know I can get away with the 8 bit resolution of a standard ESC......but as an engineer I need to get the best (i.e. overkill!) solution!

cncmachineguy
- 14th August 2011, 02:39
The part I can't get through my thick head is this, how small of a change can we cause to happen in 20mS to a spinning mass? So if the motor were actually spinning 20,000, then thats 9.75 rpm per bit at 11 bit resolution. On the other hand, getting the extra bit from the PIC may cause less time available to do other things. Mind you I have never looked at PWPS.

Ioannis
- 13th January 2012, 22:27
Hi. I am trying to make this Rotary Encoder work with DT-INTS on a 16F1827 device.

It gets once in the interrupt routine and never seem to exit.

Here is the code so far driving me crazy.



ASM
__config _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_ON & _MCLRE_ON & _CP_ON & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
__config _CONFIG2, _WRT_OFF & _PLLEN_ON & _LVP_OFF & _STVREN_OFF & _BORV_25
ENDASM

DEFINE OSC 32

OSCCON= %11110000 'PLL enabled, Internal RC-8MHz

' Set LCD Data port
DEFINE LCD_DREG PORTA
' Set starting Data bit (0 or 4) if 4-bit bus
DEFINE LCD_DBIT 0
' Set LCD Register Select port
DEFINE LCD_RSREG PORTA
' Set LCD Register Select bit
DEFINE LCD_RSBIT 4
' Set LCD Enable port
DEFINE LCD_EREG PORTB
' Set LCD Enable bit
DEFINE LCD_EBIT 3
' Set LCD bus size (4 or 8 bits)
DEFINE LCD_BITS 4
' Set number of lines on LCD
DEFINE LCD_LINES 2
' Set command delay time in us
DEFINE LCD_COMMANDUS 1500
' Set data delay time in us
DEFINE LCD_DATAUS 44

INCLUDE "DT_INTS-14.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts

'Initializing Registers
PORTB = 0:PORTA = 0
TRISB = $33
TRISA = 0

ADCON0 = 0
ADCON1 = 0
ANSELA = 0
ANSELB = 0

INTCON = $88 ' Binary 10001000

IOCBP=$30
IOCBN=$30

OPTION_REG = 0

WPUB=$33

eeprom 0,[2,0,3,1,1,3,0,2]
led var portb.4
Flag var bit
wsave VAR BYTE $70 SYSTEM ' alternate save location for W
Q_New var Byte
Q_Old var byte
M_Count var byte [4]
P_Count var byte [4]
Q_Count var word
temp var byte

clear

For Q_Old = 0 to 3
Read Q_Old,M_Count[Q_Old]
Read Q_Old + 4,P_Count[Q_Old]
Next Q_Old

Q_Count = 0
Q_New = 0
Q_Old = 0
Flag = 0

ASM
INT_LIST macro ; IntSource, Label, Type, Resetflag?
INT_Handler IOC_INT, _Encoder, pbp, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
@ INT_ENABLE IOC_INT ; enable external (INT) interrupts

'---------------------------- Initialize LCD ----------------------------

Lcdout $fe, 1 ' Clear LCD screen
Lcdout "System Ready" ' Display message
Pause 500 ' Wait .5 second
Q_Count=50

Goto Main_Loop

Encoder: ' ISR
Q_New = PortB.5 + PortB.5 + PortB.4 ' get port status

If M_Count[Q_Old] = Q_New then ' if M_Count code satisfied then minus
temp=temp+1
if temp=4 then
temp=0
Q_Count = Q_Count - 1
Flag = 1 ' set flag to true to update display
endif
goto Q_Skip
endif

If P_Count[Q_Old] = Q_New then ' if M_Count code satisfied then plus
temp=temp+1
if temp=4 then
temp=0
Q_Count = Q_Count + 1
Flag = 1
endif ' set flag to true to update display
endif

Q_Skip:
Q_Old = Q_New
toggle portb.6 ' update Q_Old Byte
@ INT_RETURN


Main_Loop:
if Flag = 1 then
Lcdout $fe, 1 ' Clear LCD screen
Lcdout dec Q_Count ' Display encoder position (counts)
Flag = 0 ' reset flag to false, display updated
endif

pause 100

goto Main_Loop



Thanks,
Ioannis

Darrel Taylor
- 13th January 2012, 22:46
Ioannis,

On those chips, the IOCIF bit is read-only and only gets cleared when ALL of the IOCBF flags are clear.
So you can set the INT_Handler's ResetFlag option to NO.

Then be sure the IOCBF flags are cleared before exiting the ISR.
Also, take a look at section 13.4 in the datasheet regarding clearing the flags.

Ioannis
- 14th January 2012, 10:48
Excellent! Works terrific now.

These chips are a little pain in setting them.

Thanks Darrel.

Ioannis

aratti
- 14th January 2012, 15:41
Use the code in post#27, (new approch to rotary encoder) is more efficient and you can achieve even higher frequency.

Cheers

Al.

Ioannis
- 14th January 2012, 17:18
Hi Al. I am using the #27 ISR.

The thing that I added was the check for the 4 counts before Q_Count variable is incremented or decremented.

Thats because the encoder I use produces 4 pulses on every step I turn the knob. Thanks Henrik for noting this.

Ioannis

aratti
- 15th January 2012, 00:52
The code was written to read quadrature count. Any rotary encoder with two channels will generate quadrature count.

Al.

Ioannis
- 15th January 2012, 12:46
Yes that is correct. So the Q_count variable is incrementing by 4.

Ioannis

AvionicsMaster1
- 1st February 2012, 00:41
If this topic was previously mentioned, I apologize for not finding it.

I'm using a 16F877A with a 4 MHz crystal and two 22pf caps with a LED hooked up to portb.1 and the code from example 2 of DT_ints-14.bas on DTs site. I'm using a oscope to look at the timing of the LED flashes and they are occuring around 950msec apart.

My question is, is there a way to tune the oscillator or modify DT interrupts to get it closer to a true 1 second pulse time? I know it's not far off but I was trying to learn something and maybe make it more accurate at the same time. Your help would be appreciated.

Yes I did read the datasheet but I couldn't find anything like OSC tune that I've seen for the 12F683.

sougata
- 1st February 2012, 05:25
Hi,

When using multiple interrupt sources you can prioritize which Interrupt flags to check when vectored to ISR, still the results may not be deterministic every time. Say you are already servicing a lower priority interrupt (not Hardware but DT's scheme) a higher priority interrupt like your time tick occurs. Generally adding the rolling timer with the offset value does the trick however if you would like more precision then use the compare module on the PIC which resets the associated timer automatically and gives a rock solid time base.

mackrackit
- 1st February 2012, 09:42
You need to fine tune the timer, not the OSC.
Here is an example
http://www.picbasic.co.uk/forum/showthread.php?t=3251&p=23259#post23259
And here is another
http://www.picbasic.co.uk/forum/showthread.php?t=11447&p=75912#post75912
And this will help with the calcs.
http://www.picbasic.co.uk/forum/content.php?r=159-New-PIC-Utility.-PICMultiCalc

DaTiNs
- 31st May 2012, 02:10
Hello good people,


I follow this forum for a long time, it is excellent! I found a lot of good stuff on it.


Now I have a problem with the code from Mr. Darrel Taylor.


Thus, I use pic18f2550 and connect DS1307z and 4 PWM channels to PORTA


SDA Var PORTA.1
SCL Var PORTA.0


ASM
SPWM_LIST macro
SPWM_PIN PORTA, 2, _CH1
SPWM_PIN PORTA, 3, _CH2
SPWM_PIN PORTA, 4, _CH3
SPWM_PIN PORTA, 5, _CH4
endm
SPWM_INIT SPWM_LIST


INT_LIST macro
INT_Handler TMR1_INT, SPWMhandler, ASM, yes
endm
INT_CREATE
ENDASM
@ INT_ENABLE TMR1_INT


Now i got problem with this configuration. When i enable SPWM_LIST then RTC stop working, in fact he working but value he give, its not good. When i disable software pwm, RTC is working good.


I hope that you understande what is my problem and that one of you has a solution for this problem.


Sory for my english :)


Thanks a lot, Damir

Darrel Taylor
- 31st May 2012, 02:50
Do you have this in your program ... ?


ADCON1 = 15

DaTiNs
- 31st May 2012, 03:08
Thank you for quick reply!

Yes i have, this is configuration for my pic



ADCON1 = $0F
CMCON = 7
UCFG.3 = 1
PORTA = 0
PORTB = 0
PORTC = 0

DaTiNs
- 31st May 2012, 12:56
Just want to add,when I turn off TRM1 before reading i2c, rtc is operating normally, but problem is with LED strips on PWM channel they strart flashing.

T1CON.0=0
I2CRead sda,scl,$D0,$00,[RTCSec,RTCMin,RTCHour,RTCDay,RTCDate,RTCMonth,RTCY ear]
T1CON.0=1

Darrel Taylor
- 31st May 2012, 19:09
Damir,

I can duplicate the issue here, which appears to be the old R-M-W hardware problem.
I moved the PWMs over to PORTC, and everything works fine.

Since I2C uses pull-ups instead of bi-polar driven outputs, it's more susceptable to R-M-W problems.

If you cannot move pins around on your project, you can get away with the following.
In general, I do not recommend doing this type of modification.
But in your specific case, it should work.


SPWM_LIST macro
SPWM_PIN LATA, 2, _CH1
SPWM_PIN LATA, 3, _CH2
SPWM_PIN LATA, 4, _CH3
SPWM_PIN LATA, 5, _CH4
endm

Darrel Taylor
- 31st May 2012, 19:45
I should have also mentioned that when using the LATA register, you'll need to set the pins to output manually.

TRISA = %11000011

DaTiNs
- 31st May 2012, 19:54
Thank you very much!

I must add TRISA = 0 to the begin of code, and then start work great.

One more time, thank you, Damir.

SteveB
- 5th December 2012, 22:36
Darrel,
While poking around and getting ideas, I got to looking at ver 1.2 of "Elapsed_INT-18.bas". I was particularly interested in the nice routine to calculate the timer reload constant:


' -------------- calc timer reload Constants -------------------------------
ASM
T1PS = 1 ; start with 1:1 postscaler
TimerConst = ((OSC*1000000)/4/100) ; how many timer ticks will it take
while TimerConst > 65400 ; if it's more than the timer can count
T1PS = T1PS * 2 ; double the postscaler
TimerConst = TimerConst / 2 ; halve the count
endw
TimerConst = 65536 - TimerConst + 8 ; final reload value

But, I think there is an error in the formula. The absolute time it takes to execute the 8 instruction cycles doesn’t change. But, the time in relation to the TMR1L will be proportional to the prescaler. So, that should be accounted for in the formula, as such:

TimerConst = 65536 - TimerConst + (8/T1PS) ; final reload value
Since it's not likely the prescaler will need to be above 1:8, the 8/T1PS shouldn’t get too low.

Thanks again for your great work and inspiring examples,
Steve

SteveB
- 5th December 2012, 22:53
The code could also be changed thus, not that it makes a difference:


T1PS = 1 ; start with 1:1 postscaler
TimerConst = ((OSC*1000000)/4/100)+8 ; how many timer ticks will it take
while TimerConst > 65400 ; if it's more than the timer can count
T1PS = T1PS * 2 ; double the postscaler
TimerConst = TimerConst / 2 ; halve the count
endw
TimerConst = 65536 - TimerConst ; final reload value

jamie_s
- 16th March 2013, 06:36
Hi Darryl,

Currently getting an error with Latest MPLAB IDE:
MPLAB 8.90.00.00

PIC is an 18F45K22 and DT_INTS-18 is latest from your website, both MPLAM and DT_INTS were downloaded from the respective sites on 15/3/2013


ERROR: Unable to execute mpasmwin.Warning[206] M:\<FOLDERPATH><FILE>ASM 2170 : Found call to macro in column 1. (INT_ENABLE)
Error[116] M:\<FOLDERPATH><FILE>.ASM 696 : Address label duplicated or different in second pass (Z00032)
Error[116] M:\<FOLDERPATH><FILE>.ASM 759 : Address label duplicated or different in second pass (Z00033)
Error[116] M:\<FOLDERPATH><FILE>.ASM 812 : Address label duplicated or different in second pass (Z00034)
Error[116] M:\<FOLDERPATH><FILE>.ASM 843 : Address label duplicated or different in second pass (Z00035)

Can you advise if there is any fix for this or do i need to use an older version of MPLAB IDE

mackrackit
- 16th March 2013, 11:30
You might try here
http://support.melabs.com/threads/110-MPLABX-DT_INTS-18.bas-error?highlight=MPLAB-X

Christopher4187
- 30th April 2013, 18:11
I've used the DT_INTS sucessfully with an 18F4550. I had to move to an 18F87J50 but the DT_INTS would not compile. Not sure if I'm doing something wrong or if the DT_INTS was never tested with J series PIC's. When I compile, I get the following warning message:
Unable to fit variable VP_DelayCount in requested bank 0
In the "VirtualPort.bas" code, I changed this code:

VP_DelayCount VAR WORD BANK0 ; Used for internal Delay only
to this:

VP_DelayCount VAR WORD BANK1 ; Used for internal Delay only
and it compiled as expected. I have no clue if this will cause unexpected problems with my program or if this is the correct way to solve it but I haven't noticed any ill effects yet. Seems like this problem could be related to the SFR's but it's way above my level of knowledge.

Just thought I'd pass it along.

Darrel Taylor
- 30th April 2013, 18:42
NO! You can't just change the variable to BANK1!
That variable must be in BANK0.

Both DT_INTS-18 and VirtualPort.bas fit quite comfortably in an 18F87J50, with room to spare. Even when using PBPL.

How many variables have you declared in BANK0 in your program?
Or, what other include files are you using that may have variables placed in BANK0.

Christopher4187
- 1st May 2013, 17:04
NO! You can't just change the variable to BANK1!Oh. The door was locked and I couldn't find the key so I just picked the lock.


How many variables have you declared in BANK0 in your program?
Or, what other include files are you using that may have variables placed in BANK0.Good questions and ones that I wish I had answers for. I'm using HIDmaker so that's probably the root cause. Do I need to figure this problem out or is there a workaround?

Ioannis
- 24th May 2013, 21:50
I am trying to make an Interrupt on Rising Edge, PortB.0 on a 16F1827 chip.

When first POR the device, it send the message "Program started" and waits for the Interrupt.

When interrupt happens, Portb.0 is left open (it has pull-up enabled) the ISR is executed sending the message "Hey, I am sleeping!".

And then keeps on sending the message even if the PortB.0 has been restored (grounded).

Anyone sees what stupid thing I missed?

Ioannis

Darrel Taylor
- 24th May 2013, 22:45
Ioannis,

You just need to clear the IOCBF register before exiting the ISR.

IOCBF = 0

Ioannis
- 25th May 2013, 00:26
Oh, I see.

I thought this was taken care by the DT-INTS.

Thanks Darrel,
Ioannis

Darrel Taylor
- 25th May 2013, 03:27
That's what everyone else thinks too, so don't feel too bad.

However, the "Interrupt On Change" on some chips have many interrupt flags that "funnel" into a single IOCIF flag.
DT_INTS only knows about the one IOCIF flag. It has no control over the other 8 flags in the IOCBF register.

It's alot like the USB modules which have 12 interrupt flags that funnel into a single USBIF flag.
But for some reason, nobody expects DT_INTS to handle all of those automatically.
Well actually, if you add DT_HID, they are handled automatically, but that's not the point.

There are too many variations of the IOC interrupts.
Some chips have them on PORTB, some on PORTA, and some have combinatons of PORTA, PORTB and PORTC.
Its the one part of a PIC that you can pretty much assume won't work the same way as the last chip you used.

And there are too many ways you can use IOC interrupts, there's no way I could make something that would work for everybody.
It's much easier for the user to add one or two lines of code to clear the flags the way that best fits the application.

Ioannis
- 25th May 2013, 21:08
Thanks Darrel. Yes I understand that it is too much to ask for your software to cover every variation that Microchip offers.

It was my part to find that, though I got a little confused by the Data sheet and could not see the obvious.

By the way, this little monster (16F1827) has got a core temperature sensor too!

Ioannis

Ruben Pena
- 7th June 2013, 18:49
Hi Darrel: I made a little test with this:
DEFINE OSC 8
' **** CONFIGURACION 16F1826 *************************
#CONFIG
__config _CONFIG1, _FOSC_INTOSC & _MCLRE_OFF & _CP_ON & _WDTE_OFF
__config _CONFIG2, _PLLEN_ON & _LVP_OFF
#ENDCONFIG
ANSELA= %00000001 'Set 'em all to digital
ANSELB= 0 ' 'all digital
ADCON0= 1
adcon1=$80
CM1CON0 = 0
CM2CON0 = 0
OSCCON = $72
'*******************************
LED1 VAR PORTB.3

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 = $31 ; Prescaler = 8, TMR1ON
@ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts

Main:
PAUSE 1
GOTO Main

'---[TMR1 - interrupt handler]--------------------------------------------------
ToggleLED1:
TOGGLE LED1
@ INT_RETURN

When I compile, I got 2 errors:
574 Illegal opcode (aftersave)
581 Illegal code (AfterUserRoutine)

and two warnings:
574 found label after column 1 (GetAddress)
581 found label after column 1 (GetAddress)
Please help...
Greetings...
Ruben de la Pena V.

Darrel Taylor
- 7th June 2013, 20:44
Ruben,

1) Did you retype the errors, or copy&paste them? The errors are not even the correct format.

2) Have you modified the DT_INTS-14.bas file? The stated errors do not occur when I compile your code.

Try downloading the include files again.
http://www.darreltaylor.com/DT_INTS-14/downloads.htm

richard
- 7th June 2013, 23:34
I have had similar problems , it seems I cut and pasted the asm section from somewhere that included an illegal non printing character. simple solution is to retype the asm section ,remember its case sensitive
ASM
INT_LIST macro
INT_Handler TMR1_INT, _ToggleLED1, PBP, yes
endm
INT_CREATE
ENDASM

Ruben Pena
- 8th June 2013, 17:55
Hi Darrel:
Thanks ... I reloaded the files and now it works...

Ruben de la Pena V.

Tywais
- 17th June 2013, 05:17
1st off wish to thank Darrel for a very useful routine. Now my issue. It seems when in a WHILE loop or a REPEAT..UNTIL look the interrupts are no longer detected. I am using the UART interrupts and they work flawlessly until I call a subroutine which has the WHILE loop and can't get out of it. I have a command protocol where I send a START command via serial which will call the looping program. I stop the loop by sending a STOP command. I minimized the routine to have only the loop and not the code within the loop to simply the trouble shooting. Below the code snippets.

The uart interrupt entry routine reduced to just the command of interest.

SERIALINT:
HSERIN [COMMAND,DEC1 MODE,DEC5 IODATA]
SELECT CASE COMMAND
CASE "N" 'Control scan position and start/stop PIEZO1
MOTORADDR = PIEZO1
SELECT CASE MODE
CASE STARTPOS 'READ START POS DATA 16-BITS
PIEZO1START = IODATA
CASE ENDPOS 'READ END POS DATA 16-BITS
PIEZO1END = IODATA
CASE STARTSCAN 'START SCANNING
SCAN = TRUE
HSEROUT ["START",13,10] '0-65535
CASE STOPSCAN 'STOP SCANNING
SCAN = FALSE
HSEROUT ["STOP",13,10] '0-65535
END SELECT
GOSUB BEGINSCAN
END SELECT
@ INT_RETURN

The subroutine being called below. When I send the start command it enters the routine fine but sending another command to stop it never enters the interrupt handler.
debugging lines to transmit START or STOP in the handler. START is sent to the terminal but STOP doesn't which shows it doesn't recognize another interrupt. Without the WHILE
loop, works fine. I commented the main code to make it as simple as possible


BEGINSCAN: 'START SCANNING PIEZO1
IF (PIEZO1END - PIEZO1START) < 1000 THEN
SCANSTEP = 1
ELSE
SCANSTEP = (PIEZO1END - PIEZO1START)/1000 'LIMIT TO 1000 STEPS
ENDIF
'
WHILE SCAN = TRUE
' SCANINDEX = PIEZO1START
' ARRAYCOUNT = 0
' WHILE SCANINDEX <= PIEZO1END
' PIEZO1POS = SCANINDEX
' GOSUB SETPIEZO
' PDSELECT = pd1 'CONVERT PD1 DATA AND STORE IN ARRAY
' GOSUB READPD
' PD1ARRAY[ARRAYCOUNT] = PD1DATA
' SCANINDEX = SCANINDEX + SCANSTEP
' ARRAYCOUNT = ARRAYCOUNT + 1
' WEND
'GOSUB SENDARRAY 'SEND SAVED DATA TO PC
WEND
RETURN

Is there something about WHILE or REPEATS that doesn't allow interrupts? I also put a 1 ms pause in the loop and same problem.

Charlie
- 17th June 2013, 09:56
You'll need to post ALL the code before folks can help I think, since the problem is not necessarily in this little bit. The "@ INT_RETURN" suggests these are the actual interrupt routines? One thing to be cautious about is that interrupts can occur while you are in your handler routine, causing the routine to restart and all sorts of other strange problems. Your interrupt routine should be as fast as possible - usually only a flag is set, that your main program loop can quickly detect and take action on. If you must do a few things in the routine, then you need to disable interrupts while in the routine, and risk missing something.

Darrel Taylor
- 17th June 2013, 15:54
If you call a subroutine from the Interrupt Handler, you are still in the Interrupt.

Interrupts will not interrupt an interrupt.
The handler must complete and exit before another interrupt can occur.

Tywais
- 17th June 2013, 17:42
You'll need to post ALL the code before folks can help I think, since the problem is not necessarily in this little bit.
The entire code is a couple of hundred lines so not practical to post all of it. I stripped it down to the absolute minimum to focus on the handler. I am using the uart interrupt to monitor for a command. If the command is "S" then it will enter the scan subroutine which is just a while loop and print START on the terminal. If when in the loop I send a F it should exit the sub and print "STOP" to the terminal. The start works as it can be seen entering the SCAN subroutine but never exits when I send a stop request. The simplified code here, interrupt handler in red. No timing issues as I am entering the commands via a terminal manually.

Darrel's comment indicates that the scan routine has to complete on its own to exit the interrupt handler, which of course is not possible with the While loop as it is. That means that the Instant Interrupts doesn't support re-entry. I've written interrupt handlers but on large non-pic systems and re-entry is critical to real time OSes but it makes stack management complex. Guess one way to do it is to monitor the receive buffer in the scan loop to look for an exit character. Not as elegant as interrupt re-entry capability but may be my only solution.

Thanks for your feedback.

DEFINE OSC 40 ' 18F6628
@ __CONFIG _CONFIG1H, _OSC_HSPLL_1H
@ __CONFIG _CONFIG2H, _WDT_ON_2H & _WDTPS_512_2H
;@ __CONFIG _CONFIG3H, _PBADEN_OFF_3H
@ __CONFIG _CONFIG4L, _LVP_OFF_4L & _XINST_OFF_4L
'
'************** UART Definitions ******************
DEFINE HSER_SPBRG 42 '21=115200 42=57600 4=512000 @40MHz 2=921000
DEFINE HSER_TXSTA 24h '%00100100 brgh high
DEFINE HSER_RCSTA 90h '%10010000
DEFINE HSER_BAUD 57600 '57600 '512000 '115200 '57600

TRISC = %10010000

'*********** Interrupt Definitions & Init ***********
include "DT_INTS-18.bas"
include "ReEnterPBP-18.bas"
'
TRUE CON 1
FALSE CON 0
SCAN VAR BYTE
COMMAND VAR BYTE

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler RX_INT, _SERIALINT, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM

@ INT_ENABLE RX_INT ; enable external (INT) interrupts

MAIN:
PAUSE 1
GOTO MAIN

BEGINSCAN: 'START SCANNING PIEZO1
HSEROUT ["START",13,10] '0-65535
WHILE SCAN = TRUE
PAUSE 1
WEND
RETURN

SERIALINT:
HSERIN [COMMAND]
IF COMMAND = "S" THEN
SCAN = TRUE
GOSUB BEGINSCAN
ENDIF
IF COMMAND ="F" THEN
SCAN = FALSE
HSEROUT ["STOP",13,10] '0-65535
ENDIF
@ INT_RETURN

Tywais
- 18th June 2013, 06:05
I made the following change in the WHILE loop to allow me to exit. As mentioned, I use the receive register and poll it for the command. Does work, just not as elegant as I would prefer. Addition in red.


BEGINSCAN: 'START SCANNING PIEZO1
'
WHILE SCAN = TRUE
PAUSE 1
if RCREG1 = "F" THEN
SCAN = FALSE
RETURN
ENDIF
WEND
RETURN

Charlie
- 18th June 2013, 11:21
My comment, and Darrel's comment both said the same thing - it is bad form to put a bunch of code in the interrupt routine. Using a GOSUB essentially puts the bulk of your code inside the routine at compile time.

In order to not get stuck in an interrupt routine forever, typically you would stop servicing interrupts while in the routine. Either you shut them off and risk missing other interrupts, or you set a flag, and exit fast (having only executed a couple instructions). Your main program loop, then checks for the flag and if it is set, executes the GOSUB code. That can be the whole main program loop: (start: -> IF flag=1 THEN GOSUB do_stuff ELSE GOTO start) Then your routine just makes flag = 1 and exits.

There are a number of reasons to not do it the way you are doing - when an interrupt occurs, everything going on in the processor is stuffed into memory and a new program is executed. If a second interrupt happens, then those memory locations get overwritten and your original point in the program is destroyed. It is not practical to allow many levels of saving - if you wish to do that, you'll have to write your own interrupt program. It won't be easy, because of the way the PIC does interrupts, and it is unlikely to be generic, or fast.
But honestly, I have not encountered a situation where it's necessary to do that, and neither have you with the code you posted.

Tywais
- 19th June 2013, 06:20
My comment, and Darrel's comment both said the same thing - it is bad form to put a bunch of code in the interrupt routine. Using a GOSUB essentially puts the bulk of your code inside the routine at compile time.

Thanks, your post cleared it up nicely for me. New strategy now as it is a complex program with dozens of subroutines all invoked via a command from the serial port. As I mentioned, most of my interrupt handler experience has been with large scale mini-computers with realtime OSes and interrupt reentry was the norm. See now the pic architecture & picbasic is limited but still doable with the flags mentioned. That code snippet was just one of dozens of similar subroutines. :)

Thanks for the feedback.

mpardinho
- 2nd October 2013, 15:24
Darrel, exist in DTS RTTC INT ??

i use pic 18F26J50 ..... i need control rtc interrupt

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler RX_??, _Relogio, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM

@ INT_ENABLE ??_INT ; enable external (RTTC INT) interrupts

mpardinho
- 3rd October 2013, 14:28
RTTC is correct Darrel ?





'************************************************* ***************
'* Name : DT_INTS-18.bas *
'* Author : Darrel Taylor *
'* Notice : Copyright (c) 2003 *
'* Version : 3.3 MAR 24, 2008 *
'* Date : JUL 11, 2006 *
'************************************************* ***************
'* Versions: *
'* 3.3 : MAR 24, 2008 *
'* Corrects an initialization problem affecting the *
'* first pass if CLEAR is not used *
'* 3.2 : Aug 26, 2007 *
'* Update for PBP 2.50 using LONG's with PBPL *
'* Added many new INT sources *
'* 3.1 : JUL 18, 2006 *
'* Modified to handle smaller BANKA in the newer chips*
'************************************************* ***************
DISABLE DEBUG

DEFINE INTHAND INT_ENTRY_H ' Context saving for High Priority Ints
DEFINE INTLHAND INT_ENTRY_L ' Context saving for Low Priority Ints

wsave var byte BANKA SYSTEM ' location for WREG
ssave var byte BANK0 SYSTEM ' location for STATUS register
bsave var byte BANK0 SYSTEM ' location for BSR register
psaveUH VAR BYTE BANK0 SYSTEM ' PCLATU Hi Pri.
psaveUL VAR BYTE BANK0 SYSTEM ' Lo Pri.
psaveH VAR BYTE BANK0 SYSTEM ' PCLATH Hi Pri.
psaveL VAR BYTE BANK0 SYSTEM ' Lo Pri.
fsave0H var WORD BANK0 SYSTEM ' locations for FSR registers
fsave1H var WORD BANK0 SYSTEM
fsave2H var WORD BANK0 SYSTEM
fsave0L var WORD BANK0 SYSTEM ' low priority FSR locations
fsave1L var WORD BANK0 SYSTEM
fsave2L var WORD BANK0 SYSTEM
RetAddrH VAR BYTE[3] BANKA SYSTEM ' 21-bit return address Hi Pri.
RetAddrL VAR BYTE[3] BANKA SYSTEM ' Lo Pri.
INT_Flags VAR BYTE BANKA SYSTEM
Serviced_H VAR INT_Flags.0
Serviced_L VAR INT_Flags.1
InHPint VAR INT_Flags.2
NoPriority VAR INT_Flags.3

INT_Flags = 0

goto OVER_DT_INTS_18

ASM
;____ Check for PBPL (PBP ver. 2.50 and above only)__________________________
PBPLongs_Used = 0
if (R1 - R0 == 4)
PBPLongs_Used = 1
; messg PBPL Used = 1
endif

nolist
;____ DEFINE available interrupt sources_____________________________________

#define INT_INT INTCON, INT0IF ;-- INT External, 16F compatible
#define INT0_INT INTCON, INT0IF ;-- INT0 External
#define INT1_INT INTCON3,INT1IF ;-- INT1 External
#define INT2_INT INTCON3,INT2IF ;-- INT2 External
#define INT3_INT INTCON3,INT3IF ;-- INT3 External
#define RBC_INT INTCON, RBIF ;-- RB Port Change
#define TMR0_INT INTCON, TMR0IF ;-- TMR0 Overflow 18F
#define TMR1_INT PIR1, TMR1IF ;-- TMR1 Overflow
#define TMR2_INT PIR1, TMR2IF ;-- TMR2 to PR2 Match
#define TMR3_INT PIR2, TMR3IF ;-- TMR3 Overflow
#define TMR4_INT PIR3, TMR4IF ;-- TMR4 Overflow
#define TX_INT PIR1, TXIF ;-- USART Transmit
#define TX1_INT PIR1, TX1IF ;-- USART1 Transmit
#define TX2_INT PIR3, TX2IF ;-- USART2 Transmit
#define RX_INT PIR1, RCIF ;-- USART Receive
#define RX1_INT PIR1, RC1IF ;-- USART1 Receive
#define RX2_INT PIR3, RC2IF ;-- USART2 Receive
#define CMP_INT PIR2, CMIF ;-- Comparator
#define EE_INT PIR2, EEIF ;-- EEPROM/FLASH Write Operation
#define BUS_INT PIR2, BCLIF ;-- Bus Collision
#define LVD_INT PIR2, LVDIF ;-- Low Voltage Detect
#define HLVD_INT PIR2, HLVDIF ;-- High/Low Voltage Detect
#define PSP_INT PIR1, PSPIF ;-- Parallel Slave Port Read/Write
#define AD_INT PIR1, ADIF ;-- A/D Converter
#define SSP_INT PIR1, SSPIF ;-- Master Synchronous Serial Port
#define CCP1_INT PIR1, CCP1IF ;-- CCP1
#define CCP2_INT PIR2, CCP2IF ;-- CCP2
#define CCP3_INT PIR3, CCP3IF ;-- CCP3
#define CCP4_INT PIR3, CCP4IF ;-- CCP4
#define CCP5_INT PIR3, CCP5IF ;-- CCP5
#define OSC_INT PIR2, OSCFIF ;-- Oscillator Fail

; -- Added for ver. 3.3 --
#define RTTCC_INT PIR3, RTCCIF ;-- RTTC

; -- Added for ver. 3.2 --
#define SPP_INT PIR1, SPPIF ;-- Streaming Parallel Port Read/Write
#define BUS1_INT PIR2, BCL1IF ;-- Bus 1 Collision
#define BUS2_INT PIR3, BCL2IF ;-- Bus 2 Collision
#define ECCP1_INT PIR2, ECCP1IF ;-- ECCP1
#define LCD_INT PIR3, LCDIF ;-- LCD Driver
#define PMP_INT PIR1, PMPIF ;-- Parallel Master Port
#define SSP1_INT PIR1, SSP1IF ;-- Synchronous Serial Port 1
#define SSP2_INT PIR3, SSP2IF ;-- Synchronous Serial Port 2
#define TMR5_INT PIR3, TMR5IF ;-- Timer 5
#define PT_INT PIR3, PTIF ;-- PWM Time Base
#define IC1IF_INT PIR3, IC1IF ;-- Motion Feedback
#define IC2QEIF_INT PIR3, IC2QEIF ;-- Motion Feedback
#define IC3DRIF_INT PIR3, IC3DRIF ;-- Motion Feedback

;_____ Comparators __________________________________________________ ________
#define CMP0_INT PIR1, CMP0IF ;-- Comparator 0 - 1230/1330 only

CMPIFREG = PIR2 ;-- Comparator 1
CMPIEREG = PIE2
CMPIPREG = IPR2
ifdef C1IF ; 18F24K20 18F25K20 18F26K20
CM1IFBIT = C1IF ; 18F44K20 18F45K20 18F46K20
endif
ifdef CM1IF
CM1IFBIT = CM1IF ; several J PICs
endif
ifdef CMP1IF
CMPIFREG = PIR1 ; 1230/1330 only
CM1IFBIT = CMP1IF
CMPIEREG = PIE1
CMPIPREG = IPR1
endif

ifdef CM1IFBIT
#define CMP1_INT CMPIFREG, CM1IFBIT
endif

ifdef C2IF ;-- Comparator 2
CM2IFBIT = C2IF ; 18F24K20 18F25K20 18F26K20
endif ; 18F44K20 18F45K20 18F46K20
ifdef CM2IF
CM2IFBIT = CM2IF ; several J PICs
endif
ifdef CMP2IF
CM2IFBIT = CMP2IF ; 1230/1330 only
endif

ifdef CM2IFBIT
#define CMP2_INT CMPIFREG, CM2IFBIT
endif

;_____ USB Module __________________________________________________ _________

#define USB_INT PIR2, USBIF ;-- USB Interrupt (funnel)
#define USB_ACTV_INT UIR, ACTVIF ;-- Bus Activity Detect
#define USB_ERR_INT UIR, UERRIF ;-- USB Error Condition INT (funnel)
#define USB_RST_INT UIR, URSTIF ;-- USB Reset
#define USB_IDLE_INT UIR, IDLEIF ;-- Idle Detect
#define USB_STALL_INT UIR, STALLIF ;-- A STALL Handshake
#define USB_TRN_INT UIR, TRNIF ;-- Transaction Complete
#define USB_SOF_INT UIR, SOFIF ;-- START-OF-FRAME Token

; -- USB Error Flags --
#define USB_BTO_INT UEIR, BTOEF ;-- Bus Turnaround Time-out Error
#define USB_BTS_INT UEIR, BTSEF ;-- Bit Stuff Error
#define USB_CRC16_INT UEIR, CRC16EF ;-- CRC16 Failure
#define USB_CRC5_INT UEIR, CRC5EF ;-- CRC5 Host Error
#define USB_DFN8_INT UEIR, DFN8EF ;-- Data Field Size Error
#define USB_PID_INT UEIR, PIDEF ;-- PID Check Failure

;_____ Ethernet Module __________________________________________________ ____
#define ETH_INT PIR2, ETHIF ;-- Ethernet Module
#define ETH_DMA_INT EIR, DMAIF ;-- DMA Interrupt
#define ETH_LINK_INT EIR, LINKIF ;-- Link Status Change
#define ETH_PKT_INT EIR, PKTIF ;-- Receive Packet Pending
#define ETH_RXER_INT EIR, RXERIF ;-- Receive Error
#define ETH_TXER_INT EIR, TXERIF ;-- Transmit Error
#define ETH_TX_INT EIR, TXIF ;-- Transmit

;_____ CAN Module __________________________________________________ _________
#define CAN_ERR_INT PIR3, ERRIF ;-- CAN bus Error
#define CAN_IRX_INT PIR3, IRXIF ;-- Invalid Received Message
#define CAN_RXB0_INT PIR3, RXB0IF ;-* Receive Buffer 0 Mode 0
#define CAN_FIFOWM_INT PIR3, FIFOWMIF ;-- FIFO Watermark Mode 1, 2
#define CAN_RXB1_INT PIR3, RXB1IF ;-* Receive Buffer 1 Mode 0
#define CAN_RXBn_INT PIR3, RXBnIF ;-- Any Receive Buffer Mode 1, 2
#define CAN_TXB0_INT PIR3, TXB0IF ;-- Transmit Buffer 0
#define CAN_TXB1_INT PIR3, TXB1IF ;-- Transmit Buffer 1
#define CAN_TXB2_INT PIR3, TXB2IF ;-* Transmit Buffer 2 Mode 0
#define CAN_TXBn_INT PIR3, TXBnIF ;-- Any Transmit Buffer Mode 1, 2
#define CAN_WAKE_INT PIR3, WAKIF ;-- CAN bus Activity Wake-up
ENDASM

asm
; -- macro --
INT_Source macro IFR, IFB, IER, IEB, IPR, IPB
if (IflagReg == IFR) && (IflagBit == IFB)
list
INT_Flag_Reg = IFR
INT_Flag_Bit = IFB
INT_Enable_Reg = IER
INT_Enable_Bit = IEB
INT_Priority_Reg = IPR
INT_Priority_Bit = IPB
Found = 1
endif
nolist
endm
endasm


asm
;_________________________________________________ ___________________________
GetIntInfo macro IflagReg, IflagBit
nolist
INT_Flag_Reg = -1
INT_Flag_Bit = -1
INT_Enable_Reg = -1
INT_Enable_Bit = -1
ifdef IPR1
INT_Priority_Reg = -1
INT_Priority_Bit = -1
endif
Found = 0

ifdef INT0IF ;----{ INT0 External Interrupt }----------[INTCON, INT0IF]---
INT_Source INTCON,INT0IF, INTCON,INT0IE, -1, -1
endif
ifdef INT1IF ;----{ INT1 External Interrupt }---------[INTCON3, INT1IF]---
INT_Source INTCON3,INT1IF, INTCON3,INT1IE, INTCON3,INT1IP
endif
ifdef INT2IF ;----{ INT2 External Interrupt }---------[INTCON3, INT2IF]---
INT_Source INTCON3,INT2IF, INTCON3,INT2IE, INTCON3,INT2IP
endif
ifdef INT3IF ;----{ INT3 External Interrupt }---------[INTCON3, INT3IF]---
INT_Source INTCON3,INT3IF, INTCON3,INT3IE, INTCON2,INT3IP
endif
ifdef RBIF ;----{ RB Port Change Interrupt }-----------[INTCON, RBIF]---
INT_Source INTCON,RBIF, INTCON, RBIE,INTCON2,RBIP
endif
ifdef TMR0IF ;----{ TMR0 Overflow Interrupt }----------[INTCON, TMR0IF]---
INT_Source INTCON,TMR0IF, INTCON,TMR0IE, INTCON2,TMR0IP
endif
ifdef TMR1IF ;----{ TMR1 Overflow Interrupt }------------[PIR1, TMR1IF]---
INT_Source PIR1,TMR1IF, PIE1,TMR1IE, IPR1,TMR1IP
endif
ifdef TMR2IF ;----{ TMR2 to PR2 Match Interrupt }--------[PIR1, TMR2IF]---
INT_Source PIR1,TMR2IF, PIE1,TMR2IE, IPR1,TMR2IP
endif
ifdef TMR3IF ;----{ TMR3 Overflow Interrupt }------------[PIR2, TMR3IF]---
INT_Source PIR2,TMR3IF, PIE2,TMR3IE, IPR2,TMR3IP
endif
ifdef TMR4IF ;----{ TMR4 Overflow Interrupt }------------[PIR3, TMR4IF]---
INT_Source PIR3,TMR4IF, PIE3,TMR4IE, IPR3,TMR4IP
endif
ifndef TX1IF ;----{ USART Transmit Interrupt }-------------[PIR1, TXIF]---
ifdef TXIF
INT_Source PIR1,TXIF, PIE1,TXIE, IPR1,TXIP
endif
endif
ifdef TX1IF ;----{ USART1 Transmit Interrupt }-----------[PIR1, TX1IF]---
INT_Source PIR1,TX1IF, PIE1,TX1IE, IPR1,TX1IP
endif
ifdef TX2IF ;----{ USART2 Transmit Interrupt }-----------[PIR3, TX2IF]---
INT_Source PIR3,TX2IF, PIE3,TX2IE, IPR3,TX2IP
endif
ifndef RC1IF ;----{ USART Receive Interrupt }---------------[PIR1 RCIF]---
ifdef RCIF
INT_Source PIR1,RCIF, PIE1,RCIE, IPR1,RCIP
endif
endif
ifdef RC1IF ;----{ USART1 Receive Interrupt }------------[PIR1, RC1IF]---
INT_Source PIR1,RC1IF, PIE1,RC1IE, IPR1,RC1IP
endif
ifdef RC2IF ;----{ USART2 Receive Interrupt }------------[PIR3, RC2IF]---
INT_Source PIR3,RC2IF, PIE3,RC2IE, IPR3,RC2IP
endif
ifdef CMIF ;----{ Comparator Interrupt }-----------------[PIR2, CMIF]---
INT_Source PIR2,CMIF, PIE2,CMIE, IPR2,CMIP
endif
ifdef EEIF ;----{ EEPROM/FLASH Write Operation Interrupt [PIR2, EEIF]---
INT_Source PIR2,EEIF, PIE2,EEIE, IPR2,EEIP
endif
ifdef BCLIF ;----{ Bus Collision Interrupt }-------------[PIR2, BCLIF]---
INT_Source PIR2,BCLIF, PIE2,BCLIE, IPR2,BCLIP
endif
ifdef LVDIF ;----{ Low Voltage Detect Interrupt }--------[PIR2, LVDIF]---
INT_Source PIR2,LVDIF, PIE2,LVDIE, IPR2,LVDIP
endif
ifdef HLVDIF ;----{ High/Low Voltage Detect Interrupt }--[PIR2, HLVDIF]---
INT_Source PIR2,HLVDIF, PIE2,HLVDIE, IPR2,HLVDIP
endif
ifdef PSPIF ;----{ Parallel Slave Port Interrupt }-------[PIR1, PSPIF]---
INT_Source PIR1,PSPIF, PIE1,PSPIE, IPR1,PSPIP
endif
ifdef ADIF ;----{ A/D Converter Interrupt }--------------[PIR1, ADIF]---
INT_Source PIR1,ADIF, PIE1,ADIE, IPR1,ADIP
endif
ifdef SSPIF ;----{ Synchronous Serial Port Interrupt }---[PIR1, SSPIF]---
INT_Source PIR1,SSPIF, PIE1,SSPIE, IPR1,SSPIP
endif
ifdef CCP1IF ;----{ CCP1 Interrupt }---------------------[PIR1, CCP1IF]---
INT_Source PIR1,CCP1IF, PIE1,CCP1IE, IPR1,CCP1IP
endif
ifdef CCP2IF ;----{ CCP2 Interrupt Flag }----------------[PIR2, CCP2IF]---
INT_Source PIR2,CCP2IF, PIE2,CCP2IE, IPR2,CCP2IP
endif
ifdef CCP3IF ;----{ CCP3 Interrupt Flag }----------------[PIR3, CCP3IF]---
INT_Source PIR3,CCP3IF, PIE3,CCP3IE, IPR3,CCP3IP
endif
ifdef CCP4IF ;----{ CCP4 Interrupt Flag }----------------[PIR3, CCP4IF]---
INT_Source PIR3,CCP4IF, PIE3,CCP4IE, IPR3,CCP4IP
endif
ifdef CCP5IF ;----{ CCP5 Interrupt Flag }----------------[PIR3, CCP5IF]---
INT_Source PIR3,CCP5IF, PIE3,CCP5IE, IPR3,CCP5IP
endif
ifdef OSCFIF ;----{ Osc Fail Interrupt Flag }-----------[PIR2, OSCFIF]---
INT_Source PIR2,OSCFIF, PIE2,OSCFIE, IPR2,OSCFIP
endif
endasm

asm
; -- Added for ver. 3.3 --
ifdef RTCCIF ;----{ RTTC }-------------------------------[PIR3, RTCCIF]---
INT_Source PIR3,RTCCIF, PIE3,RTCCIE, IPR3, RTTCIP
endif
endasm

asm
; -- Added for ver. 3.2 --
ifdef SPPIF ;----{ Streaming Parallel Port Read/Write }--[PIR1, SPPIF]---
INT_Source PIR1,SPPIF, PIE1,SPPIE, IPR1,SPPIP
endif
ifdef BCL1IF ;----{ Bus 1 Collision }--------------------[PIR2, BCL1IF]---
INT_Source BUS1_INT, PIE2,BCL1IE, IPR2,BCL1IP
endif
ifdef BCL2IF ;----{ Bus 2 Collision }--------------------[PIR3, BCL2IF]---
INT_Source BUS2_INT, PIE3,BCL2IE, IPR3,BCL2IP
endif
ifdef CMP0IF ;----{ Comparator 0 }-----------------------[PIR1, CMP0IF]---
INT_Source CMP0_INT, PIE1,CMP0IE, IPR1,CMP0IP
endif
ifdef CM1IFBIT ;--{ Comparator 1 }-----------------------------[varies]---
INT_Source CMP1_INT, CMPIEREG,CM1IFBIT, CMPIPREG,CM1IFBIT
endif
ifdef CM2IFBIT ;--{ Comparator 2 }-----------------------------[varies]---
INT_Source CMP2_INT, CMPIEREG,CM2IFBIT, CMPIPREG,CM2IFBIT
endif
ifdef ECCP1IF ;---{ ECCP1 }-----------------------------[PIR2, ECCP1IF]---
INT_Source ECCP1_INT, PIE2,ECCP1IE, IPR2,ECCP1IP
endif
ifdef LCDIF ;----{ LCD Driver }--------------------------[PIR3, LCDIF]---
INT_Source LCD_INT, PIE3,LCDIE, IPR3,LCDIP
endif
ifdef PMPIF ;----{ Parallel Master Port }----------------[PIR1, PMPIF]---
INT_Source PMP_INT, PIE1,PMPIE, IPR1,PMPIP
endif
ifdef SSP1IF ;----{ Synchronous Serial Port 1 }----------[PIR1, SSP1IF]---
INT_Source SSP1_INT, PIE1,SSP1IE, IPR1,SSP1IP
endif
ifdef SSP2IF ;----{ Synchronous Serial Port 2 }----------[PIR3, SSP2IF]---
INT_Source SSP2_INT, PIE3,SSP2IE, IPR3,SSP2IP
endif
ifdef TMR5IF ;----{ Timer 5 }----------------------------[PIR3, TMR5IF]---
INT_Source TMR5_INT, PIE3,TMR5IE, IPR3,TMR5IP
endif
ifdef PTIF ;----{ PWM Time Base }------------------------[PIR3, PTIF]---
INT_Source PT_INT, PIE3,PTIE, IPR3,PTIP
endif
ifdef IC1IF ;----{ Motion Feedback IC1}------------------[PIR3, IC1IF]---
INT_Source IC1IF_INT, PIE3,IC1IE, IPR3,IC1IP
endif
ifdef IC2QEIF ;----{ Motion Feedback IC2QE}--------------[PIR3, IC2QEIF]---
INT_Source IC2QEIF_INT, PIE3,IC2QEIE, IPR3,IC2QEIP
endif
ifdef IC3DRIF ;----{ Motion Feedback IC3DR}--------------[PIR3, IC3DRIF]---
INT_Source IC3DRIF_INT, PIE3,IC3DRIE, IPR3,IC3DRIP
endif

; ifdef ;----{ }-------------[, ]---
; INT_Source , ,, ,
; endif
endasm

asm ; -- USB sources --
ifdef USBIF ;----{ USB Interrupt funnel }---------------[PIR2, USBIF]---
INT_Source PIR2,USBIF, PIE2,USBIE, IPR2,USBIP

;----{ Bus Activity Detect }-----------------[UIR, ACTVIF]---
INT_Source USB_ACTV_INT, UIE,ACTVIE, _NoPriority

;----{ USB Reset }---------------------------[UIR, URSTIF]---
INT_Source USB_RST_INT, UIE,URSTIE, _NoPriority

;----{ Idle Detect }-------------------------[UIR, IDLEIF]---
INT_Source USB_IDLE_INT, UIE,IDLEIE, _NoPriority

;----{ A STALL Handshake }------------------[UIR, STALLIF]---
INT_Source USB_STALL_INT, UIE,STALLIE, _NoPriority

;----{ Transaction Complete }-----------------[UIR, TRNIF]---
INT_Source USB_TRN_INT, UIE,TRNIE, _NoPriority

;----{ START-OF-FRAME Token }-----------------[UIR, SOFIF]---
INT_Source USB_SOF_INT, UIE,SOFIE, _NoPriority

; -- USB Error Flags --
;----{ USB Error Condition Int funnel }------[UIR, UERRIF]---
INT_Source USB_ERR_INT, UIE,UERRIE, _NoPriority

;----{ Bus Turnaround Time-out Error }-------[UEIR, BTOEF]---
INT_Source USB_BTO_INT, UEIE,BTOEE, _NoPriority

;----{ Bit Stuff Error }---------------------[UEIR, BTSEF]---
INT_Source USB_BTS_INT, UEIE,BTSEE, _NoPriority

;--{ CRC16 Failure }-----------------------[UEIR, CRC16EF]---
INT_Source USB_CRC16_INT, UEIE,CRC16EE, _NoPriority

;---{ CRC5 Host Error }---------------------[UEIR, CRC5EF]---
INT_Source USB_CRC5_INT, UEIE,CRC5EE, _NoPriority

;---{ Data Field Size Error }---------------[UEIR, DFN8EF]---
INT_Source USB_DFN8_INT, UEIE,DFN8EE, _NoPriority

;----{ PID Check Failure }-------------------[UEIR, PIDEF]---
INT_Source USB_PID_INT, UEIE,PIDEE, _NoPriority
endif
endasm

asm ; -- Ethernet sources --
ifdef ETHIF ;----{ Ethernet Module }----------------------[PIR2, ETHIF]---
INT_Source ETH_INT, PIE2,ETHIE, IPR2,ETHIP

;----{ DMA Interrupt }-------------------------[EIR, DMAIF]---
INT_Source ETH_DMA_INT, EIE,DMAIE, _NoPriority

;----{ Link Status Change }-------------------[EIR, LINKIF]---
INT_Source ETH_LINK_INT, EIE,LINKIE, _NoPriority

;----{ Receive Packet Pending }----------------[EIR, PKTIF]---
INT_Source ETH_PKT_INT, EIE,PKTIE, _NoPriority

;----{ Receive Error }------------------------[EIR, RXERIF]---
INT_Source ETH_RXER_INT, EIE,RXERIE, _NoPriority

;----{ Transmit Error }-----------------------[EIR, TXERIF]---
INT_Source ETH_TXER_INT, EIE,TXERIE, _NoPriority

;----{ Transmit }-------------------------------[EIR, TXIF]---
INT_Source ETH_TX_INT, EIE,TXIE, _NoPriority
endif
endasm

asm ; -- CAN Module --
ifdef WAKIF
;----{ CAN bus Error }------------------------[PIR3, ERRIF]---
INT_Source CAN_ERR_INT, PIE3,ERRIE, IPR3,ERRIP

;----{ Invalid Received Message }-------------[PIR3, IRXIF]---
INT_Source CAN_IRX_INT, PIE3,IRXIE, IPR3,IRXIP

;----{ Receive Buffer 0 }------Mode 0--------[PIR3, RXB0IF]---
INT_Source CAN_RXB0_INT, PIE3,RXB0IE, IPR3,RXB0IP
;----{ FIFO Watermark }--------Mode 1, 2---[PIR3, FIFOWMIF]---
INT_Source CAN_FIFOWM_INT, PIE3,FIFOWMIE, IPR3,FIFOWMIP

;----{ Receive Buffer 1 }------Mode 0--------[PIR3, RXB1IF]---
INT_Source CAN_RXB1_INT, PIE3,RXB1IE, IPR3,RXB1IP
;----{ Any Receive Buffer }----Mode 1, 2-----[PIR3, RXBnIF]---
INT_Source CAN_RXBn_INT, PIE3,RXBnIE, IPR3,RXBnIP

;----{ Transmit Buffer 0 }-------------------[PIR3, TXB0IF]---
INT_Source CAN_TXB0_INT, PIE3,TXB0IE, IPR3,TXB0IP

;----{ Transmit Buffer 1 }-------------------[PIR3, TXB1IF]---
INT_Source CAN_TXB1_INT, PIE3,TXB1IE, IPR3,TXB1IP

;----{ Transmit Buffer 2 }-----Mode 0=-------[PIR3, TXB2IF]---
INT_Source CAN_TXB2_INT, PIE3,TXB2IE, IPR3,TXB2IP
;----{ Any Transmit Buffer }---Mode 1, 2-----[PIR3, TXBnIF]---
INT_Source CAN_TXBn_INT, PIE3,TXBnIE, IPR3,TXBnIP

;----{ CAN bus Activity Wake-up }-------------[PIR3, WAKIF]---
INT_Source CAN_WAKE_INT, PIE3,WAKIE, IPR3,WAKIP
endif

list
endm
list
ENDASM

;____[ if not using Low Priority INTS, create a dummy handler ]_______________
ASM
ifndef USE_LOWPRIORITY
INT_ENTRY_L
retfie
else
if (USE_LOWPRIORITY != 1)
INT_ENTRY_L
retfie
endif
endif
ENDASM

;_________________________________________________ ____________________________
Asm
asm = 0 ; Assembly language Interrupts
ASM = 0
Asm = 0
pbp = 1 ; Basic language interrupts
PBP = 1
Pbp = 1
YES = 1
yes = 1
Yes = 1
NO = 0
no = 0
No = 0
H equ 'H' ; High Priority
h equ 'H'
L equ 'L' ; Low Priority
l equ 'L'

nolist

;_________________________________________________ ____________________________
SaveFSR macro F, Pr
list
if (F >= 0) && (F <= 2)
if (Pr == H) || (Pr == L)
movff FSR#v(F)L, fsave#v(F)Pr
movff FSR#v(F)H, fsave#v(F)Pr + 1
nolist
else
ERROR "SaveFSR - Invalid Priority"
endif
else
ERROR "SaveFSR - Invalid FSR number"
endif
list
endm
ENDASM

;_________________________________________________ ____________________________
Asm
RestFSR macro F, Pr
list
if (F >= 0) && (F <= 2)
if (Pr == H) || (Pr == L)
movff fsave#v(F)Pr , FSR#v(F)L
movff fsave#v(F)Pr + 1 , FSR#v(F)H
nolist
else
ERROR "RestFSR - Invalid Priority"
endif
else
ERROR "RestFSR - Invalid FSR number"
endif
list
endm
ENDASM

;---[Stay compatible with the 14-bit version]---------------------------------
Asm
INT_FINISH_H macro
endm
EndAsm

;---[Create the High Priority Interrupt Processor]----------------------------
ASM
INT_CREATE_H macro
local OverCREATE
goto OverCREATE
Priority = H
INT_ENTRY_H
movff PCLATU, psaveUH
movff PCLATH, psaveH
SaveFSR 0, H
SaveFSR 1, H
SaveFSR 2, H
bsf _InHPint, 0
List_Start_H
bcf _Serviced_H, 0 ; Clear Serviced flag
clrf BSR
PREV_BANK = 0
ifdef INT_LIST_H
INT_LIST_H ; Expand the users list of HP INT handlers
else
ifdef INT_LIST
INT_LIST ; Expand the 16F Compatible List
else
error "INT_CREATE_H - INT_LIST or INT_LIST_H not found"
endif
endif
btfsc _Serviced_H,0 ; if anything was serviced
goto List_Start_H ; go around, and check again

ifdef ReEnterHPused ; was ReEnterPBP-18.bas included
GetAddress21 INT_EXIT_H, RetAddrH
L?GOTO _RestorePBP_H ; Restore PBP system Vars
endif

INT_EXIT_H
PREV_BANK = 0
bcf _InHPint, 0
RestFSR 0, H ; Restore FSR0, if it was saved?
RestFSR 1, H ; Restore FSR1, if it was saved?
RestFSR 2, H ; Restore FSR2, if it was saved?
movff psaveH, PCLATH
movff psaveUH, PCLATU
retfie FAST ; Return from Interrupt
OverCREATE
bsf INTCON,GIE, 0 ; Enable High Priority Interrupts
bsf INTCON,PEIE, 0 ; Enable Peripheral Interrupts
endm

;---[Stay compatible with the 14-bit version]---------------------------------
INT_CREATE macro
INT_CREATE_H
endm
ENDASM

;---[Create the Low Priority Interrupt Processor]-----------------------------
ASM
INT_CREATE_L macro
local OverCREATE
goto OverCREATE
ifdef USE_LOWPRIORITY
if (USE_LOWPRIORITY != 1)
error "'DEFINE USE_LOWPRIORITY 1' required for Low Priority Interrupts"
endif
else
error "'DEFINE USE_LOWPRIORITY 1' required for Low Priority Interrupts"
endif
Priority = L
INT_ENTRY_L
movff WREG, wsave ; Wreg
movff STATUS, ssave ; STATUS
movff BSR, bsave ; BSR
movff PCLATU, psaveUL
movff PCLATH, psaveL
SaveFSR 0, L ; FSR0
SaveFSR 1, L ; FSR1
SaveFSR 2, L ; FSR2
bcf _InHPint, 0
List_Start_L
clrf BSR
PREV_BANK = 0
bcf _Serviced_L, 0
ifdef INT_LIST_L
INT_LIST_L ; Expand the users list of HP INT handlers
else
error "INT_CREATE_L - INT_LIST_L not defined, can not create"
endif
btfsc _Serviced_L, 0 ; if anything was serviced
goto List_Start_L ; go around, and check again

ifdef ReEnterLPused ; was ReEnterPBP-18LP.bas included
GetAddress21 INT_EXIT_L, RetAddrL
L?GOTO _RestorePBP_L ; Restore PBP system Vars
endif

INT_EXIT_L
PREV_BANK = 0
RestFSR 0, L ; Restore saved vars
RestFSR 1, L
RestFSR 2, L
movff psaveUL, PCLATU
movff psaveL, PCLATH
movff bsave, BSR ; BSR
movff wsave, WREG ; WREG
movff ssave, STATUS ; STATUS
retfie ; Return from Interrupt
OverCREATE
bsf RCON,IPEN, 0 ; Enable Interrupt Priorities
bsf INTCON,GIEL, 0 ; Enable Low Priority Interrupts
endm
ENDASM

ASM
;---[Returns the Address of a Label as a Word]--(under 64K)------------------
GetAddress macro Label, Wout
CHK?RP Wout
movlw low Label ; get low byte
movwf Wout
movlw High Label ; get high byte
movwf Wout + 1
endm

;---[Returns the Address of a Label as a 3 byte array]---(under/over 64k)-----
GetAddress21 macro Label, Aout
CHK?RP Aout
movlw low Label ; get low byte
movwf Aout
movlw high Label ; get high byte
movwf Aout + 1
movlw upper Label ; get upper byte
movwf Aout + 2
endm

;---[find correct bank for a PBP BIT variable]-------------------------------
CHKRP?T macro reg, bit
CHK?RP reg
endm



;---[find Assigned Priority for specified INT Source]------------------------
INT_Count = 0

FindIntPriority macro IntFlagReg, IntFlagBit
local LoopCount
nolist
Pfound = 0
LoopCount = 1
while LoopCount <= INT_Count
if (IntFlagReg == PrList#v(LoopCount)R)
if (IntFlagBit == PrList#v(LoopCount)B)
list
Priority = PrList#v(LoopCount)Priority
Pfound = 1
endif
endif
LoopCount += 1
endw
endm
ENDASM

ASM

;---[Add an Interrupt Source to the user's list of INT Handlers]--------------
INT_Handler macro IntFlagReg, IntFlagBit, Label, Type, Reset
list
local AfterSave, AfterUser, NoInt
INT_Count += 1
PrList#v(INT_Count)R = IntFlagReg
PrList#v(INT_Count)B = IntFlagBit
PrList#v(INT_Count)Priority = Priority
GetIntInfo IntFlagReg, IntFlagBit
if (Found == YES)
btfss INT_Enable_Reg, INT_Enable_Bit, 0 ; if INT is enabled
goto NoInt
btfss INT_Flag_Reg, INT_Flag_Bit, 0 ; and the Flag set?
goto NoInt
if (Priority == H)
bsf _Serviced_H, 0
else
bsf _Serviced_L, 0
endif
ifdef NO_CLRWDT
if (NO_CLRWDT != 1)
CLRWDT
endif
else
CLRWDT
endif

if (Type == PBP) ; If INT handler is PBP
if (Priority == H)
ifdef ReEnterHPused
GetAddress21 AfterSave, RetAddrH
L?GOTO _SavePBP_H ; Save PBP system Vars in HP INT
else
error "ReEnterPBP-18 must be INCLUDEd to use High Priority PBP interrupts"
endif
else ; Priority = L
ifdef ReEnterLPused
GetAddress21 AfterSave, RetAddrL
L?GOTO _SavePBP_L ; Save PBP system Vars in LP INT
else
error "ReEnterPBP-18LP must be INCLUDEd to use Low Priority PBP interrupts"
endif
endif
endif
AfterSave
PREV_BANK = 0
if (Priority == H)
GetAddress21 AfterUser, RetAddrH
else ; Priority = L
GetAddress21 AfterUser, RetAddrL
endif
L?GOTO Label ; goto the users INT handler

AfterUser
PREV_BANK = 0
if (Reset == YES) ; reset flag (if specified)
bcf INT_Flag_Reg, INT_Flag_Bit, 0
endif
else
error Interrupt Source (IntFlagReg,IntFlagBit) not found
endif
NoInt
clrf BSR
PREV_BANK = 0
endm
ENDASM

asm
;---[Returns from a "goto" subroutine]--(21-bit RetAddr? must be set first)---
INT_RETURN macro
local Ret2LP, Ret2HP
btfsc _InHPint, 0
goto Ret2HP
Ret2LP
movff RetAddrL + 2, PCLATU ; Load PC buffers with return address
movff RetAddrL + 1, PCLATH
movf RetAddrL, W, 0
clrf BSR ; Set to BANK0 before returning
PREV_BANK = 0 ; Tell PBP about the BANK change
movwf PCL, 0 ; Go back to where we were

Ret2HP
movff RetAddrH + 2, PCLATU ; Load PC buffers with return address
movff RetAddrH + 1, PCLATH
movf RetAddrH, W, 0
clrf BSR ; Set to BANK0 before returning
PREV_BANK = 0 ; Tell PBP about the BANK change
movwf PCL, 0 ; Go back to where we were
endm

;---[Enable an interrupt source]----------------------------------------------
INT_ENABLE macro IntFlagReg, IntFlagBit
GetIntInfo IntFlagReg, IntFlagBit
if (Found == YES)
FindIntPriority IntFlagReg, IntFlagBit
if (Pfound == 1)
if (INT_Priority_Reg != -1)
if (Priority == H)
bsf INT_Priority_Reg, INT_Priority_Bit, 0
else
if (Priority == L)
bcf INT_Priority_Reg, INT_Priority_Bit, 0
else
error "INT_ENABLE - Invalid Priority Specified"
endif
endif
else
if (Priority == L)
error "INT0_INT can NOT be assigned to Low Priority"
endif
endif
else
error "INT_ENABLE - Priority State Not Found"
endif
; bcf INT_Flag_Reg, INT_Flag_Bit, 0 ; clear the flag first
bsf INT_Enable_Reg, INT_Enable_Bit, 0 ; enable the INT source
else
error "INT_ENABLE - Interrupt Source not found!"
endif
endm

;---[Disable an interrupt source]---------------------------------------------
INT_DISABLE macro IntFlagReg, IntFlagBit
GetIntInfo IntFlagReg, IntFlagBit
if (Found == YES)
bcf INT_Enable_Reg, INT_Enable_Bit, 0 ; disable the INT source
else
error "INT_DISABLE - Interrupt Source not found!"
endif
endm

;---[Clear an interrupt Flag]-------------------------------------------------
INT_CLEAR macro IntFlagReg, IntFlagBit
GetIntInfo IntFlagReg, IntFlagBit
if (Found == YES)
bcf INT_Flag_Reg, INT_Flag_Bit, 0 ; clear the INT flag
else
error "INT_CLEAR - Interrupt Source not found!"
endif
endm

ENDASM

; ---[See if we need to save TBLPTR]------------------------------------------
ASM
Save_TBLPTR = 0

ifdef SIN_USED
Save_TBLPTR = 1
endif
ifdef DTMFOUT_USED
Save_TBLPTR = 1
endif
ifdef SERDELAY_USED
Save_TBLPTR = 1
endif
ifdef CONVBIT_USED
Save_TBLPTR = 1
endif
ifdef ERASECODE_USED
Save_TBLPTR = 1
endif
ifdef READCODE_USED
Save_TBLPTR = 1
endif
ifdef WRITECODE_USED
Save_TBLPTR = 1
endif
ifdef LOOKDOWN?BCLB
Save_TBLPTR = 1
endif
ifdef LOOKDOWN?BCLT
Save_TBLPTR = 1
endif
ifdef LOOKDOWN?BCLW
Save_TBLPTR = 1
endif
ifdef LOOKDOWN?CCLB
Save_TBLPTR = 1
endif
ifdef LOOKDOWN?CCLT
Save_TBLPTR = 1
endif
ifdef LOOKDOWN?CCLW
Save_TBLPTR = 1
endif
ifdef LOOKDOWN?WCLB
Save_TBLPTR = 1
endif
ifdef LOOKDOWN?WCLT
Save_TBLPTR = 1
endif
ifdef LOOKDOWN?WCLW
Save_TBLPTR = 1
endif
ifdef LOOK2_USED
Save_TBLPTR = 1
endif
ifdef LOOKUP?BCLB
Save_TBLPTR = 1
endif
ifdef LOOKUP?BCLT
Save_TBLPTR = 1
endif
ifdef LOOKUP?BCLW
Save_TBLPTR = 1
endif
ifdef LOOKUP?CCLB
Save_TBLPTR = 1
endif
ifdef LOOKUP?CCLT
Save_TBLPTR = 1
endif
ifdef LOOKUP?CCLW
Save_TBLPTR = 1
endif
ifdef LOOKUP?TCLB
Save_TBLPTR = 1
endif
ifdef LOOKUP?TCLT
Save_TBLPTR = 1
endif
ifdef LOOKUP?TCLW
Save_TBLPTR = 1
endif
ifdef LOOKUP?WCLB
Save_TBLPTR = 1
endif
ifdef LOOKUP?WCLT
Save_TBLPTR = 1
endif
ifdef LOOKUP?WCLW
Save_TBLPTR = 1
endif
endasm

OVER_DT_INTS_18:

ENABLE DEBUG

LinkMTech
- 4th October 2013, 18:17
Hi,
You are on the right track. Darrel did add this interrupt:

; -- Added for ver. 3.3 --
#define RTTCC_INT PIR3, RTCCIF ;-- RTTC


Setup as:

INCLUDE "DT_INTS-18.bas" ; Darrel Taylor's Base Interrupt System
INCLUDE "ReEnterPBP-18.bas" ; Include if using PBP interrupts
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler RTTCC_INT, _Relogio, PBP, yes

endm
INT_CREATE ; Creates the interrupt processor
ENDASM

@ INT_ENABLE RTTCC_INT ; Enable RTCC interrupt


The RTCC interrupt flag is PIR3.0 found in Register 9-6 of the data sheet.

LinkMTech
- 4th October 2013, 20:13
I happen to also be working with the PIC18F24J50 for the RTCC and just tried DT's Interrupts for it and got an error. It may have already been addressed in this thread that has become short of a book but here it is:


Symbol not previously defined (RTTCIP)


Found a typo here:


asm
; -- Added for ver. 3.3 --
ifdef RTCCIF ;----{ RTTC }-------------------------------[PIR3, RTCCIF]---
INT_Source PIR3,RTCCIF, PIE3,RTCCIE, IPR3, RTTCIP
endif
endasm


Data sheet Register 9-12 shows IPR3.0 labeled as RTCCIP, so I changed it to the following and error message gone.


asm
; -- Added for ver. 3.3 --
ifdef RTCCIF ;----{ RTTC }-------------------------------[PIR3, RTCCIF]---
INT_Source PIR3,RTCCIF, PIE3,RTCCIE, IPR3, RTCCIP
endif
endasm


By the way, many thanks to Darrel for this extremely fine piece of work that looks like it took a lot of time and doing then to just give it to everyone.

midali
- 3rd January 2014, 12:02
hi to all,
I'm a beginner , so I need your help , please! .I want to play with 3 LEDs with pwm control . For begin I tried to compile a example from Darrel Taylor's page : http://www.darreltaylor.com/DT_INTS-14/SPWM.html .
the compilation was succesfull for 18F's and work perfectly.
I use MCS 3.0.7.0 and MAPSM v5.42 compiler . I want to compile the sorce code for 12F683 and I have this error:

Error[101] C:\LUCRU\TEST_SPWM_INT.ASM 238 : ERROR: (wsave variable not found,)
Error[101] C:\LUCRU\TEST_SPWM_INT.ASM 204 : ERROR: (" Add:" wsave VAR BYTE $20 SYSTEM)
Error[101] C:\LUCRU\TEST_SPWM_INT.ASM 259 : ERROR: (Chip has RAM in BANK1, but wsave1 was not found.)
Error[101] C:\LUCRU\TEST_SPWM_INT.ASM 211 : ERROR: (" Add:" wsave1 VAR BYTE $A0 SYSTEM)


I use this code :

'************************************************* ***************
'* Name : Test_SPWM.pbp *
'* Author : Darrel Taylor *
'* Date : 9/30/2006 *
'* Version : 1.0 *
'* Notes : *
'* : *
'************************************************* ***************
; Initialize your hardware first

DEFINE OSC 20
CLEAR

INCLUDE "..\DT_INTS-14.bas" ; Base Interrupt System
INCLUDE "SPWM_INT.bas" ; Software PWM module

DEFINE SPWM_FREQ 40 ; SPWM Frequency
DEFINE SPWM_RES 256 ; SPWM Resolution

DutyVars VAR BYTE[3] ; DutyCycle Variables
DutyVar1 VAR DutyVars[0] ; group them in an array for easy access
DutyVar2 VAR DutyVars[1] ; with FOR loops etc.
DutyVar3 VAR DutyVars[2]

ASM
SPWM_LIST macro ; Define PIN's to use for SPWM
SPWM_PIN GPIO, 0, _DutyVar1
SPWM_PIN GPIO, 1, _DutyVar2
SPWM_PIN GPIO, 2, _DutyVar3
endm
SPWM_INIT SPWM_LIST ; Initialize the Pins
ENDASM

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, SPWMhandler, ASM, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM

@ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts

;_________________________________________________ ____________________________

RandVar VAR WORD : RandVar = 12345
LoopCount VAR WORD

Main: ; Simple Demo to fade/flash some LED's
DutyVar1 = 5 ; Start with 3 LED's at different
DutyVar2 = 50 ; brightness
DutyVar3 = 150
pause 3000

FOR LoopCount = 1 to 4 ; Reapeat 4 times
for DutyVar1 = 0 to 150 ; Fade LED1 UP
pause 10
RANDOM RandVar
DutyVar3 = RandVar & $3F ; Give LED3 a random dutycycle
next DutyVar1

for DutyVar1 = 150 to 0 STEP -1 ; Fade LED1 Down
pause 10
RANDOM RandVar
DutyVar2 = RandVar & $3F ; Give LED2 a random dutycycle
next DutyVar1
NEXT LoopCount
GOTO Main




Can somedody help me to finish my ideea ?

1000xthx

Ioannis
- 3rd January 2014, 12:15
The answer is in the Error messages:


hi to all,
Error[101] C:\LUCRU\TEST_SPWM_INT.ASM 238 : ERROR: (wsave variable not found,)
Error[101] C:\LUCRU\TEST_SPWM_INT.ASM 204 : ERROR: (" Add:" wsave VAR BYTE $20 SYSTEM)
Error[101] C:\LUCRU\TEST_SPWM_INT.ASM 259 : ERROR: (Chip has RAM in BANK1, but wsave1 was not found.)
Error[101] C:\LUCRU\TEST_SPWM_INT.ASM 211 : ERROR: (" Add:" wsave1 VAR BYTE $A0 SYSTEM)


It says, " Add:" wsave VAR BYTE $20 SYSTEM
and also " Add:" wsave1 VAR BYTE $A0 SYSTEM

So, your code might look like this now:



'************************************************* ***************
'* Name : Test_SPWM.pbp *
'* Author : Darrel Taylor *
'* Date : 9/30/2006 *
'* Version : 1.0 *
'* Notes : *
'* : *
'************************************************* ***************
; Initialize your hardware first

DEFINE OSC 20
CLEAR

INCLUDE "..\DT_INTS-14.bas" ; Base Interrupt System
INCLUDE "SPWM_INT.bas" ; Software PWM module

wsave VAR BYTE $20 SYSTEM
wsave1 VAR BYTE $A0 SYSTEM

DEFINE SPWM_FREQ 40 ; SPWM Frequency
DEFINE SPWM_RES 256 ; SPWM Resolution

DutyVars VAR BYTE[3] ; DutyCycle Variables
DutyVar1 VAR DutyVars[0] ; group them in an array for easy access
DutyVar2 VAR DutyVars[1] ; with FOR loops etc.
DutyVar3 VAR DutyVars[2]

ASM
SPWM_LIST macro ; Define PIN's to use for SPWM
SPWM_PIN GPIO, 0, _DutyVar1
SPWM_PIN GPIO, 1, _DutyVar2
SPWM_PIN GPIO, 2, _DutyVar3
endm
SPWM_INIT SPWM_LIST ; Initialize the Pins
ENDASM

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, SPWMhandler, ASM, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM

@ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts

;_________________________________________________ ____________________________

RandVar VAR WORD : RandVar = 12345
LoopCount VAR WORD

Main: ; Simple Demo to fade/flash some LED's
DutyVar1 = 5 ; Start with 3 LED's at different
DutyVar2 = 50 ; brightness
DutyVar3 = 150
pause 3000

FOR LoopCount = 1 to 4 ; Reapeat 4 times
for DutyVar1 = 0 to 150 ; Fade LED1 UP
pause 10
RANDOM RandVar
DutyVar3 = RandVar & $3F ; Give LED3 a random dutycycle
next DutyVar1

for DutyVar1 = 150 to 0 STEP -1 ; Fade LED1 Down
pause 10
RANDOM RandVar
DutyVar2 = RandVar & $3F ; Give LED2 a random dutycycle
next DutyVar1
NEXT LoopCount
GOTO Main


Ioannis

midali
- 3rd January 2014, 12:20
1000 X Ioannis ! Now its ok !

midali
- 8th January 2014, 17:35
Hi,
in the last four days I spend my time with play of this code, but now I'm need to your help. I repeat, im begginer and at this time I dont know how work the intrerrupts.
The Darrel Tylor code blink 3 leds at different intensity. I want to turn on 3 leds in background at different intensity without blinking. i tried this code, but leds blinks....where I'm wrong?


Main: ; Simple Demo to fade/flash some LED's
DutyVar1 = 5 ; Start with 3 LED's at different
DutyVar2 = 50 ; brightness
DutyVar3 = 150
GOTO Main

Darrel Taylor
- 8th January 2014, 17:39
That is not enough code to make a whole program.
Please post your entire code.

Also include the PIC you are using and the compiler version.

midali
- 8th January 2014, 18:01
I work with 12F683 and MPASM v5.42.

1000 x thx

Code :

'************************************************* ***************
'* Name : Test_SPWM.pbp *
'* Author : Darrel Taylor *
'* Date : 9/30/2006 *
'* Version : 1.0 *
'* Notes : *
'* : *
'************************************************* ***************
; Initialize your hardware first

DEFINE OSC 20
CLEAR

INCLUDE "..\DT_INTS-14.bas" ; Base Interrupt System
INCLUDE "SPWM_INT.bas" ; Software PWM module
wsave VAR BYTE $20 SYSTEM
wsave1 VAR BYTE $A0 SYSTEM

DEFINE SPWM_FREQ 40 ; SPWM Frequency
DEFINE SPWM_RES 256 ; SPWM Resolution

DutyVars VAR BYTE[3] ; DutyCycle Variables
DutyVar1 VAR DutyVars[0] ; group them in an array for easy access
DutyVar2 VAR DutyVars[1] ; with FOR loops etc.
DutyVar3 VAR DutyVars[2]

ASM
SPWM_LIST macro ; Define PIN's to use for SPWM
SPWM_PIN GPIO, 0, _DutyVar1
SPWM_PIN GPIO, 1, _DutyVar2
SPWM_PIN GPIO, 2, _DutyVar3
endm
SPWM_INIT SPWM_LIST ; Initialize the Pins
ENDASM

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, SPWMhandler, ASM, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM

@ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts

;_________________________________________________ ____________________________

RandVar VAR WORD : RandVar = 12345
LoopCount VAR WORD

Main:
DutyVar1 = 5
DutyVar2 = 50
DutyVar3 = 150

GOTO Main

Ioannis
- 8th January 2014, 18:09
How fast is the led blinking?

Ioannis

midali
- 8th January 2014, 18:20
I apreciate 4-5 blinks/sec

Darrel Taylor
- 8th January 2014, 18:57
1) Are you really using a 20 Mhz crystal?
Not very many people use crystals on an 8-pin PIC.

2) 40 Hz is really slow for LED's
Increase the SPWM_FREQ.

midali
- 8th January 2014, 19:31
I use in config : @_INTRC_OSC_NOCLKOUT . its necessary to use external crystal ?
I increased the SPWM_FREQ at 219 and leds are relativelly well

Darrel Taylor
- 8th January 2014, 19:36
No, it is not necessary to use a crystal.
But your DEFINE OSC must match your actual oscillator frequency.

If you have specified the internal oscillator in your configs, then the default is 4Mhz, not 20Mhz.
And your program is running at 1/5th the speed it is supposed to.

midali
- 8th January 2014, 19:49
Thank you for your help and patience !

midali
- 11th January 2014, 14:10
Can somebody help me with this code for 12F683: ?

I want to blink very quikly a led in background ,independent of my code, random, pause between 1-20 ms. I think that this interval is ok, the best if its possible to set pause limits.
I want learn about intrerupts but i think that I'm too old ...

thx in advance !!

midali
- 11th January 2014, 17:34
...or , how I can make SPWM without intrerupts...?

Demon
- 11th January 2014, 21:05
I want to blink very quikly a led in background ,independent of my code...I want learn about intrerupts but i think that I'm too old...

Try this as an intro to Darrel Interrupts and blinking LED:
http://darreltaylor.com/DT_INTS-14/blinky.html

It's worth the time to practice. His routines make things so much easier and flexible later on as you add more complexity to your code.

Robert

RossWaddell
- 3rd April 2014, 23:21
sougata,

I'm glad it's working out for you. And yes, it is more managable. Kinda the whole idea behind it. :)

Squibcakes,

No, it doesn't work that way.

The AD_INT is fired on the completion of an A/D conversion. Not when the value changes.

So, in your AD_INT handler, you could test to see if the recent A/D reading differs from the previous A/D value. If it does, call a subroutine.

Then start another conversion before exiting the handler.

Added: Or like sougata said, have a timer periodicaly start a conversion, then do the same.

HTH,

I've been using DT_INTS-14 for a while with various types of interrupts but now I want to implement one for A/D. I've created the dummy interrupt handler, but my question is whether I can read the value of the conversion using PBP's ADCIN or should I grab directly from the registers. If the latter, I could use some help with that.

My ADC set up is as follows:



; PIC12F1840

DEFINE ADC_BITS 8 ; Set number of bits in result
DEFINE ADC_SAMPLEUS 5 ; Set sampling time in uS
DEFINE ADC_CLOCK 3 ; Set clock source (3=rc)

FVRCON = 0 ' Fixed Voltage Reference is disabled
ANSELA = %00000010 ; Analog on PORTA.1 (AN1) only
ADCON0 = %00000101 ' ADC (analog-to-digital) is enabled on AN1 (RA1) only
ADCON1.7 = 0 ; Left-justified results in 8-bits

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler INT_INT, _Flash_Mode_Btn, PBP, yes
INT_Handler AD_INT, _ADC_change, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM


' Enable interrupts
@ INT_ENABLE INT_INT ; INT Interrupt
@ INT_ENABLE AD_INT ; A/D Interrupt



I'm working on implementing Darrel's MIBAM with a trim pot to set the brightness of an LED.

RossWaddell
- 3rd April 2014, 23:24
...or , how I can make SPWM without intrerupts...?
Darrel came up with a terrific piece of code for my project - have a look at this thread:

http://www.picbasic.co.uk/forum/showthread.php?t=17299

HenrikOlsson
- 4th April 2014, 06:48
Hi,
I guess you COULD use ADCIN but it kind of defeats the purpose of the interrupt since it is a self timed command.

When using ADC interrupts you basically set the GO/DONE bit to start the converstion and the interrupt fires when the ADC conversion is done. If you then use ADCIN in the interrupt handler it would perform another, self-timed, conversion which, again, kind of defeats the use of interrupts in the first place.

The idea is to start the conversion and then either go to sleep or go do something important while the ADC does its job. The interrupt fires when the conversion is complete and you go grab the result by reading ADRESH/ADRESL register pair.

/Henrik.

RossWaddell
- 5th April 2014, 01:07
Thanks Henrik. I've never done A/D conversion before other than through ADCIN but I guessed it wouldn't make sense to use in an interrupt. I'll have to do a search on 'ADRESH' to see how to read the result when I turn the trim pot dial.

RossWaddell
- 5th April 2014, 02:33
I've set up and ADC interrupt using DT_INST-14 with the following handler code:



' ************************************************** *************
' [A/D - interrupt handler]
' ************************************************** *************
ADC_change:
PAUSEUS 50 ' Wait for A/D channel acquisition time
ADCON0.1 = 1 ' Start conversion
WHILE ADCON0.1 ' Wait for it to complete
WEND
ADCInVal = ADRESH

@ INT_RETURN


Is that right? I just need 8-bit ADC resolution (0-255)

HenrikOlsson
- 5th April 2014, 08:11
Hi,
Well, that too defeats the purpose of using the interrupt in the first place since you trig the conversion and sit around waiting for it to complete while IN the interrupt handler. You could just as well have used ADCIN in the ISR.

One thing we need to get squared away just so we're clear. Your ISR is called ADC_Change and from that I get the feeling that you might think the ADC interrupt fires when the voltage at the input changes - that's not the case. If that was already obvious to you then I appologise, I just wanted to clarify that.

You start the conversion from within your main code or possibly from another ISR, whatever. Then, instead of sitting around waiting for the duration of the conversion you go do something else or go to sleep to provide a quiet environment for the ADC. The interrupt then fires when the conversion is complete and all you need to do in the ISR is grab the result by reading ADRESH, just like you're doing now.

As you probably know using, when using DT-ints, PBP needs to do a whole lot of context saving/restoring when entering/exiting the ISR and this takes time. So it might not even be worth it using interrupts as the time taken to enter and exit the ISR could very well be longer than the ADC conversion time. I don't know for sure, and it depends, just saying..... If reading the result is all you're going to do in the ISR then you can probably get away with an ASM type handler still written in PBP which will be much quicker to get in and out of - but that's always "risky" so lets not go there untill you have something that works and does what you need.

/Henrik.

RossWaddell
- 5th April 2014, 12:37
Thanks for your detailed reply, Henrik. In the past, I've just used a GOSUB in the main loop and in the subroutine call ADCIN and compare the current value to a previous value; if it's different, I use that 8-bit value to set a PWM duty cycle to brighten/dim an LED. For this project, I thought it might be more efficient to set up an AD_INT interrupt which I thought would be triggered whenever I turn the dial on the trim pot and hence slightly more efficient. I think I see now that I'm wrong in what I thought would trigger this interrupt and that I guess I have to go back to the GOSUB approach.

HenrikOlsson
- 5th April 2014, 16:43
Hi,
You don't have to go back to the GOSUB aproach but yes, it does look like you've misunderstood how the ADC interrupt works.
If, for example, you have timer interrupt in your program you could use that to start to AD conversion and then either wait for the conversion or let the ADC trip another interrupt when it's done.

/Henrik.

RossWaddell
- 5th April 2014, 17:46
That makes sense, thanks Henrik. I may tie this to a button so that it's not constantly reading the trim pot - I only want to adjust the LED brightness (PWM duty cycle) infrequently and deliberately.

mpgmike
- 7th April 2014, 17:20
Wow! 7 years & still adding pages! A conversation with Daryl led me here. I want to have an event occur just prior to the end of a PWM period. I was told it had to be done in assembly. My project is based on the PIC16F1828, uses CCP for PWM, DSM (Digital Signal Modulation) to embed HF within a slower PWM clock, and just before the Off/On I need to trigger an event. Got it working thanks to Daryl. Here's what it looks like:

http://i223.photobucket.com/albums/dd270/mpgchris/246_zps91083c15.jpg (http://s223.photobucket.com/user/mpgchris/media/246_zps91083c15.jpg.html)

The code looks like this:


define OSC 32
define ADC_BITS 8
define ADC_CLOCK 3
DEFINE ADC_SAMPLEUS 50

#CONFIG
CONFIG1_FOSC_INTOSC
CONFIG1_MCLRE_OFF
CONFIG1_CLKOUTEN_OFF
CONFIG2_PLLEN_ON
#endconfig

OSCCON = %11110011
TRISA = %00111100
TRISB = %01100000
TRISC = %11001011
ANSELA = %00011111
ANSELB = %01100000
ANSELC = %11001011
WPUA = 0
WPUB = 0
WPUC = 0
MDSRC = %10000010 'DSM Activated (.7) on CCP1 (RC5) (<3:0>
MDCARH = %10000011 'OOK Mode
MDCARL = %10100000 'Disables Low Carrier Signal; OOK Mode
MDCON = %11000000 '.7 Enables OOK, .3 Current State (read only)
CLKRCON = %10110000

b0 var byte
b1 var byte
b1 = 0
LED1 VAR PORTC.5
TPS_In var PORTC.7 'AN9

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 TMR2_INT, _SetTR4, PBP, yes
INT_Handler TMR4_INT, _GP, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM

'T1CON = %00110001 ; Prescaler=8, TMR1ON
@ INT_ENABLE TMR2_INT ; enable Timer 2 interrupts

Main:
adcin 9, b0
hpwm 1, b0, 1056
PAUSE 1
GOTO Main

'---[TMR1 - interrupt handler]--------------------------------------------------
SetTR4:
T4CON = T2CON
PR4 = PR2
TMR4 = TMR2 - 246
@ INT_ENABLE TMR4_INT
@ INT_RETURN
GP:
pulsout PORTC.5, 5
@ INT_DISABLE TMR4_INT
'@ INT_CLEAR TMR1_INT
@ INT_RETURN

end


All I can say is, I'm so glad I found ME Labs and now this forum. Overwhelming thanks to Charles, Daryl, and many whose work I've gleened from, but have yet to get to know personally.

Mike

ShoKre
- 17th July 2014, 08:53
Hi, is there any known error /workaround for using eeprom "read"(didn't test write) while @ INT_ENABLE TMR1_INT ; Enable Timer 1 Interrupts ?
I use 16f1827, if I comment INT_enable line, all works great, but if line is enabled, read command return same index instead value
i experimented with putting int_disable before read int_enable after, putting some pause between disabling/enabling GIE before/after read
but nothing give me result, only when INT_enable commented, never executed, then works...

Dave
- 17th July 2014, 12:05
ShoKre, I have never had a problem using the READ and WRITE commands while having the interrupts enabled. I have used it with 18F8722, 18F67k22, 18f46k22, 18f4620, 18f452, 16f1825, 18f1320, 16f88, 12f1840.
Maybe you should post some code and we here can have a look?

ShoKre
- 17th July 2014, 13:14
i figured out what interfere, i have readcode command in my (basic)ISR, and read in main-loop, after i commented readcode in isr read in main-loop has began to work, so, now i have to find another way
for reading LED gamma table in isr, or pattern eeprom in main, at least I found what interfere, and the way will come, maybe put read in isr too.... there is more than 500ln of code so it will probably make
treed dirty with non important/regarded stuff...
..it is good to know that there isn't other problems with dt-ints and read.
...found interesting or sad errata for 16f1827 http://ww1.microchip.com/downloads/en/DeviceDoc/80485G.pdf so ih you bught chip with 1M/100k read write eeprom/flash, you actually get 1k/10k :), good to know for save lifespan with fewer writes... i was reading that when couldn't read eeprom...
(sorry for my bad English if sentences sometime don't have sense :)

thanx anyway,

pickup
- 1st November 2014, 22:31
Hi all

Could anybody help me with a problem I'm having with using instant interrupts "Thanks to Darrel for all his work" and the IC3 module of the PIC18F2431
I can get IC1 (CAP1) to work OK also IC2(CAP2) but when I compile using IC3 (CAP3) I get the following errors.

Symbol not previously defined (IntFlagReg)
Symbol not previously defined (IntFlagBit)
ERROR: (Interrupt Source IntFlagReg,IntFlagBit) not found)

Following is a snip-it from parts of the program and if I substitute IC3DRIF_INT for IC1IF_INT or IC2QEF and change the CAP3BUF's for 1 or 2 every thing works OK.

I've tried every thing I can think of but not bright enough to sort this out.
Using PBX 3.0.4.1


INT_Handler IC3DRIF_INT

INT_LIST macro ;IntSource, Label, Type, ResetFlag?

INT_Handler IC3DRIF_INT, _InputSignal, ASM, yes

@ INT_Handler IC3DRIF_INT

InputSignal: 'Input pulse width capture of CAP3


ReciverOutput.lowbyte = CAP3BUFL
ReciverOutput.highbyte = CAP3BUFH

Passthrough = ReciverOutut


Thanks in advance Geoff

Demon
- 2nd November 2014, 02:08
Totally wild guess, Darrel's routine only has code for #1 and 2. Can't check includes and asm files from my phone, but I'd start there.

Robert

richard
- 2nd November 2014, 04:42
have a look at these threads with dt's guidance I added unsupported interrupts to dt_int18
http://support.melabs.com/threads/392-Dt-ints-18-with-pic18f248
http://support.melabs.com/threads/320-DT-INTS-18-WITH-PIC18F25K22-TMR4-int-ERROR

HenrikOlsson
- 2nd November 2014, 08:49
Hi,
I think the problem is that you're mixing up the names of the interrupt source and the interrupt handler. The interrupt source is called IC3DRIF_INT - you can't call the interrupt handler that as well. This compiles just fine:

Include "DT_INTS-18.pbp" 'Include the interrupt system files.

ASM
INT_LIST macro ;IntSource Label Type ResetFlag
INT_Handler IC3DRIF_INT, _InputSignal, ASM, yes
endm
INT_CREATE
ENDASM

@ INT_ENABLE IC3DRIF_INT

Main:
Toggle PortB.0
Pause 500
Goto Main


InputSignal:
@ NOP
@ INT_RETURN

/Henrik.

pickup
- 2nd November 2014, 16:50
Hi all
Thanks Henrik, Richard and Demon for the response with my problem, it is much appreciated.
It turns out Henrik spotted the problem and it is now sorted. Being lazy I copied and pasted a line for the interrupt enable from the handler line but didn't change from Handler to Enable as Henrik spotted. I then spent a week of evenings trying to find the problem, it is true sometimes you cannot see the wood for the trees.
Thanks again Geoff.

ecoli-557
- 2nd November 2014, 18:01
Good Afternoon All-
I have gone through this thread and apologies if this is not the correct place for me to post this question;
I have a home project in which I want to use 2 USARTs for my humble home automation idea. I know that DT's interrupts-18 will handle 2 serial ports and have used it - works quite well and again Kudos to DT!
The chip I want to use is the 16F1527 which looks to be a great choice, capable and cheap!
I see by DT's site that there is no 2nd serial interrupt as in the -18. In looking through DT_INTS-14 I do not see one either.
My question, is there a way (surely?) to add this to DT_INTS-14?
I read a post in where you can add an interrupt on change but I am not experienced enough to see how I might apply this philosophy to the 2nd serial port.
Any advice would be greatly appreciated.
BTW, after reading all 19 pages of this thread, my cap will no longer fit on my head - its swollen <grin>........
Regards to All.