Searching \ for '[PIC]: mcc18 and interrupts on the PIC18F8525' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: piclist.com/techref/microchip/ints.htm?key=interrupt
Search entire site for: 'mcc18 and interrupts on the PIC18F8525'.

Exact match. Not showing close matches.
PICList Thread
'[PIC]: mcc18 and interrupts on the PIC18F8525'
2005\08\05@175540 by Andrew Kilpatrick

flavicon
face
Hi,

I'm working on a project with the PIC18F8525 using the mcc18 compiler.
There seem to be some weird behaviours when using code in interrupts
mixed with code running in the mainline. It seems that there is some
sort of interference between variables running in the interrupt vs.
variables in the mainline. Sometimes apparently innocent variables in
either routine (like an index variable in a for loop) get clobbered.

Only high priority interrupts are in use, so from what I've read that
means that the appropriate registers get backed up automatically. The
compiler seems to add some more code to back up other variables too. But
stuff happens that shouldn't. By rearranging which parts run in the
interrupt, I can affect what parts of my program get messed up, but I
can't really explain what's happening very well. If I run everything in
the interrupt or the mainline it all seems to work fine. But this is not
good for my application which needs to do some things on an accurate
time and some other more intensive procedures in the background.

Another related question.... is it safe to modify variables from an
interrupt that are being used in the mainline? Is there any point at
which an undesired value could exist in the register? My interrupt runs
a matrix keyboard/LED scanning routine on a timer so that the LEDs are
multiplexed properly. The keyboard data is read in the interrupt and
processed (for debouncing, etc.) in the mainline. But this sometimes
causes erroneous behaviour.

Any help would be greatly appreciated. My mind is so wrapped up in this
that I might be forgetting to explain everything... Please ask and I
would be glad for your help.



Andrew

2005\08\05@221632 by Oscar T.

picon face
> Only high priority interrupts are in use, so from what I've read that
> means that the appropriate registers get backed up automatically. The

