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.

CCS/MSP432P401R: Unable to measure frequency less than 100 m Hz ( Overflow count is not correct )

Part Number: MSP432P401R

Tool/software: Code Composer Studio

Hello I am using MSP432P401R Timer A to measure low frequency signals. I have configured Timer A in Capture Mode. Timer runs in Continuous Mode. Timer Input Clock is (ACLK/8=4096 Hz). I am recording count value when a positive edge occurs. Comparing two adjacent count values I am calculating frequency of input signal. From 100 m Hz (0.1 Hz) onwards, frequency measurement is accurate.

But I have issue with low frequencies less than 100 m Hz.

I tried to debug the issue by applying different frequencies and recording more than two edges. I observe that when no of overflows occur between two positive edges. Recorded Overflow count is always one. Even though for 10 m Hz overflow count value between two edges should be 5 but it is still 1.

For example when I applied 10 m Hz signal and I captured 10 positive edges (Total Run time more than 17 mins). Overflow count value is 10 which is not accurate. It should be 50.

Is there any limit on maximum low frequency that you can measure with MSP432P401R?

I have also pasted my code

#include "msp.h"
#include <stdint.h>

#define NUMBER_TIMER_CAPTURES 100
volatile uint32_t timerAcaptureValues[NUMBER_TIMER_CAPTURES] = {0};
uint32_t timerAcapturePointer = 0;

uint32_t overflow_count = 0;
uint32_t captureValue = 0;

int main(void)
{
WDT_A->CTL = WDT_A_CTL_PW | // Stop watchdog timer
WDT_A_CTL_HOLD;

//Configure SMCLK = MCLK = 12MHz, ACLK = REFOCLK.
CS->KEY = CS_KEY_VAL ; // Unlock CS module for register access
CS->CTL0 = 0; // Reset tuning parameters
CS->CTL0 = CS_CTL0_DCORSEL_3; // Set DCO to 12MHz (nominal, center of 8-16MHz range)
// Select ACLK = REFO, SMCLK = MCLK = DCO
CS->CTL1 = CS_CTL1_SELA_2 | CS_CTL1_SELS_3 | CS_CTL1_SELM_3;
CS->KEY = 0; // Lock CS module from unintended accesses


// Configure GPIO
P2->SEL0 |= BIT5; // TA0.CCI2A input capture pin, second function
P2->DIR &= ~BIT5;


// Timer0_A Setup
TIMER_A0->CCTL[2] = TIMER_A_CCTLN_CM_1 | // Capture rising edge,
TIMER_A_CCTLN_CCIS_0 | // Use CCI2A=ACLK,
TIMER_A_CCTLN_CCIE | // Enable capture interrupt
TIMER_A_CCTLN_CAP | // Enable capture mode,
TIMER_A_CCTLN_SCS; // Synchronous capture

TIMER_A0->CTL |= TIMER_A_CTL_TASSEL_1 | // Use ACLK as clock source,
TIMER_A_CTL_ID__8| // Div8
TIMER_A_CTL_MC_2 | // Start timer in continuous mode
TIMER_A_CTL_CLR; // clear TA0R

SCB->SCR |= SCB_SCR_SLEEPONEXIT_Msk; // Enable sleep on exit from ISR

// Enable global interrupt
__enable_irq();

NVIC->ISER[0] = 1 << ((TA0_N_IRQn) & 31);

__sleep();
__no_operation();
}


// Timer A0 interrupt service routine
void TA0_N_IRQHandler(void)
{
//Overflow?
if(TIMER_A0->CTL & TIMER_A_CTL_IFG)
{
// Clear timer overflow interrupt flag
TIMER_A0->CTL &= ~TIMER_A_CTL_IFG;

overflow_count ++;
// Frequencyinput_Overflow_callback();
}

//Compare?
if(TIMER_A0->CCTL[2] & TIMER_A_CCTLN_CCIFG)
{
// Clear the capture interrupt flag
TIMER_A0->CCTL[2] &= ~TIMER_A_CCTLN_CCIFG;

if (timerAcapturePointer == NUMBER_TIMER_CAPTURES)
{
// Stop timer
TIMER_A0->CTL |= TIMER_A_CTL_TASSEL_2 | // Use SMCLK as clock source,
TIMER_A_CTL_MC_0 ; // Stop timer
// captureValue = calculate_average_capture_value(timerAcaptureValues,NUMBER_TIMER_CAPTURES );
}
else
{
timerAcaptureValues[timerAcapturePointer++] = TIMER_A0->CCR[2];
}

}
}