PDA

View Full Version : Instant Interrupts Questions



JosueCas
- 9th February 2006, 23:26
Hi!!
This was a great piece of code, I tried both the elapsed timer and the multiple interrupt code, both worked perfectly!!! GREAT POST!!

But i couldnt find any info in using the other interrupts, how much do i have to configure to use them, i am trying to use USART RX_INT but it dont seems to work for me, my code (Darrel´s? :D):

LED1 VAR PORTB.1

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


DEFINE HSER_RCSTA 90h
DEFINE HSER_TXSTA 20h
DEFINE HSER_BAUD 9600
DEFINE HSER_CLROERR 1


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


@ INT_ENABLE RX_INT ; enable Timer 1 interrupts

Main:
PAUSE 1
GOTO Main

ToggleLED1:
TOGGLE LED1
@ INT_RETURN


Thanks for any HELP

Darrel Taylor
- 10th February 2006, 04:49
Hi JosueCas,

Thanks! Nice to know it's working!

I'm still trying to write up a good explanation of how it all works. That's why the thread is still closed. Hopefully I can answer most of the questions there.

But in your case, the RX interrupt works a little different. It's Flag bit gets reset by hardware whenever you read from the RCREG register, and can't be reset by software.

So inside a RX interrupt routine you MUST read from RCREG, or you'll end up in an Continuous Interrupt Loop.

Also, the HSER defines only work if you are using PBP's HSERIN/OUT, so the USART must be set up manually. OR, you can use this macro...
'--[ Initialize USART for specified baud rate at current OSC speed ]------------
ASM
USART_Init macro Baud
CHK?RP TXSTA
clrf TXSTA
_SPBRG = (OSC * 1000000) / 16 / Baud - 1 ; calc SPBRG @ High baud rate
if _SPBRG > 255 ; if SPBRG is too high
_SPBRG = (OSC * 1000000) / 64 / Baud - 1 ; calc for Low baud rate
bcf TXSTA, BRGH ; Set BRGH to Low Speed
if _SPBRG > 255
_SPBRG = 255
endif
else
bsf TXSTA, BRGH ; Set BRGH to High Speed
endif
bsf TXSTA, TXEN ; Set Transmit Enable bit
movlw _SPBRG
CHK?RP SPBRG
movwf SPBRG ; load the calulated SPBRG
movlw B'10010000' ; enable USART
CHK?RP RCSTA
movwf RCSTA
endm
ENDASM


Then to initialize the USART, just do this...
@ USART_Init 9600With this macro you can also change the baud rate at any time. Unlike the Define's.
<br>

Josuetas
- 18th February 2006, 17:13
You where right, tx a lot, the most important isue was with the configuration, i used a simple Hserout [0] at the begining and it all worked.

By the way!, i cant get the interruption system to work either in my 18f452 or in my 16f628, in 628 it says something like wsave5 being in the wrong bank, i am not at home right now. What must be done to work with different devices? I REALLY LIKE THIS STUFF!!!

Thanks AGAIN!

Darrel Taylor
- 18th February 2006, 21:28
My pleasure Josue,

The program currently only works with 14-bit cores, so for now, it won't work with 18-F's.

For the 628,
Although it has 4 banks, bank 3 doesn't have any General Purpose Registers in it. This causes one of the variable assignments to fail.
It does have access memory that's common to all banks at $70 which can be used instead.

Open the DT_INTS-14.bas file, and at the top you should see this section...
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
' ------------------------------------------------------------------------------
Comment out all the wsave? lines, and un-comment the 'wsave var byte $70

Then you should be good to go.
<br>

Josuetas
- 22nd February 2006, 01:05
Hi, i spent the last couple of days with a program that uses 6 interruptions, i am glad to say that everything works fine until now. I am using RX, TX, Timer0, Timer1, INT and portB interrupts. I REALLY DONT KNOW HOW I MADE IT BEFORE THIS STUFF!!.

I didn´t wanted to start a new post so i will use this conversation and all your knowledge and disposition with me to move on the questions.

1. How do you disable/reenable an interrupt? i mean in this system and to avoid using registers.
2. Is there any constrain about the handlers lenght? i am using a very large RX handler that seems to work by now, is it better to go to subroutines from the handler to come back later and make the codespace of the handler small?
3. Out of topic but really interesting to me, how can i work with an array? for example an 8 rows x 10 bytes array? is there any way in pbp (i have read the manual but there is nothing about it).
4. How can i avoid filling my memory program with LCDOUT sentences? they seem to be very consuming... :p
5. What is the difficulty about using this system in 18f452 like devices, i recall using interrupts in them and it was much more easier than in the 877.
6. To many questions? :D cause i got one more.. also offtopic
7. I am using a matrix keyboard with portbchange interruption, but i am losing time (missing the tmr1 int) while i wait for the user to release at the kb, any other great piece of code you have under your pillow to help me solve this?.


