CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Timer2 above 60khz

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
tmeyer



Joined: 28 Jul 2021
Posts: 2

View user's profile Send private message

Timer2 above 60khz
PostPosted: Wed Jul 28, 2021 8:35 pm     Reply with quote

Hello all

I have been playing with pics for years just as a hobby making simple devices. But I have recently been trying to understand the math behind the timers. When I use the below code and the program (with a period of 78 or above in setup_timer2(T2_DIV_BY_1,78,1)) everything works fine. The frequency of the interrupt matches the math.

However, when I put in 77 it should generate an interrupt frequency of 64,102hz. Note that I am actually measuring for 1/2 that (32,051hz) since I am using two interrupts to toggle the pin I am measuring PIN_C4.

After being "spot on math vs actual" from period values of 78 and above, the scope and counter diverge from math at 77 showing 29,450hz instead of expected 32,051hz. And the faster I make frequency of interrupts by lowering period value the worse the spread between measured and actual gets. I also moved the prescaler and periods around but still broke away from the math at around the same 30Khz point measured, 60khz actual interrupt frequency.

Anyone know why? This example is on a 18F258 with 20mhz clock. Same issue on a 16f684 with 20mhz clock but things break down 10khz later at around 40khz on scope, 80khz actual interrupt frequency. Multiple clock crystals, multiple different chips. Same results.

I've got to be missing something pretty basic. I even used the code generating wizard to make sure I wasn't doing something stupid. I am using a regulated power source so no issues there.

Thanks if anyone can tell me why. I searched everywhere for explanation but maybe don't know how to phrase the question.
Code:

#include <main.h>

#INT_TIMER2
void  TIMER2_isr(void)
{
   output_toggle(PIN_C4);
}

void main()
{
   setup_timer_2(T2_DIV_BY_1,78,1);     


   enable_interrupts(INT_TIMER2);
   enable_interrupts(GLOBAL);
   setup_low_volt_detect(FALSE);

   while(TRUE)
   {
      //TODO: User Code
   }

}

main.h
Code:

#include <18F258.h>
#device ADC=16

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O

#use delay(crystal=20000000)
Ttelmah



Joined: 11 Mar 2010
Posts: 19520

View user's profile Send private message

PostPosted: Thu Jul 29, 2021 12:33 am     Reply with quote

Problem is entering and exiting an interrupt takes time....

At 20MHz, the chip does 5MIPS. It typically takes about 35 instructions to
detect an interrupt has happened, save the registers, then enter the
interrupt.
Your output toggle, takes another two instructions. Then clearing the
interrupt and restoring the registers another thirty instructions. By the time
the code arrives back in the 'main' about 70 instructions have passed. Remember a call, return etc., all take two instruction times, so more
than this in actual instruction times.

So at 20MHz, the maximum rate would be around perhaps 65KHz.
At this point, the code would be 100% occupied handing this interrupt.
No time to do anything else.

You are finding it runs out of time (remember it needs one instruction
time back in the 'main', to then respond to the interrupt), at 79 instruction
times between the triggers.

This is why chips have hardware to do useful things for you. So the PWM,
allows you to generate output pulse trains using no processor time. More
flexibly, the CCP can support having the hardware set a pin or clear a
pin after an interval. This is why to do anything actually useful, you need
to use the hardware.

There is a trick that can be used, which is to not physically call an interrupt:
Code:

#include <main.h>

void main()
{
   setup_timer_2(T2_DIV_BY_1,78,1);     

   setup_low_volt_detect(FALSE);

   while(TRUE)
   {
      if (interrupt_active(INT_TIMER2))
      {
         output_toggle(PIN_C4);
         clear_interrupt(INT_TIMER2);
      }
   }
}


Here, the main code 'polls' the interrupt flag. When it sets, does the toggle,
and clears the flag. Result, handling in a total of less than 10 instructions.
Suddenly toggle rates at about 500KHz potentially become possible!....
tmeyer



Joined: 28 Jul 2021
Posts: 2

View user's profile Send private message

PostPosted: Fri Jul 30, 2021 1:48 pm     Reply with quote

Thanks for taking the time to answer me! Your explanation makes perfect sense - I guess I would have though there would be some disclaimer somewhere about the maximum frequency that could be generated by processing the interrupt. There is a note in the datasheet (at least on the 16f684) about max PWM frequency. They are giving hobbyists like me way too much credit (I run a Ford Truck Dealership as my day job).

For the sample code below (which I haven't had time to try), I don't need to enable interrupts to test for their presence?

Thanks again - much appreciated.

Trey
newguy



Joined: 24 Jun 2004
Posts: 1908

View user's profile Send private message

PostPosted: Fri Jul 30, 2021 2:37 pm     Reply with quote

No you don't need to enable interrupts to test to see if one has "fired". Interrupts are simply hardware-induced function calls if they're enabled. If they're not enabled, they still "fire" but the function isn't called. All you're doing by testing for the interrupt flag in a loop is essentially bypassing the (slow) formal interrupt call mechanism.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group