Re: 16F628 Interrupt problem - help!

From: Anthony Fremont (spam_at_anywhere.com)
Date: 01/08/05


Date: Sat, 08 Jan 2005 21:05:19 GMT

Mark Jones wrote:
> Anthony Fremont wrote:
>> "Rob" wrote
>>
>>
>>> Snipped original post content
>>>
>>>
>>>> ~ Your LED2_PULSE and LED1_OFF, what do they do?
>>>>
>>>> ~ The optical encoder, is it measuring something fast? Precise?
>>>> Or is it just being used as a knob? (100ms sample rate is much
>>>> easier to deal with than 2kHz.)
>>>>
>>>> ~ The general rule of thumb regarding ISR's & PICs is A) 95% of
>>>> the time they are not needed, B) they should be very short,
>>>> and C) all port activity has to be double-buffered. (Think,
>>>> what happens if an interrupt occurs while a port is being
>>>> modified?)
>>>>
>>>>
>>>> ~ That said, if the encoder is suppling a very fast interrupt,
>>>> what happens if another interrupt occurs before the line ~ BCF
>>>> INTCON,INTE ;DISABLE RBO INTERRUPT ~ ?
>>>>
>>>
>>>
>>> Thanks for the reply Mark.
>>>
>>> The LEDs are just being turned on/off for test purposes. The
>>> encoder runs very slowly - it is to be used to measure a slowly
>>> changing mechanical position, << 500 Hz encoder pulse rate (500
>>> slot encoder wheel). The application is battery powered hence the
>>> need for the extra glue logic to power up and sample the encoder
>>> periodically.
>>>
>>> Re point C, can you please elaborate on "double buffering" port
>>> read/writes - I don't understand what you mean by this.
>>
>>
>> He was referring to keeping a "shadow" ram location that represents
>> the value of an ouput port. You then set and reset individual
>> bits within the shadow register and move the whole shadow register
>> to the output port, instead of flipping bits directly on the output
>> port. This avoids potential Read/Modify/Write issues having to do
>> with the way the PIC ports are designed. These issues are
>> generally associated with highly loaded output pins and/or fast
>> clock speeds.
>>
>> When you flip an output bit on a PIC, the whole port is read, a
>> single bit is modified, and the whole port is re-written. With
>> heavily loaded pins, or in the case of not allowing enough settling
>> time after changing a pins state, the pin state can be misread. It
>> will consequently be re-written with the incorrect value resulting
>> in the appearance of output pins mysteriously changing themselves
>> when other pins on the same port are changed.
>>
>>
>>> I was of the understanding that as soon as an interrupt occurs
>>> the GIE bit was cleared - preventing futher interrupts being
>>> registered, so the problem of an interrupt occuring before the
>>> line "BCF INTCON,INTE" would not be an issue - am I incorrect on
>>> this?
>>
>>
>> Your interpretation is correct, Mark appears to be somewhat
>> unfamiliar with PICs.
>
> No, it's just that I avoid ISR's because of all the inherent trouble

What inherent trouble with PIC ISR's are you referring to, or are you
talking about ISR's in general? I happen to love using interrupt
handlers, they are quite beneficial to have IMO. ;-) I like to use
them for serial i/o, button press sensing, or virtually anything that
involves some kind of unpredictable input. They are also good for
performing repetitive tasks on a precise interval (like switch
debouncing, or even polling ;-) The whole key is in saving and
restoring context properly for the main level and setting up the correct
context for the ISR. Also, it's good to keep in mind when writing your
code that an interrupt can (and eventually will ;-) occur between any
two instructions of your program.

You should try to stop avoiding them. Once you get the hang of it, you
will begin to see more and more applications for them vs. polling at
mainlevel. I tend to use allot of circular queues for my projects,
usually stuffing data in them in an ISR and then pulling it out at
liesure during main level processing.

> with them. It's been so long, I'd forgotten GIE was automatically
> cleared. It's just as easy most of the time to check for things in the
> main program loop anyways.

Polling is ok I suppose, unless you need absolute precision. And
polling introduces it's own set of problems anyway, which is best all
depends upon the specific application. Interrupts are also nice in that
they let you seperate your program flow into asynchronous pieces (in a
sorta threadish way). The 18F pics have two priority levels, letting
you receive a high priority interrupt while a lower one is already
running. :-)))

> Also check out JAL, it's a friendly pascal-like language for PICs
> (which will do assembler also if you like.)
> http://groups.yahoo.com/group/jallist/ - binary from
> sourceforge.net/projects/jal/

Thanks anyway, but I'm already aware of JAL. It's pretty neat, but it's
just not my thing. I've used high level languages on micros before, but
I tend to stick with assembler for my PIC projects. Although I am
thinking about trying one of the free BASIC compilers to see how I like
it. I will say though that the most trouble I've had out of using
interrupts is when using them from a high level language. But even
then, I only really needed to figure out the rules for the particular
compiler and then things worked as expected.

>> In fact your clearing and setting of INTE in
>> the ISR is not really necessary, since no other interrupts will be
>> serviced until GIE is set again (by retfie).
>>
>> Be aware that the PIC's stack is quite small. Your ISR is using
>> two of the eight locations available.
>>
>
> Also sorry about the strange message formatting... was tinkering with
> PGP stuff.
>
> -- "The one truth of the universe is: infinite recursion. That is
> all."