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

PIC18F CCP (PWM) and Timers1/3 interrupts problem

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



Joined: 20 Jan 2017
Posts: 2

View user's profile Send private message

PIC18F CCP (PWM) and Timers1/3 interrupts problem
PostPosted: Fri Jan 20, 2017 12:06 pm     Reply with quote

Hello everyone,

PCM programmer and Ttelmah, THANKS because you have solved many problems I had, and by searching on the forum you already solved the problem. But I need your help now, please!

I have a PIC18F2685, and I'm using the CCP1 to produce a PWM signal. I'm also using timer_0 as a millisecond event counter.

Code:
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DIV_BY_16,249,10);  //freq PWM
   setup_timer_3(T3_DISABLED);
   
   setup_ccp1(CCP_PWM);                //CCP pin PWM
   set_pwm1_duty(1000);                //Dc 100% = 1000


I setup the timer2 with the desired frequency and everything worked fine, until now that I added timer3 to generate an event after a certain amount of time after another event.

Code:
//some event()
{
set_timer3(43036); //45 ms //2^16 - ms/(4/Fosc*DIV) , Fosc 16 MHz , DIV 8 | 53036 - 25 ms | 50536 - 30 ms | 43036 - 45 ms // 50 ms max timeout
setup_timer_3(T3_INTERNAL|T3_DIV_BY_8);
}


I tried it with "timer_1" instead of "timer_3" and makes no difference.

This caused the PWM signal to disappear, no longer PWM output on CCP1 pin (RC2).
I tried changing timer3 with timer1 and the problem still exists.
The problem, as I have seen so far, is with the Interrupts:

Code:
#int_TIMER1
void TIMER1_isr(void)
{
   //do things
   setup_timer_1(T1_DISABLED);
}


or

Code:
#int_TIMER3
void TIMER3_isr(void)
{
   //do things
   setup_timer_3(T3_DISABLED);
}


If I disable this part of code, the PWM works fine.

Why are timer1/3 affecting the CCP module? In PWM mode is not only timer2?
What can I do to fix this, please?!

Thanks in advance!!!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Jan 20, 2017 12:29 pm     Reply with quote

Can you post a complete test program that shows the problem ?
In other words, if the problem is that enabling Timer3 shuts down CCP1,
then post a program that demonstrates this. Post the #include for the
PIC, #fuses, #use delay(), main(), etc. It should be compilable.
Leave out any code that isn't related to the problem.

Also post your compiler version.
Ttelmah



Joined: 11 Mar 2010
Posts: 19520

View user's profile Send private message

PostPosted: Sat Jan 21, 2017 2:01 am     Reply with quote

It certainly shouldn't affect the CCP.

The classic thing is to simplify. Just generate a minimum program generating the PWM, and running Timer3. Does it work?. If not, then this becomes something you can post so that we can look at the problem.

The obvious thing that changes, is whatever is in '//Do Things', so this would be the first place to look. If you remark out this code, what happens?. Obvious things to look for here:
Anything changing TRIS on the PWM port.
Anything touching the timers.
Anything accessing arrays of using pointers (which might 'overflow' and therefore affect other registers.

Where are you setting up the PWM?. Before or after you setup Timer3?.
The other things that may be happening, is that the code is simply never reaching the PWM setup. If you are executing too many interrupts, and they contain code that takes significant time, it's possible that effectively the main code is never actually getting executed. You mention a 1mSec counter, and show this using the RTC as an /256 counter. This implies potentially an interrupt every 256 instructions. If this is executing a handler, even if this does nothing at all, immediately 25% of your processor's time will be being used handling this. If you then add another interrupt at 45mSec, and this takes perhaps 35mSec to execute it's code, suddenly there is no time let to do anything.
It takes quite a bit of time to get into and out of an interrupt handler. Typically something like 60 instructions. This is why it is better to keep the number of interrupts low if possible. If you want a timer, then consider if you could do this by just reading the timer registers, rather than having an interrupt. If you have a 1mSec timer, and want a 45mSec one, then just add a counter in the 1mSec interrupt (uses less time provided it is a simple int8, than calling another interrupt). However many interrupts you have though repeat the mantra fifty times _spend as little time as possible inside the handler_.

As one further comment to this, if 256 instructions is about 1mSec, this implies the chip is only being clocked at 1MHz. Honestly if you want to have an interrupt at 1mSec, you need to be clocking the chip faster than this. However your comment on Timer3 setup, says you are using 16MHz, which would imply timer1 interrupting every 64uSec...
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Jan 21, 2017 4:13 pm     Reply with quote

He said in a PM to me that upon trying to make a test progarm, it all
started working fine.
Alel8



Joined: 20 Jan 2017
Posts: 2

View user's profile Send private message

PostPosted: Sat Jan 21, 2017 4:48 pm     Reply with quote

Ttelmah wrote:
As one further comment to this, if 256 instructions is about 1mSec, this implies the chip is only being clocked at 1MHz. Honestly if you want to have an interrupt at 1mSec, you need to be clocking the chip faster than this. However your comment on Timer3 setup, says you are using 16MHz, which would imply timer1 interrupting every 64uSec...


I'm clocking with a 4MHz crystal and the x4 PLL enabled, and the timer0 is 16bit mode and I precharge a value of around 61600 so it generates an interrupt on overflow every 1000us.

PCM programmer wrote:
He said in a PM to me that upon trying to make a test progarm, it all
started working fine.


In the test program it works fine, but in the "bigger" one it doesn't. I had to add another setup_ccp(PWM); just before entering the while(1) loop inside the main routine and that seems to work. I will keep trying to find the problem.
Ttelmah



Joined: 11 Mar 2010
Posts: 19520

View user's profile Send private message

PostPosted: Sun Jan 22, 2017 5:34 am     Reply with quote

Your timer0 code is never going to be very accurate. You are attempting to tweak the loaded value to adjust for the instructions it takes to go into the interrupt (fair enough)_, but if another interrupt occurs, the tweak will be wrong.
Why do this?. You already have Timer2 ticking at exactly 1000HZ. Pointless to setup another timer and try to 'fiddle' it's timings. Just put the timer2 postscaler down to 1, and have a timer2 interrupt like:
Code:

#INT_TIMER2
{
   static int8 hundredth_tick=9;
   //assuming you do want to handle something every ten times
   if (hundredth_tick==0)
   {
       hundredth_tick=9;
       //Your existing int_timer2 code

   }
   else
      --hundredth_tick;

   //Now your 1mSec code

}

The test & decrement will take no more instructions than you currently have loading the 16bit timer value , and implies one less interrupt to worry about...
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