By the way i could solve the issue with the 628, you will have to make a MANUAL for this :D, maybe i can end up doing it for you

Thanks a loTTTT

Darrel Taylor
- 22nd February 2006, 04:06
>> 1. How do you disable/reenable an interrupt? i mean in this system and to avoid using registers.

There are 2 macros, INT_ENABLE and INT_DISABLE.
@ INT_DISABLE TX_INT ; Disable USART Transmit interrupt
@ INT_ENABLE TX_INT ; Enable USART Transmit interrupt
@ INT_DISABLE INT_INT ; Disable external INT interrupt
>> 2. Is there any constrain about the handlers lenght?

The biggest thing to worry about is Time. &nbsp; If the interrupt handler takes a long time to do something, you run the risk of missing other interrupts. &nbsp; In general, the interrupt handler should be as short as possible, and it should NEVER contain pauses or routines that wait for something external to happen.

This forces you to think a little differently when writing interrupt driven programs. For instance, for USART RX, the interrupt handler should only be receiving the byte and placing it in a buffer. Don't try to HSERIN a whole string because it will take too long.

After placing the byte in a buffer, you would set a Flag to indicate that a byte is waiting, then somewhere in the main loop, the program should test that flag to see if it needs to do something with the data that has arrived.

As another example, say you measure a pulse width using Capture Mode. The interrupt handler will only grab the CCP1H:CCP1L value and save it to a variable, to be processed later in the main program. Attempting to Calculate the Actual Pulse width with complex formulas will take many hundreds, or even thousands of instruction cycles to complete, and any other interrupts that happen in the mean time will be lost.

>> 3. ...how can i work with an array? for example an 8 rows x 10 bytes array?

PBP doesn't have Multi-Dimensioned arrays, but it's easy enough to just make one big array and calculate the offset into it to accommodate the Rows.
array VAR BYTE[80]
Row VAR BYTE ' 0-7
COL VAR BYTE ' 0-9
Temp VAR BYTE

Row = 4
Col = 8
Array(Row*10+Col) = 69 ' Put 69 in Array(4, 8)
Temp = Array(Row*10+Col) ' Get value of Array(4, 8)

>> 4. How can i avoid filling my memory program with LCDOUT sentences?

http://www.picbasic.co.uk/forum/showthread.php?t=1999


>> 5. What is the difficulty about using this system in 18f452 like devices

The 18F interrupts can have either a High or Low priority. A high Priority interrupt can interrupt a Low priority interrupt that has already triggered. &nbsp; This presents some HUGE problems for the Instant Interrupt system, especially when using PBP Ints. The problems are not insurmountable, just HUGE.

>> 6. To many questions?

Yes. :eek:

>> 7. I am using a matrix keyboard with portbchange interruption, but i am losing time (missing the tmr1 int) while i wait for the user to release at the kb

Again, never wait for anything in an interrupt handler. With RBC_INT, you'll start with all PORTB 3:0 set to Output Low, so that when the user presses a button you will get an interrupt. At this point scan the keypad real quick to see which button was pressed. Then set the bottom 4 bits back to Low again. Now, Read PORTB one more time before exiting (very important) to end any mis-match condition.

When the user releases the key, you will get another interrupt. Do the same thing again. But this time you should scan that no keys are pressed. Keep track of the Presses and Releases in the routine. Of course de-bouncing becomes more difficult too.

<br>

Josuetas
- 22nd February 2006, 17:53
Ok, I will get my hands to work.
It seems like i will have to rewrite most of my code as i began to have problems just today before reading your post.
i will surely have all your answers in mind,

TX Again,


Yoshua

jheissjr
- 24th February 2006, 06:37
Even though the interrupts for 18F's are more complicated, do you plan on making the code work for them sometime in the future. I wish I was fortunate enough to know assembly as well as you do. I have been reading in the 18F datasheets and they say you can enable and disable the interrupt priority feature. Would disabling the priority make it more doable. Or if not, maybe something like setting all the interrupts to either high priority or to all low priority. Anything I can do to convince you to do take on the task for us :)

jheissjr
- 24th February 2006, 07:37
An exert from an 18F datasheet:

When the IPEN bit is cleared (default state), the interrupt priority feature is disabled and interrupts are compatible with PICmicro mid-range devices. In
Compatibility mode, the interrupt priority bits for each source have no effect. INTCON<6> is the PEIE bit, which enables/disables all peripheral interrupt sources. INTCON<7> is the GIE bit, which enables/disables all interrupt sources. All interrupts branch to address 000008h in Compatibility mode.

Darrel Taylor
- 1st March 2006, 22:22
Yes, you can make an 18F work like a 16F.

But why buy a Ferrari, if it comes with a 60mph governor?

Actually, I already have it working like that. But, I don't want to release a crippled version.

Patience.
<br>

Josuetas
- 1st March 2006, 22:34
Hi Darrel, i certainly agree with your idea of using interrupts priority, but for the moment i would really find useful this system in 18F devices as i need for example more code (32K) or even the USB port.

