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

Output Pulse Jitter

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



Joined: 20 Dec 2007
Posts: 9

View user's profile Send private message

Output Pulse Jitter
PostPosted: Thu Mar 26, 2009 6:26 pm     Reply with quote

Hey Guys,

I am using a 16F819 to generate some output pulses for an RC-type servo (but my output is buffered by an inverter, so my PIC pulses are active-low, usually high level). I am experiencing a jitter of one instruction cycle when using both the internal CCP module and bit-bang techniques. The CCP module I don't understand as that should output a very clean pulse, any ideas as to the source of the jitter?

I would really appreciate your input!


Here is my code-

Fuses:
Code:

#include <16F819.h>
#device adc=10

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES NOBROWNOUT               //No brownout reset
#FUSES CCPB3                    //CCP pin B3
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOPROTECT                //Code not protected from reading

#use delay(clock=8000000)



Setup:
Code:

setup_timer_1(T1_INTERNAL|T1_DIV_BY_2);   //For 1us resolution
setup_ccp1(CCP_COMPARE_SET_ON_MATCH); //Default set mode


Pulse Routine:
Code:

void output_pulse(){           //Generate output pulse (1us/step)
      set_timer1(10);           //Arbitrary set point to prevent accidental trigger
      setup_ccp1(CCP_COMPARE_CLR_ON_MATCH); //Start CCP again for pulse gen
      CCP_1 = 1;
      set_timer1(1);          //Reset timer
      CCP_1 = out_width;   //Set CCP_1 register
      setup_ccp1(CCP_COMPARE_SET_ON_MATCH); //Go high again
}

I am quite baffled by this and am not sure what to make of it. I would love to get any insight from those of you who have heard of this problem before. (I am likely just doing something wrong) Confused

-Matt
_________________
-Matthew A. Aurand
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Fri Mar 27, 2009 12:35 am     Reply with quote

If I understand right, the pulsewidth in your example is affected by code execution timing, cause setup_ccp1() defines the leading edge and set_timer1(1) the trailing. Most instructions use two instruction cycles, but instruction timing isn't synchronized to timer1 prescaler. So a jitter must be expected.

Generally, there are methods for each microprocessor family to achieve a cycle accurate timing of pins, even with software generated timing. When using a hardware timer, it's essential not to reinitialize or reset the involved time base, timer1 in this case, but to keep it running continuously and manipulate only registers, that don't threaten the timebase's integrity.
Guest








PostPosted: Fri Mar 27, 2009 5:41 am     Reply with quote

Matt,
Why aren't you using the CCP_PWM directive in setup_ccp1()? This would give you the exact PWM you want with no software intervention.
RLScott



Joined: 10 Jul 2007
Posts: 465

View user's profile Send private message

PostPosted: Fri Mar 27, 2009 6:00 am     Reply with quote

FvM wrote:
...but instruction timing isn't synchronized to timer1 prescaler. So a jitter must be expected...

Ah, but it is. Whenever you write to Timer 1 you automatically clear the prescaler. This synchronizes the prescaler to the instruction timing. If there are no interrupts, I see no reason why there should be any pulse-width jitter. The code is completely deterministic.

Edit: On second thought, there may be something a little strange about the way the pulse is started - with a write to Timer 1 with the exact value in CCP_1. It is not clear exactly when the "comparision" would be made in that case. It might be dependent on the previous state of the prescaler, which is in the process of being cleared by this very instruction. How about setting CCP_1 = 1 first and then doing a set_timer1(0) instead of set_timer(1)? This will allow the compare to take place in the normal way - upon a regular increment of Timer 1. With a 2:1 prescaler on Timer 1, you only need to pause for 2 instruction times for this CCP comparison to trigger before you go on with CCP_1 = out_width.
_________________
Robert Scott
Real-Time Specialties
Embedded Systems Consulting


Last edited by RLScott on Fri Mar 27, 2009 7:09 am; edited 1 time in total
RLScott



Joined: 10 Jul 2007
Posts: 465

View user's profile Send private message

PostPosted: Fri Mar 27, 2009 6:14 am     Reply with quote

Anonymous wrote:
Matt,
Why aren't you using the CCP_PWM directive in setup_ccp1()? This would give you the exact PWM you want with no software intervention.

His code shows that he is using an 8 MHz clock, so the available PWM periods are less than 2.048 msec (using the 16:1 prescaler on Timer 2). This is too short for an R/C servo signal whose on-time varies from 1 to 2 msec. Normally they repeat every 20 msec. That is why PWM cannot be used.
_________________
Robert Scott
Real-Time Specialties
Embedded Systems Consulting
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Fri Mar 27, 2009 7:22 am     Reply with quote

Quote:
I see no reason why there should be any pulse-width jitter. The code is completely deterministic.

Yes, I see you should be right (if TIMER1 and CCP are working as documented). Also, both edges should occur with a fixed timing related to set_timer(1). I wonder however, if it's correct to set timer(1) to a matching value immediately. It probably should be set to zero instead, to create the edge on next count.
Code:
CCP_1 = 1;
set_timer1(0);

If a jitter is still present, there may be a hardware issue of this PIC. I expect, that the jitter was observed in real measurement, not a simulation?
Guest








PostPosted: Fri Mar 27, 2009 9:10 am     Reply with quote

Hey guys, I'm going to do some more quick experiments and post back - thanks for the help!

The jitter is observed in real-world, not simulation.
Matthew Aurand



Joined: 20 Dec 2007
Posts: 9

View user's profile Send private message

PostPosted: Fri Mar 27, 2009 9:37 am     Reply with quote

OK. The jitter is not one instruction but about 10uS peak-peak. The same jitter remains whether I do this:

Code:

      output_low(OUTPUT);
      delay_us(out_width);
      output_high(OUTPUT);


or various OCP variations:

Code:

      setup_ccp1(CCP_COMPARE_CLR_ON_MATCH); //Start CCP for falling edge
      set_timer1(0);   
      CCP_1 = 3;              //So falling edge occurs in 3us
      delay_cycles(100);      //Make sure it happens 
      CCP_1 = out_width;
      set_timer1(0);
      setup_ccp1(CCP_COMPARE_SET_ON_MATCH);


The reason I don't use PWM is that I will not be able to get terribly good servo resolution - I wanted to maximize the resolution while keeping the numbers simple (1000-2000us per output pulse). I will try PWM now and report back.

Thanks again for the help guys.

-Matt
_________________
-Matthew A. Aurand
Matthew Aurand



Joined: 20 Dec 2007
Posts: 9

View user's profile Send private message

PostPosted: Fri Mar 27, 2009 10:07 am     Reply with quote

OK - PWM is not working at all even with code that should be fine.

Code:

   set_pwm1_duty(100);
   setup_timer_2(T2_DIV_BY_4,127,1);
   setup_ccp1(CCP_PWM);


PWM uses timer 2, so I initialize that first with an arbitrary period and post-scale of 1. (I had set it up as (T2_DIV_BY_16,255,16) to get the proper output width of 0-2.04ms and off time of 32ms) but changed it to simple parameters to see what I was doing wrong.

I suspect that the internal clock is not stable enough - but I have written PBP code with the same part that exhibited no jitter with simple bit-banging.




-Matt
_________________
-Matthew A. Aurand
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