Author Topic: Interrupt On Change  (Read 3998 times)

0 Members and 1 Guest are viewing this topic.

Offline singlarrysongTopic starter

  • Contributor
  • Posts: 34
Interrupt On Change
« on: May 05, 2015, 06:47:03 pm »
Anyone have IOC program sample for PIC16 that work perfectly well?
I got some cool project for customizing home lightning on going.
Because using I/O reading technique not as good as reading edge, so I wish to use it in my program.
Its better have multiple IOC configured, I tried on config it for one I/O, it work, but unstable. When I increase the number of I/O that using IOC, it not working anymore.

TQ very much!!!
 

Offline SL4P

  • Super Contributor
  • ***
  • Posts: 2318
  • Country: au
  • There's more value if you figure it out yourself!
Re: Interrupt On Change
« Reply #1 on: May 05, 2015, 10:35:53 pm »
It's not all that hard.
Strip out all other code, and work on a basic test... (blinking LED!)
Instability may be due to switch bounce or too much happening within the ISR.

ISR code should be as short and sweet as possible.
Test your state flags and do further (time consuming) work in your main()...
(CPU cycles spent in main() are 'free' - you will just get interrupted again if something else changes )

// ================================
void main() {
  • Make sure the idle state of your inputs are pulled as expected
  • Set up your IO pins.
  • Clear any stray interrupt source flags (in case!)
  • Enable interrupt modes
             -- things can start happening now...

    // ----------------
    while(1) {
         -- main stuff
         -- test your private flags and call your action functions
         -- reset your private flags or whatever is needed to maintain your operating state
    }
    // ----------------
}
// ================================
void interrupt isr {
  • Test which interrupt source fired the ISR...
  • if (RBIF) {
    -- test those specific I/O bits that are your sensor-input pins
    (minimise the code executed within the ISR - e.g. only set some flags etc)
  • }
  • Clear the ISR source flag & return to caller.
    RBIF = 0;
}
« Last Edit: May 05, 2015, 10:38:27 pm by SL4P »
Don't ask a question if you aren't willing to listen to the answer.
 

Online nctnico

  • Super Contributor
  • ***
  • Posts: 26870
  • Country: nl
    • NCT Developments
Re: Interrupt On Change
« Reply #2 on: May 05, 2015, 10:40:37 pm »
Rule number one: never use interrupts on GPIO pins for events which cannot be predicted. You won't be the first to find out the CPU gets stalled because it can't cope with the amount of interrupts. It is far better to poll the GPIO pins. That way you can also detect whether the condition stays valid for a certain time (and it wasn't a glitch due to static discharge).
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline SL4P

  • Super Contributor
  • ***
  • Posts: 2318
  • Country: au
  • There's more value if you figure it out yourself!
Re: Interrupt On Change
« Reply #3 on: May 05, 2015, 10:47:03 pm »
Rule number one: never use interrupts on GPIO pins for events which cannot be predicted. You won't be the first to find out the CPU gets stalled because it can't cope with the amount of interrupts. It is far better to poll the GPIO pins. That way you can also detect whether the condition stays valid for a certain time (and it wasn't a glitch due to static discharge).
I won't say you're wrong, but where did you pick that up?  I'd like to learn.
How do you read high-speed rotary encoders etc.....
Don't ask a question if you aren't willing to listen to the answer.
 

Offline mazurov

  • Frequent Contributor
  • **
  • Posts: 524
  • Country: us
Re: Interrupt On Change
« Reply #4 on: May 05, 2015, 10:54:12 pm »
This is the encoder code (and interrupt-on-change routine, for AVR) -> https://www.circuitsathome.com/mcu/rotary-encoder-interrupt-service-routine-for-avr-micros .  Works very well for reading hand-operated encoders and slow motors.
With sufficient thrust, pigs fly just fine - RFC1925
 

Offline mikerj

  • Super Contributor
  • ***
  • Posts: 3237
  • Country: gb
Re: Interrupt On Change
« Reply #5 on: May 06, 2015, 11:33:23 am »
It's not all that hard.

// ================================
void main() {
    void interrupt isr {
    • Test which interrupt source fired the ISR...
    • if (RBIF) {
      -- test those specific I/O bits that are your sensor-input pins
      (minimise the code executed within the ISR - e.g. only set some flags etc)
    • }
    • Clear the ISR source flag & return to caller.
      RBIF = 0;
    }
[/list]

Note that within the 'if (RBIF)' block the IOC port (PortB) must be either read or written to in order to remove the mismatch condition.  If you don't do this, the PIC will jump straight back into the interrupt.

Also, beware of this bug in the IOC.
 

Online nctnico

  • Super Contributor
  • ***
  • Posts: 26870
  • Country: nl
    • NCT Developments
Re: Interrupt On Change
« Reply #6 on: May 06, 2015, 07:09:15 pm »
Rule number one: never use interrupts on GPIO pins for events which cannot be predicted. You won't be the first to find out the CPU gets stalled because it can't cope with the amount of interrupts. It is far better to poll the GPIO pins. That way you can also detect whether the condition stays valid for a certain time (and it wasn't a glitch due to static discharge).
I won't say you're wrong, but where did you pick that up?  I'd like to learn.
How do you read high-speed rotary encoders etc.....
From a high speed timer interrupt.
I've seen it go wrong too many times combined with insufficient input debouncing/filtering. Using a GPIO interrupt for buttons, encoders, etc looks very nice but it is cumbersome to filter such inputs properly in hardware. And what when (not if) an input gets stuck between logic levels and starts to generate a continouos stream of interrupts? And then there is also the matter of signalling the interrupt to the user application (synchronisation between asynchronous threads). Polling allows to do simple filtering in software for low frequency events like buttons and other inputs.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline Howardlong

  • Super Contributor
  • ***
  • Posts: 5317
  • Country: gb
Re: Interrupt On Change
« Reply #7 on: May 07, 2015, 07:20:59 am »
You can use the IOC to do the initial wakeup, but in general I agree, using IOC for quadrature encoders isn't the way forward for the reasons mentioned. Regretfully the IOC pins on most, if not all PIC16 devices don't have Schmitt trigger inputs, so even an external cap in compination with the weak pull up won't work.

In a power constrained system, you could do IOC in combination with a timer interrupt to resample regularly until a steady state is reached. IOC should be disabled immediately on wakeup, and the timer reset. The IOC can be re-enabled just before sleeping again, but the device needs to be awake during the de-glitching period however long that is.
 

Offline singlarrysongTopic starter

  • Contributor
  • Posts: 34
Re: Interrupt On Change
« Reply #8 on: May 09, 2015, 07:51:55 am »
Hi everyone, sorry for the late reply.
I rework my initial program that fail and now it success.
I avoid setting GIE so no interrupt function require. I read the interrupt flag to identify the interrupt.

On the circuit part, there is a pF cap across each switch button to filter out the noise and further more Schmitt trigger is configure for the triggering method.

and yea it work. PIC16F1825 with Hi-Tech C at MPLAB v8.9
 

Online nctnico

  • Super Contributor
  • ***
  • Posts: 26870
  • Country: nl
    • NCT Developments
Re: Interrupt On Change
« Reply #9 on: May 10, 2015, 11:19:43 am »
Now count the number of interrupts versus the button pushes...
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf