Jump to content

Reading R/C PPM signal w capture and compare?

Recommended Posts

MSP430 is not so nice for this application because of its voltage level, my RC has 5 V.. But: I have plenty of G2231 that are well-suited for the task. I will add a few FETs for level conversion and as power switches for the lights..

If you know of any code snippet that uses the timer in capture mode, please let me know..


PS: I was going for a single-channel decoder..

Link to post
Share on other sites
.. and I've previously asked for capture code: viewtopic.php?f=8&t=1333&p=8815&hilit=capture#p8815


the following is an extract from my ezprobe project http://www.43oh.com/forum/viewtopic.php?p=2160#p2160


the project demonstrates timer capture and timer compare, it can capture / count pulses and generate pwm signals.


i used p1.6 (on a f2012, not available on a g2211) as input due to h/w layout constraint.


to determine which pin u can use for timer capture, u need to read the datasheet for the device itself. u should look for those pins w/ CCI0A or CCI1A function (cee-cee-eye). on g2211/g2231 they are p1.1 and p2.2.


basically u need to

. setup capture pin via P1DIR and P1SEL

. turn on capture and specify trigger edge via CCTL0 or CCTL1

. setup your interrupt or check CCIFG captured flag in CCTLx register, and optionally do your count


if u are into analyzing your pwm pulse width / duty cycle and such, u might need to setup to capture BOTH edges and then count the different of high-low and low-high, they are explained in the datasheet slau144?



void sample(void) {

   P1DIR &= ~P_PROBE;                      // probe pin as input
   P1SEL &= ~P_PROBE;                      // turn off alternate function on pin

   ADC10AE0  |= P_PROBE;                   // probe pin in adc
   ADC10CTL0 |= ENC + ADC10SC;             // enable, start adc conversion
   __bis_SR_register(CPUOFF | GIE);        // enter lpm0 sleep for adc read
   ADC10AE0 &= ~P_PROBE;                   // adc done, turn off probe pin as adc

   //______ setup timer
   TACTL = TASSEL_2|ID_1|SCS|MC_2|TACLR;   // continous mode
   uint8_t adc = ADC10MEM>>2;              // we only need 8 bit
   if ((adc) < 0x30 || (adc) >= 0xd0) {    // that's what we consider non-floating

       P1SEL |= P_PROBE;                   // turn probe pin as timer capture pin
       CCTL1 = CAP | CCIS_1 | CM_2;        // capture falling edges

       uint16_t trips = 0;
       // timer will overflow in
       //  8mhz =  8,000,000 / 0x10000 = 1/122 sec (/2 clk = 1/61)
       // 12mhz = 12,000,000 / 0x10000 = 1/183 sec (/2 clk = 1/91)
       while (!(TACTL & TAIFG)) {
           if (CCTL1 & CCIFG) {    // tripped
               CCTL1 &= ~CCIFG;

       CCTL1 = 0;
       P1SEL &= ~P_PROBE;

       //trips >>= 1;      // divide by 2 as we counted both edges
       if (trips > 640) {
           trips /= 91;
           trips *= 100;
       else {
           trips *= 100;
           trips /= 91;        // now trips in 100ms units

Link to post
Share on other sites
  • 1 month later...

As it turns out, the TC4017BP responsible to separate the PPM signal into pulses for each channel is reset every frame (about 20 ms), so the modified PPM needs to be synchronous to the original signal (just one frame later).

Although I have tried to keep calculations in pin- and timer interrupts to a minimum (by setting flags and crunching numbers in the main loop instead), they take long enough to cause problems when overlapping, i.e. an edge of the incoming signal concurs with an edge of the generated signal, causing jitter.


Is there any way to prevent this, without moving the output after the input frame (into the sync gap, either by skipping an input frame or taking over the TC4017BP's reset input or using a different ouput scheme altogether)?

Link to post
Share on other sites

I failed to grasp that TimerA has two CCUs, which allows for independent PPM capture and generation. The only important part is to read/compute/write the new CCR values in time.

The other thing is that the demultiplexer reset needs to be controlled by the microcontroller, too, in order to be able to output channel signals even if there is no valid input signal (failsafe), as the reset pulse (on my receiver) depends on the reception as well. It is easily generated along with the ouput frame.

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...