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 support@ccsinfo.com

#USE TIMER and the ISR

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



Joined: 31 Dec 2010
Posts: 36

View user's profile Send private message

#USE TIMER and the ISR
PostPosted: Sat May 01, 2021 12:50 pm     Reply with quote

The chip I am using has only 1 timer and the Modbus library takes it over with a
#USE TIMER(TIMER=1,TICK=.1ms,BITS=16, ISR) command.

I need a second timer and I'd like to add my own counter inside the timer1 ISR because the modbus library is constantly resetting the ticks.

Is it possible to add a second counter inside the ISR when using #USE TIMER?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat May 01, 2021 11:41 pm     Reply with quote

Why don't you tell us what your PIC is ?

Also tell us the frequency of the PIC's oscillator.
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Sun May 02, 2021 6:58 am     Reply with quote

There isn't any PIC made that 'only has one timer'. Even the 16F18313, which
has one 16bit timer, has two more 8bit timers. With a suitably selected
prescaler one of these can generate a high speed tick, or give something
close to the tick required by the MODBUS driver.
So as PCM says, 'tell us what your PIC is'.
temtronic



Joined: 01 Jul 2010
Posts: 9097
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun May 02, 2021 7:16 am     Reply with quote

Is it possible, yes, of course....
Say the ISR is triggered every 1 ms.
You simply have an increment/test inside the ISR for another 'flag'.
Say you need a 10ms flag...

There's a SW RTC program in the code library, that shows one way to do it....

Though using a 2nd timer has benefits.....

LOTS of choices.
pebbert9



Joined: 31 Dec 2010
Posts: 36

View user's profile Send private message

PostPosted: Sun May 02, 2021 10:28 am     Reply with quote

I'm using the dsPIC33CK32MP502 which has only 1 timer.

Is there an ISR available to put code in if using the #USE TIMER(TIMER=1,TICK=.1ms,BITS=16, ISR directive?

I tried adding
Code:

#INT_TIMER1
void timer1_int(void) {
   cntr++;
}


But it doesn't seem to work unless I setup the timer manually like
Code:

setup_timer1(TMR_INTERNAL|TMR_DIV_BY_64, TIME_1_MS);
enable_interrupts(INT_TIMER1);
clear_interrupt(INT_TIMER1);


Which won't work with the library unless I re-write that part of it.
dluu13



Joined: 28 Sep 2018
Posts: 395
Location: Toronto, ON

View user's profile Send private message Visit poster's website

PostPosted: Sun May 02, 2021 10:39 am     Reply with quote

Are you locked into using this MCU? Having only one timer feels very restrictive.
pebbert9



Joined: 31 Dec 2010
Posts: 36

View user's profile Send private message

PostPosted: Sun May 02, 2021 10:48 am     Reply with quote

I am for it's CAN controller

I just realized it has a CCP module which I've never used before that can act as a timer.

I need to research on how to set it up....
dluu13



Joined: 28 Sep 2018
Posts: 395
Location: Toronto, ON

View user's profile Send private message Visit poster's website

PostPosted: Sun May 02, 2021 10:54 am     Reply with quote

Sadly, there aren't many PICs with a built in CAN controller...

I use the MCP2515 with the CCS driver for it when I need it though.
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Sun May 02, 2021 12:07 pm     Reply with quote

Your chip as well as the single pure 'timer', has eight SCCP modules and
one MCCP module, each of which can be programmed as timers.
Use one of these.
You actually have a total of ten timers available.
pebbert9



Joined: 31 Dec 2010
Posts: 36

View user's profile Send private message

PostPosted: Sun May 02, 2021 3:20 pm     Reply with quote

The manual is very vague on using the CCP module as a general purpose timer and there isn't much on the forum.

It looks like I would do something like this if I have an 8MHz external crystal (clock=160MHz). It would have an interrupt every 0.1 second, correct?

Code:
setup_ccp1(CCP_TIMER | CCP_DIV_BY_64 | CCP_FOSC | CCP_COMPARE_SET_ON_MATCH | CCP_TIMER_32_BIT);

set_timer_period_ccp1(12500);
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Mon May 03, 2021 12:57 am     Reply with quote

The key thing to read here is the Microchip application note on these
modules. 300003035b.pdf
Refer to section 5.

Now to use it as a 32bit timer, key thing to note is that you must load
both the 16bit period values. This means the number you give the
set_timer_period function, needs to either be two 16bit values, or needs
to be explicitly a 32bit value (so would need an 'L' after the value).
Currently you are only feeding it a 16bit value.
You don't want 'set_on_match'. That makes the CCP output set.

So (very basic demo):
Code:
   
#include <33CK32MP502.h>
#device ICSP=1
#use delay(clock=160000000,crystal=8000000)

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES CKSFSM                   //Clock Switching is enabled, fail Safe clock monitor is enabled

int count=0;

#INT_TIMERCCP1
void tick(void)
{
   count++;
}

void main()
{
   setup_ccp1(CCP_TIMER | CCP_DIV_BY_16 | CCP_FOSC | CCP_TIMER_32_BIT);

   set_timer_period_ccp1(99999); //one less than the count you want
   //since > 65535, forces to be an int32, so both registers are loaded.
   enable_interrupts(INT_TIMERCCP1);
   enable_interrupts(GLOBAL);

   while(TRUE)
   {
      if (count==10)
      {
         count=0;
         output_toggle(PIN_A0);         
      }
   }
}


Since the period here is >65535, this forces it to be a 32bit value, and
thereby load both registers.
You should find this will merrily interrupt at 16*100000 counts of the
FOSC. By using the /16 divisor, ir allows the 32bit timer value to be used.
However you don't need to do this. So:
Code:

void main()
{
   setup_ccp1(CCP_TIMER | CCP_DIV_BY_64 | CCP_FOSC);
   //get rid of the 32bit setting & instead /64

   set_timer_period_ccp1(24999); //one less than the count you want
   //only loading a 16bit value
   enable_interrupts(INT_TIMERCCP1);
   enable_interrupts(GLOBAL);

   while(TRUE)
   {
      if (count==10)
      {
         count=0;
         output_toggle(PIN_A0);         
      }
   }
}


So now the timer is used in 16bit mode with the /64 prescaler.

I think I've got the counts right. Have a play and see...
Very Happy
pebbert9



Joined: 31 Dec 2010
Posts: 36

View user's profile Send private message

PostPosted: Mon May 03, 2021 10:42 pm     Reply with quote

Thanks for the help, everything's working fine now.
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Tue May 04, 2021 6:56 am     Reply with quote

Good. Glad you have it working. Very Happy
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