Part Number:MSP430F5172
您好!
电路目的用于测量两个脉冲的上升沿的间隔时间,希望达到4nS的精度。
下面是电路与程序说明。
电路通过PJ.4和PJ.5外接11.0592MHz晶振
设置如下:
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
}
串口设置如下:
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设置:
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
}
中断程序:
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;
}
其中TD1是产生脉冲,用于测试。
我的程序可以测量到脉冲间隔时间,上面程序TD1模拟出11.05kHz(周期:90.49uS),TD0测量的结果是:407(90.49/407=0.22uS),而且后两为不停跳动,根据手册芯片可以达到4nS的分辨率,请问如何设置才能提高测量分辨率?
谢谢!
Cherry Zhou:
您好我们已收到您的问题并反馈,预计将于24小时内给您答复。谢谢!
,
Cherry Zhou:
1)通过您提供的信息,看起来像是正在从 DCO 运行 SMCLK (UCSCTL4 : SELS 不变)。DCO 无法提供所需精度,而且由于调制器,DCO也会有相当大的 (有意的) 抖动。
我们建议您从 ACLK (晶振) 运行 TD0。
2)以及我们不建议您在每次捕获时清除计数器 (TDCLR) ,这会给开始时间带来一些延迟。 我们还是建议您使定时器运行,然后从连续 (上升) 边沿中减去捕获。