Author Topic: ... have your PIE1 and eat it!  (Read 2784 times)

0 Members and 2 Guests are viewing this topic.

Offline PerranOakTopic starter

  • Frequent Contributor
  • **
  • Posts: 581
  • Country: gb
... have your PIE1 and eat it!
« on: May 14, 2020, 12:03:35 pm »
I am running Timer 2 on a PIC16F1827.

I looked in the datasheet and it said:

22.2 Timer2/4/6 Interrupt
Timer2/4/6 can also generate an optional device interrupt. The Timer2/4/6 output signal (TMRx-to-PRx match) provides the input for the 4-bit counter/postscaler. This counter generates the TMRx match interrupt flag which is latched in TMRxIF of the PIRx register. The interrupt is enabled by setting the TMRx Match Interrupt Enable bit, TMRxIE of the PIEx register.


However, the first time I ran it I forgot to set TMR2IE on PIE1 (it's on PIE1 not PIE2 as implied above) but it still worked! I checked with the simulator on MPLAB X IDE and the whole of PIE1 was zero.

Now I'm really confused. Do I need to set TMR2IE like it says in the datasheet or not? Experience tells me not but I wonder if this is automatically set somewhere else … or something(!) Also, GIE and PIEI of INTCON were all zero too - what I have learned is no longer true.  ???

Cheers.
« Last Edit: May 14, 2020, 12:18:26 pm by PerranOak »
You can release yourself but the only way to go is down!
RJD
 

Offline JTR

  • Regular Contributor
  • *
  • Posts: 107
  • Country: au
Re: ... have your PIE1 and eat it!
« Reply #1 on: May 14, 2020, 02:03:56 pm »
If you want an interrupt to be generated then you need to set the corresponding TMRxIE bit. However, the TMRxIF bit is set on timer overflow regardless of whether an interrupt is generated or not. The TMRxIE does not need to be set for the TMRxIF to be set. This is to allow software polling methods to know when a timeout condition has been met.
 
The following users thanked this post: PerranOak

Offline PerranOakTopic starter

  • Frequent Contributor
  • **
  • Posts: 581
  • Country: gb
Re: ... have your PIE1 and eat it!
« Reply #2 on: May 15, 2020, 10:19:14 am »
Ah, right. I was thinking that an actual interrupt was needed but the programme just waits while TMR2IF is low then, on going high, it acts - a very simple prog.

Thank you very much for pointing that out. I knew I was thinking wrongly!  |O
You can release yourself but the only way to go is down!
RJD
 

Offline itdontgo

  • Regular Contributor
  • *
  • Posts: 167
  • Country: gb
    • IoT Manufacturer
Re: ... have your PIE1 and eat it!
« Reply #3 on: May 16, 2020, 03:43:27 pm »
Also a little trap is putting the test for TMR2IF before another interrupt in the ISR. So if an interrupt was generated by the other thing it goes off and does the TMR2IF before the true interrupt cause... even when the TMR2IE is not set.

org 0x04

btfsc PIEx,TMRxIF
goto TMRx thing

btfsc PIEy,TMRyIF
goto TMRy thing

...it will always do TMRx thing first if the flag is set even if not enabled. I've often had to test the TMRxIE and skip over the TMRxIF test to avoid this.
 
The following users thanked this post: PerranOak

Offline mikerj

  • Super Contributor
  • ***
  • Posts: 3671
  • Country: gb
Re: ... have your PIE1 and eat it!
« Reply #4 on: May 16, 2020, 07:58:45 pm »
...it will always do TMRx thing first if the flag is set even if not enabled. I've often had to test the TMRxIE and skip over the TMRxIF test to avoid this.

This is standard practice for the PICs that have only one or two interrupt vectors, you must always test the interrupt enable bit for each source if you are handling multiple interrupts.
 

Offline ajb

  • Super Contributor
  • ***
  • Posts: 2867
  • Country: us
Re: ... have your PIE1 and eat it!
« Reply #5 on: May 17, 2020, 12:26:07 am »
...it will always do TMRx thing first if the flag is set even if not enabled. I've often had to test the TMRxIE and skip over the TMRxIF test to avoid this.

This is standard practice for the PICs that have only one or two interrupt vectors, you must always test the interrupt enable bit for each source if you are handling multiple interrupts.

This is how basically how every ARM MCU works too. If you had a separate ISR for every single interrupt the vector table alone would wind up being like 2kB. So there's only one vector per peripheral, and it's up to you to make sure the ISR handles the correct condition at the correct time.
 

Offline PerranOakTopic starter

  • Frequent Contributor
  • **
  • Posts: 581
  • Country: gb
Re: ... have your PIE1 and eat it!
« Reply #6 on: May 17, 2020, 10:15:27 am »
Cheers all.  :)
You can release yourself but the only way to go is down!
RJD
 

Offline itdontgo

  • Regular Contributor
  • *
  • Posts: 167
  • Country: gb
    • IoT Manufacturer
Re: ... have your PIE1 and eat it!
« Reply #7 on: May 17, 2020, 12:11:00 pm »
I don't do that on every interrupt I just put them in the order where it doesn't matter. It wastes page 0 memory and makes the ISR slower if you do it for everything.

The only important ones in our comms firmware is the UART TXIF/E which I put last as it's least timing critical.

Offline mikerj

  • Super Contributor
  • ***
  • Posts: 3671
  • Country: gb
Re: ... have your PIE1 and eat it!
« Reply #8 on: May 25, 2020, 11:40:25 am »
I don't do that on every interrupt I just put them in the order where it doesn't matter. It wastes page 0 memory and makes the ISR slower if you do it for everything.

The only important ones in our comms firmware is the UART TXIF/E which I put last as it's least timing critical.

How can this prevent an interrupt getting serviced if e.g. you have temporarily cleared the IE bit in the main loop? 
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf

 

-->