This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430F5172: Measured pulses with TD

Part Number: MSP430F5172

The purpose of the circuit is to measure the time between the rising edges of two pulses, with a desired accuracy of 4 nS.

Circuit and Program:

The Circuit : externally connected to the 11.0592 MHz crystal through PJ.4 and PJ.5

Settings are as follows:

void initClock()
{
    // Configure XT1
    PJSEL |= BIT4+BIT5;                       // Port select XT1
    UCSCTL6 &= ~(XT1OFF);                     // XT1 On
    UCSCTL6 |= XTS + XCAP_3;                        // Internal load cap

    // Loop until XT1 fault flag is cleared
    do
    {
      UCSCTL7 &= ~XT1LFOFFG;                  // Clear XT1 fault flags
    }while (UCSCTL7&XT1LFOFFG);               // Test XT1 fault flag

    UCSCTL3 |= SELREF_2;                      // Set DCO FLL reference = REFO
    UCSCTL4 |= SELA_0;                        // Set ACLK = XT1CLK

    // Initialize DCO to 2.45MHz
     __bis_SR_register(SCG0);                  // Disable the FLL control loop
     UCSCTL0 = 0x0000;                         // Set lowest possible DCOx, MODx
     UCSCTL1 = DCORSEL_5;                      // Set RSELx for DCO = 4.9 MHz
     UCSCTL2 = FLLD_0 + 300;                    // Set DCO Multiplier for 2.45MHz
                                               // (N + 1) * FLLRef = Fdco
                                               // (74 + 1) * 32768 = 2.45MHz
                                               // Set FLL Div = fDCOCLK/2

     __bic_SR_register(SCG0);                  // Enable the FLL control loop

     // Worst-case settling time for the DCO when the DCO range bits have been
     // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx
     // UG for optimization.
     // 32 x 32 x 2.45 MHz / 32,768 Hz = 76563 = MCLK cycles for DCO to settle
     //__delay_cycles(76563);
     __delay_cycles(500000);//
     // Loop until XT1 & DCO fault flag is cleared
     do
     {
       UCSCTL7 &= ~(XT1LFOFFG + XT1HFOFFG + DCOFFG);
                                               // Clear XT1,DCO fault flags
       SFRIFG1 &= ~OFIFG;                      // Clear fault flags
     }while (SFRIFG1&OFIFG);                   // Test oscillator fault flag

}

Serial port settings are as follows:

void UARTConfig()
{
    //UART CONFIG
      P1SEL |= BIT1+BIT2;
      UCA0CTLW0 |= UCSSEL_1;               // CLK = ACLK
      // Baud Rate calculation
      // 11059200/(9600) = 1152(L:0x80 H:0x04
      UCA0BR0 = 0x80;
      UCA0BR1 = 0x04;
      UCA0MCTL |= UCBRS_3;

      // over sampling
      UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
      UCA0IE |= UCRXIE;                         // Enable USCI_A0 RX interrupt
}

TD0CCR0 settings are as follows:

void initTD1()
{
    // Configure the TD0CCR0 to do input capture
    TD0CTL2 &= ~TDCAPM1;                      // Channel 1; single capture mode
    TD0CCTL1 = CAP + CM_1 + CCIE + SCS + CCIS_0;
                                              // TD0CCR1 Capture mode; CCI1A; BothTD0CCR1
                                              // Rising and Falling Edge; interrupt enable
    TD0CTL0 |= TDSSEL__SMCLK + MC_2 + MC_0 + TDCLR;       // SMCLK, Cont Mode; start timerSMCLK,

    // Configure TD1.1 to output PWM signal
    // Period = 82/32khz = 2.5ms ~ 400Hz Freq
    TD1CCR0 = 1000;                          // Period Register
    TD1CCR1 = 500;                            // TD1.1 25% dutycycle
    TD1CCTL1 |= OUTMOD_7;                    // TD1CCR1, Reset/Set
    TD1CTL0 = TDSSEL_1 + MC_1 + TDCLR;       // ACLK, upmode, clear TDR
}

The interrupt program is as follows:

switch(__even_in_range(TD0IV,0x1E))
  {
      case  0x0: break;                     // Vector  0:  No interrupt
      case  0x2:                            // Vector  2:  TDCCR1 CCIFG
          if(!Count)
          {
              TD0CTL0 |= TDSSEL__SMCLK + MC_2 + TDCLR;
               //FEdge1 = TD0CCR1;              // 1st falling edge
               //REdge1 = TD0CL1;               // 1st rising edge
               Count++;
          }
          else
          {
              TD0CTL0 |= TDSSEL__SMCLK + MC_0 + TDCLR;
                REdge2 = TD0CL1;              // 2nd rising edge
                FEdge2 = TD0CCR1;             // Dummy Read
                Count = 0x0;
                //__bic_SR_register_on_exit(LPM0_bits + GIE);  // Exit LPM0 on return to main
           }

        break;
      case 0x4: break;                      // Vector  4:  TDCCR2 CCIFG
      case 0x6: break;                      // Vector  6:  TDCCR3 CCIFG
      case 0x8: break;                      // Vector  8:  TDCCR4 CCIFG
      case 0xA: break;                      // Vector 10:  TDCCR5 CCIFG
      case 0xC: break;                      // Vector 12:  TDCCR5 CCIFG
      case 0xE: break;                      // Vector 14:  -
      case 0x10:break;                      // Vector 16:  TDIFG
      case 0x12:break;                      // Vector 18:  TDHINT TDHFLIFG
      case 0x14:break;                      // Vector 20:  TDHINT TDHFHIFG
      case 0x16:break;                      // Vector 22:  TDHINT TDHLKIFG
      case 0x18:break;                      // Vector 24:  TDHINT TDHUNLKIFG
      case 0x1A:break;                      // Vector 26:  -
      case 0x1C:break;                      // Vector 28:  -
      case 0x1E:break;                      // Vector 28:  -
      default:  break;
  }

NOTE: TD1 is the generation pulse for testing.

ISSUE:

The program can measure the pulse interval time, the above program TD1 simulates 11.05 kHz (period: 90.49 uS), and the TD0 measurement is 407 (90.49/407 = 0.22 uS), but the last two bits are beating.

According to the manual, the chip can reach a resolution of 4 nS, the customer would like to know how to set it to improve the measurement resolution.

Thanks!

Best Regards,

Cherry Zhou

  • 1) It seems that you're running SMCLK from the DCO (UCSCTL4:SELS unchanged). The DCO won't give you the kind of accuracy you're looking for and, more important, has a fair amount of (deliberate) jitter due to the modulator. I suggest you run TD0 from ACLK (crystal) instead.

    2) I don't recommend clearing the counter (TDCLR) on each capture, since this introduces an unpredictable latency into the start time. Rather, let the timer run and subtract the  captures from successive (rising) edges.

**Attention** This is a public forum