If things hasn't changed, the compiler only saves "a basic context"
(see section 3.4 of the compiler's manual for a complete list), but
for some weird reason it does not consider some registers as PROD,
TBLPTR,...,  part of the "basic ones", although it uses them at its
wild as temporally variables. So you end catched by corrupting them
inadvertely.

If my memory doesn't leak, the < save = section ("MATH_DATA") > option
will instruct the compiler to save all them.

> Another related question.... is it safe to modify variables from an
> interrupt that are being used in the mainline? Is there any point at
> which an undesired value could exist in the register? My interrupt runs

It depends ...

> a matrix keyboard/LED scanning routine on a timer so that the LEDs are
> multiplexed properly. The keyboard data is read in the interrupt and
> processed (for debouncing, etc.) in the mainline. But this sometimes
> causes erroneous behaviour.

... how you implement it.


Oscar

2005\08\06@003223 by Andrew Kilpatrick

flavicon
face
> If things hasn't changed, the compiler only saves "a basic context"
> (see section 3.4 of the compiler's manual for a complete list), but
> for some weird reason it does not consider some registers as PROD,
> TBLPTR,...,  part of the "basic ones", although it uses them at its
> wild as temporally variables. So you end catched by corrupting them
> inadvertely.
>
> If my memory doesn't leak, the < save = section ("MATH_DATA") > option
> will instruct the compiler to save all them.

Aha! I knew there must be something like this. I'll give it a shot.

>>a matrix keyboard/LED scanning routine on a timer so that the LEDs are
>>multiplexed properly. The keyboard data is read in the interrupt and
>>processed (for debouncing, etc.) in the mainline. But this sometimes
>>causes erroneous behaviour.

I use a keyboard matrix using transistor pulldowns on the rows (12 rows)
and columns pulled up with resistors to read the key inputs (6 columns)
processed through some comparators to make the signals look TTL again
due to voltage drop over the row drivers. At the same time the row
drivers double as LED drivers. I have also 6 LED columns using push-pull
drivers to pulse the LEDs at high current.

During the interrupt the LED rows are scanned and the keyboard inputs
are stored into an array. (one element per row) In the mainline the
keyboard inputs are processed for change and debounce, etc. and key
up/down changes are sent to the host over the USART. Meanwhile my
program is also taking care of a number of other peripherals which are
less timing sensitive.


Andrew

2005\08\06@032237 by Oscar T.

picon face
By the way, read the compiler's readme file, there was/is some bug
about the compiler not returning long structures/variables in an
interrupt safe way.

> I use a keyboard matrix ....
>                                        .... of a number of other peripherals which are
> less timing sensitive.
>

That seems ok, but what is it the erroneous behaviour?

Oscar

2005\08\06@114119 by Andrew Kilpatrick

flavicon
face

Oscar T. wrote:
>>I use a keyboard matrix ....
>>                                       .... of a number of other peripherals which are
>>less timing sensitive.
>>
>
>
> That seems ok, but what is it the erroneous behaviour?
>
> Oscar

Sometimes keys get detected that haven't been pressed. I suspect this is
some sort of interrupt-based problem. Some variable involved is getting
corrupted, or something like that. It doesn't exhibit this behaviour if
I don't use interrupts. That's why I'm suspecting that not all the
registers are properly saved before entering the interrupt handler.


Andrew

2005\08\06@160345 by Oscar T.

picon face
Also don't forget to declare as volatile, any variable used in both
mainline an interrupt.You may also need todo double buffering, or just
drop out scancodes when the last one is still processing.

Oscar.

2005\08\08@014321 by Chen Xiao Fan

face
flavicon
face
Have you read the errata of the chip? Quite some of the chips
like 18FUSB parts are affected by the bug in interrupt. I am
not so sure about 18F8525 though. Maybe they suffer the
same bugs.

Regards,
Xiaofan

>From 18F USB errata: DS80220A.

4. Module: Interrupts
If a high priority interrupt occurs during a two-cycle
instruction that modifies the STATUS, BSR or
WREG register, the unmodified value of the
register will be saved to the corresponding Fast
Return (Shadow) register and upon a fast return
from the interrupt, the unmodified value will be
restored to the STATUS, BSR or WREG register.
For example, if a high priority interrupt occurs
during the instruction, MOVFF TEMP, WREG, the
MOVFF instruction will be completed and WREG
will be loaded with the value of TEMP before
branching to ISR. However, the previous value of
WREG will be saved to the Fast Return register
during ISR branching. Upon return from the
interrupt with a fast return, the previous value of
WREG in the Fast Return register will be written to
WREG. This results in WREG containing the value
it had before execution of MOVFF TEMP, WREG.
Affected instructions are:
MOVFF Fs, Fd
where Fd is WREG, BSR or STATUS;
MOVSF Zs, Fd
where Fd is WREG, BSR or STATUS; and
MOVSS [Zs], [Zd]
where the destination is WREG, BSR or STATUS.

Work around
1. Assembly Language Programming: If any twocycle
instruction is used to modify the WREG,
BSR or STATUS register, do not use the
RETFIE FAST instruction to return from the
interrupt. Instead, save/restore WREG, BSR
and STATUS via software in the same manner
as is done with low priority interrupts.
Alternatively, in the case of MOVFF, use the
MOVF instruction to write to WREG instead.
2. C Language Programming: The exact work
around depends on the compiler in use. Please
refer to your C Compiler documentation for
details.
If using the Microchip MPLAB® C18 C Compiler,
define both high and low priority interrupt
handler functions as "low priority" by using the
pragma interruptlow directive. This
directive instructs the compiler to not use the
RETFIE FAST instruction. If the proper high
priority interrupt bit is set in the IPRx register,
then the interrupt is treated as high priority in
spite of the pragma interruptlow directive.
The following code snippet demonstrates the
work around using the C18 compiler:

#pragma interruptlow MyLowISR
void MyLowISR(void)
{
// Handle low priority interrupts.
}
// Although MyHighISR is a high priority interrupt, use interruptlow pragma
so that
// the compiler will not use retfie FAST.
#pragma interruptlow MyHighISR
void MyHighISR(void)
{
// Handle high priority interrupts.
}
#pragma code highVector=0x08
void HighVector (void)
{
_asm goto MyHighISR _endasm
}
#pragma code /* return to default code section */
#pragma code lowVector=0x18
void LowVector (void)
{
_asm goto MyLowISR _endasm
}
#pragma code /* return to default code section */

{Original Message removed}

More... (looser matching)
- Last day of these posts
- In 2005 , 2006 only
- Today
- New search...