Using TIMER to Capture (measure) Pulsewidth

I need help on how to setup the timer-A in capture mode and use

it to measure the external pulsewidth.

Does anybody know where I can get sample of such C type source code?

Thanks in advance

JIMMY

TI has hundreds of Code Examples on their web-site.

Sample codes available at TI website do not show TIMER in capture mode.

That is strange.

I found 40+ of them use Timer Capture. For example:

fet120_fll_01.c

fet120_fll_02.c

fet120_uart02_09600.c

fet120_uart02_19200.c

fet120_uart03_09600.c

fet120_uart03_19200.c

fet140_fll_01.c

fet140_fll_02.c

fet140_ta_22.c

fet140_uart02_09600.c

fet140_uart02_19200.c

fet140_uart03_09600.c

fet140_uart03_19200.c

… just to name a few …

Dear Sir,

I checked the cose samples you listed above one-by-one. Eventhough,

they are in fact utilizing some sort of capture feature of a MSP430, but

I don’t think they are suitable for my application.

My project requires that an incoming pulse coming to one of the input

pin, and the timer START counting as soon as it detect the rising edge

of the pulse, and then STOP at the falling edge, and the different of the

two readings would be the pulsewidth.

The right sequence would be like:

  1. Arm the timer-A and setup interrupt etc…

  2. Wait for rising edge / start timer when detection occured

  3. Wait for falling edge / Stop timer when detection occured

  4. Count value is equal to the pulsewidth.

Could you please help me modifying the sample codes

you suggested to achieve the task above.

Thanks in advance,

JIMMY

Here is a modification to fet140_ta_22.c

I only added 1 line of code and modified 5 lines of comments.

All these 6 lines are marked witb //OCY

//***********************************************************************
//  MSP-FET430P140 Demo - Timer_A0, Capture of External Signal      //OCY
//
//  Description: Input capture of External Signal at P1.1(TA0)      //OCY
//  Run to breakpoint at the _NOP() instruction to see 16 capture
//  values and the differences.
//  ACLK = 32768Hz, MCLK = SMCLK = default ~800kHz
//  //* An external watch crystal on XIN XOUT is required for ACLK *//
//
//                MSP430F149
//             -----------------
//         /|\|              XIN|-
//          | |                 | 32kHz
//          --|RST          XOUT|-
//            |                 |
//            |        P2.0/ACLK|---> Not used                      //OCY
//            |                 |
//            |         P1.1/TA0|<----------< External Signal       //OCY
//            |                 |
//            |             P1.0|--->LED

//
//  H. Grewal
//  Texas Instruments Inc.
//  Feb 2005
//  Built with IAR Embedded Workbench Version: 3.21A
//  Modified by Old Cow Yellow (OCY)                                //OCY
//******************************************************************************

#include  <msp430x14x.h>

unsigned int new_cap=0;
unsigned int old_cap=0;
unsigned int cap_diff=0;

unsigned int diff_array[16];                // RAM array for differences
unsigned int capture_array[16];             // RAM array for captures
unsigned char index=0;
unsigned char count = 0;

void main(void)
{
  volatile unsigned int i;
  WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer
  for (i=0; i<20000; i++)                   // Delay for crystal stabilization
  {
  }
  P1DIR = 0x01;                             // Set P1.0 out,1.1 input dir
  P1OUT &= ~0x01;                           // LED off
  P1SEL = 0x02;                             // Set P1.1 to TA0
  P2DIR = 0x01;                             // P2.0-ACLK
  P2SEL |= 0x01;
  BCSCTL1 |= DIVA_3;                        // ACLK/8

  CCTL0 = CM_1 + SCS + CCIS_0 + CAP + CCIE; // Rising edge + CCI0A (P1.1)
                                            // + Capture Mode + Interrupt

  TACTL = TASSEL_2 + MC_2;                  // SMCLK + Continuous Mode

  _BIS_SR(LPM0_bits + GIE);                 // LPM0 + Enable global ints
}

#pragma vector=TIMERA0_VECTOR
__interrupt void TimerA0(void)
{
   new_cap = TACCR0;

   TACCTL0 ^= CM_3;                         // change edge             //OCY

   cap_diff = new_cap - old_cap;

   diff_array[index] = cap_diff;            // record difference to RAM array
   capture_array[index++] = new_cap;
   if (index == 16)
   {
     index = 0;
     P1OUT ^= 0x01;                         // Toggle P1.0 using exclusive-OR
   }
   old_cap = new_cap;                       // store this capture value
   count ++;
   if (count == 32)
   {
     count = 0;
     _NOP();                                // SET BREAKPOINT HERE
   }

}

Thank you very much, sir.

I will let let you know the test results.

Thanks again,

JIMMY

Dear Mr Oldcow

I tested the code above. I seemed to compile OK, but when

I tried to simulate the code on my PC using the built-in IAR

simulator on TIMERA0_VECTOR , the progam error message

popped up right way.

“User error: illegal opcode found on address 0x0”

I set the interrupt setup as follow: (but I don’t think that was the cause of the problem)

interrupt = TIMERA0_VECTOR

description = 0x12 2 TACCTL0.CCIE TACCTL0.CCIFG

first activation = 10000

repeat interval = 5000

hold time = 250

variance = 5%

probality = 100

Any idea?

Thanks,

JIMMY

I think the Simulator itself is in error.

Use a real MSP430F chip and use FET-Debugger instead of Simulator. Do not use Single Step (which is buggy too). Set a Break-Point at the _NOP(); and click Go. When the CPU hits the Break-Point, open a Memory Window and inspect what is in diff_array[16] (0x0206 to 0x0225) and capture_array[16] (0x0226 to 0x0245)