Part Number: MSP430FG6626
Hi,
My purpose is to measure the on and off durations of a square signal. The frequency of the timer is 20MHz. I feed the signal (20kHz) from an external signal generator to P3.1. Below you will see my code. (This is shorter version of the original code to study the capture process. You would see some variable declarations not used in this snippet)
When I run the program very first time I see the captured values in the debug screen (8 values are captured) and they are in perfect match with the signal (e.g. 471, 622, 472, 622, 470, 621, 471, 622). But if I change the frequency or duty cycle of the external signal, captured values are no longer correct.
I read user guides, forums and learned that a possible cause might be the floating pin. I added pull-up (P3REN |= BIT1 ; P3OUT |= BIT1 ) and pull-down resistors (P3REN |= BIT1 ; P3OUT &= ~BIT1 ) for P3.1 but it didn't help. I connected 10K resistor between P3.1 and ground (without invoking P3REN). It also didn’t work.
Then I tried to change CCIS to GND or VCC in capture interrupt routine and/or in the main program but no success. The lines with two slash signs at the begin are my (failed) trials.
I would appreciate any suggestions.
#include <msp430.h>
#include <stdint.h>
#include <stdio.h>
#include <driverlib.h>
#include <math.h>
#define f_system 19988.48
#define Num_of_Channels 3
uint32_t say_ilk ;
uint8_t cnt = 0 ;
uint32_t T_system ;
uint16_t faz_farki ;
uint16_t ratio_system ;
uint16_t say1 ;
uint16_t T_deger[8] ;
void main(void)
{
//Stop WDT
WDT_A_hold(WDT_A_BASE);
PMM_setVCore(PMM_CORE_LEVEL_3);
//Set ACLK = XT1
UCS_initClockSignal(
UCS_ACLK,
UCS_XT1CLK_SELECT,
UCS_CLOCK_DIVIDER_1
);
ratio_system = round((float)f_system*1000/32768) ;
//Set Ratio and Desired MCLK Frequency and initialize DCO
UCS_initFLLSettle(
f_system,
ratio_system
);
P3DIR = 0x00 ; P3SEL = BIT1 ; // (P3.1) Timer TA1.CCI0A capture input ; pin no:43
// P3REN |= BIT1 ;
// P3OUT |= BIT1 ;
TA1CTL = TASSEL_2 | MC_2 | TACLR ; // 1:ACLK - 2:SMCLK, Continuous mode
TA1CCTL0 = CM_3 | CCIS_0 | SCS | CAP | CCIE ; // = Capture on both rising and falling edges, CCIxA
__enable_interrupt();
while (1)
{
for (fr=22000 ; fr>19000 ; fr = fr-1) // this for loop is redundant in this snippet
{
TA1CCTL0 = CM_2 | CCIS_0 | SCS | CAP | CCIE ; // TA1CCTL0 |= CCIE would be good enough
// TA1CCTL0 = CM_3 | CCIS_3 | SCS | CAP | CCIE ;
// TA1CCTL0 = CM_3 | CCIS_2 | SCS | CAP | CCIE ;
}
}
}
#pragma vector = TIMER1_A0_VECTOR
__interrupt void TIMER1_A0_ISR (void) // Flag cleared automatically
{
static uint16_t LastTime = 0; // Last time captured
T_deger[cnt] = TA1CCR0 ;
faz_farki = T_deger[cnt] - LastTime ; // find interval (counts)
LastTime = T_deger[cnt]; // Save time for next capture
cnt = cnt + 1 ;
if (cnt>7) // 8 captures
{
TA1CCTL0 &= (~CCIE) ; // go out of interrupt routine
// TA1CCTL0 = CM_3 | CCIS_2 | SCS | CAP ;
// TA1CCTL0 = CM_3 | CCIS_2 | SCS | CAP ;
cnt = 0 ;
}
// TA1CCTL0 &= (~CCIE) ;
// TA1CCTL0 = CM_3 | CCIS_3 | SCS | CAP ;
// TA1CCTL0 = CM_3 | CCIS_2 | SCS | CAP ;
}