My 16f877 is full even with the method of storing strings in the code space.

By the way, i am also looking to make my project to PRINT in a standard ASCII characters printer, can you give me any advice?, an easy link?. Thanks!!.

Darrel Taylor
- 1st March 2006, 23:05
This might help with the printer part...
http://www.picbasic.co.uk/forum/showthread.php?t=218
<br>

jheissjr
- 2nd March 2006, 02:05
I would like to use the 18F because it has a large amount of RAM and code space. Other wise I agree, I would be using a 16F. Would you mind releasing the 'governed' version of what you have so far.

modifyit
- 14th March 2006, 01:24
Is the INT_INT interupt the pin B0 interrupt? If so, does the interupt trigger on the falling or rising edge?

In the example I am working with I am using an 16F877a

Thanks

Darrel Taylor
- 14th March 2006, 02:47
Yes, that's the pin.

By default, it interrupts on the Rising Edge. But it depends on the INTEDG bit in the OPTION_REG.

OPTION_REG.6 = 0 ' INT on Falling Edge
<br>

modifyit
- 14th March 2006, 05:01
So do I just put the register declaration right after the inlcude file definitions or do I need to imbed it in your files some how? I'm looking to triger based on a falling edge.

Thanks again

Darrel Taylor
- 14th March 2006, 07:30
As long as you put it somewhere before the @ INT_ENABLE INT_INT you should be OK.

<br>

modifyit
- 14th March 2006, 14:03
So using your example I should put the option_reg declaration where I have it in your example below if I want the interupt to occur on the falling edge? I will try this tonight thanks alot!




LED1 VAR PORTB.1

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

OPTION_REG.6 = 0 ' INT on Falling Edge

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler INT_INT, _ToggleLED1, PBP, yes
endm

INT_CREATE ; Creates the interrupt processor

INT_ENABLE INT_INT ; enable external (INT) interrupts

ENDASM

Main:
PAUSE 1
GOTO Main

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

Darrel Taylor
- 14th March 2006, 23:23
That should work.

Just be sure to indent the INT_CREATE and INT_ENABLE lines. You'll get an error if they are in column 1.
<br>

Josuetas
- 18th March 2006, 16:30
Well it seems i got to a dead end, i have most of my work done but now i am out of RAM in my 16f877A, i now HAVE TO migrate to 18f452, so i will have to do it on assembler which i really dont now very well.

I am using portb, timer0 and RX interrupts.

I made it to work the timer int once in this device but i have never used multiple interrupts on it, what has to be done? check flags to see which was the last interrupt? (i dont know ASM), if so, should i manage the interrupt at once or send it to other independent subroutines.

I really am close to cry, all my work and happy moments with this Instant interrupt system seem to come to an end, even more all the work done seems to be useless.

Please help me.

dhouston
- 2nd April 2006, 16:02
Can Instant Interrupts be used with the 12F683? If so, what changes are needed in the Include files?

paul borgmeier
- 3rd April 2006, 20:37
Josuetas,

Although I have no clue what you are trying to do – you may want to consider the following: The 877A has 256 bytes of EEPROM (w/ 1,000,000 read write cycle life).

You said you were out of RAM? All 368 bytes? I cannot imagine needing immediate access to all of these bytes. Consider reusing some RAM and tuck away the answers in EEPROM and retrieve and replace when needed? See example below.

*** Old Way ***

X var byte
Y var byte
Z var byte

X = 1
Y = 2
Z = 3

If X > 4 then DoSomething1
If Y > 1 then Y = 6
If Z > 6 then DoSomething3

*** New Way ***

Data @1,1,2,3

X Var byte

Read 1,X
If X > then 4 then DoSomething1
Read 2,X
If X > 1 then
Write 2, 6
Endif
Read 3, X
If X > 6 then DoSomething

***

The “New Way” used 1/3 the RAM of the “Old Way”. I think you get the idea. Could this work to save RAM and your past work?

Good Luck,
Paul Borgmeier
Salt Lake City, Utah
USA

jheissjr
- 4th April 2006, 00:40
I would like to save the NMEA strings coming out of my GPS receiver as they arrive at the PIC. The GPS has a refresh rate of 1 Hz and sends out 450 bytes each second. I would like to be able to capture and hold the bytes as they arrive.

I don't think I can save these bytes in EEPROM because of the 10 ms time it takes to read/write each byte to EEPROM. The serial data would be arriving at the PIC faster then the EEPROM can save it (at 4800 bps, a new byte arrives every 1.7 ms). Do you possibly have any suggestions?

Josuetas
- 4th April 2006, 15:54
That is my other problem already, i have a 16k words code already, thanks for your concern but your code is much, much, much larger!.
I will have to do it with asm although i have no idea of how to do it yet, does anyone have good and simple example ofmultiple interrupt handling?.

Waiting for 18x version of DT-INTXX.bas

Tx in ADVANCE