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.
使用捕获功能对频率信号进行测量,捕获到第一个上升沿时对TBCCR1寄存器值进行读取,赋值给SMCLK_Count_Num_start变量,设置当TBR寄存器在连续模式下连续溢出11次时停止捕获,将此时TBCCR1寄存器的值赋予SMCLK_Count_Num_stop变量,按如下公式进行计算:
SMCLK_Count_Num = 65535*overflow_Num + SMCLK_Count_Num_stop - SMCLK_Count_Num_start
Frequency = ((CaptureNum-1)*SMCLK_Frequency)/SMCLK_Count_Num
在调试过程中,出现现象为待测频率高于80kHz时 TIMERB1中断case14无法进入,溢出次数变量无法更新,导致程序卡死
请各位帮忙分析解答问题所在。
主程序如下:
#include <msp430fg439.h>
#include "main.h"
void main(void)
{
WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
SetupClock();
Capture_Pos();
__enable_interrupt();//中断使能
while(1)
{
if (cap_finish_flag ==1)
{
cap_finish_flag = 0;
SMCLK_Count_Num = 65535*overflow_Num + SMCLK_Count_Num_stop - SMCLK_Count_Num_start;
Frequency = ((CaptureNum-1)*SMCLK_Frequency)/SMCLK_Count_Num;
CaptureNum = 0;
overflow_Num = 0;
TB0CTL |= MC_2;
TBCTL |= TBCLR + TBIE;
TBCCTL1 |= CCIE;
}
}
}
void SetupClock()
{
uint16_t tmpv;
FLL_CTL1 &= ~XT2OFF; //开启外部振荡器
do
{
IFG1 &= ~OFIFG; //清除晶振失效标志
for (tmpv = 0xff; tmpv > 0; tmpv--);
}
while((IFG1 & OFIFG)!=0); //*等待外部晶振就绪
IFG1 &= ~OFIFG;
FLL_CTL1 |= SELM_XT2+SELS; //选择MCLK,选择SMCLK //+DIVM_1
}
void Capture_Pos()//TIMER_B 捕获/比较寄存器 0
{
P2SEL |= BIT2; //TIMER B1通道
P2DIR &= ~BIT2;
//SMCLK做时钟源,16位计数器,不分频,连续计数模式,开中断
TB0CTL |= TBSSEL_2 + CNTL_0 + ID_0 + MC_2 + TBCLR + TBIE;
TBCCTL1 = CM_1+ CCIS_1 + SCS + CAP + CCIE;//上升沿触发,同步捕获,使能中断CCI1B
}
#pragma vector = TIMERB1_VECTOR
__interrupt void Timer_B1 (void)
{
switch(TBIV)
{
case 2:
TBCCTL1 &= ~COV ;
CaptureNum++;
if(CaptureNum== 1)
{
SMCLK_Count_Num_start = TBCCR1;
overflow_Num = 0;
}
if(overflow_Num== 11)
{
SMCLK_Count_Num_stop = TBCCR1;
cap_finish_flag = 1;
TB0CTL |= MC_0;
TBCTL &= ~TBIE;
TBCCTL1 &=~CCIE;
}
break;
case 4:
break;
case 14:
overflow_Num ++ ;
break;
default:
break;
}
}
待测频率80Khz是可以测量的,在数据手册内有相关的说明
www.ti.com.cn/.../msp430fg439.pdf
5.6 Inputs Px.y, TAx, TBx
在G2553有相关的测试例程,您可以参考一下写法
dev.ti.com/.../node
抱歉,目前手边没有MSP430FG系列的板子,我回头找一下其他板子来测试一下
已参考该例程进行测试,DEBUG时,程序会在如下程序不断循环:
if (TB0CCTL1 & COV) // Check for Capture Overflow
while(1);
测试程序如下:
#include <msp430fg439.h>
#include "main.h"
unsigned long SMCLK_Count_Num = 0;
unsigned long Frequency = 0;
unsigned char Count = 0x0;
unsigned int REdge1, REdge2;
void main(void)
{
WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
SetupClock();
Capture_Pos();
// __enable_interrupt();//中断使能
while(1)
{
// __enable_interrupt();//中断使能
__bis_SR_register(LPM0_bits + GIE); // Enter LPM0
__no_operation(); // For debugger
if (TB0CCTL1 & COV) // Check for Capture Overflow
while(1);
SMCLK_Count_Num = REdge2 - REdge1;
Frequency = (Count*SMCLK_Frequency)/SMCLK_Count_Num;
// TBCTL |= TBCLR + TBIE;
// TBCCTL1 |= CCIE;
}
}
void SetupClock()
{
uint16_t tmpv;
FLL_CTL1 &= ~XT2OFF; //开启外部振荡器
do
{
IFG1 &= ~OFIFG; //清除晶振失效标志
for (tmpv = 0xff; tmpv > 0; tmpv--);
}
while((IFG1 & OFIFG)!=0); //*等待外部晶振就绪
IFG1 &= ~OFIFG;
FLL_CTL1 |= SELM_XT2+SELS; //选择MCLK,选择SMCLK //+DIVM_1
}
void Capture_Pos()//TIMER_B 捕获/比较寄存器 0
{
P2SEL |= BIT2; //TB1端口
P2DIR &= ~BIT2;
//SMCLK做时钟源,16位计数器,不分频,连续计数模式,开中断
TB0CTL |= TBSSEL_2 + MC_2 + TBCLR ;
TBCCTL1 = CM_1+ CCIS_1 + SCS + CAP + CCIE;//上升沿触发,同步捕获,使能中断CCI1B
}
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = TIMERB1_VECTOR
__interrupt void TIMER0_B1_ISR (void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(TIMER0_B1_VECTOR))) TIMER0_B1_ISR (void)
#else
#error Compiler not supported!
#endif
//__interrupt void Timer_B1 (void)
{
switch(__even_in_range(TB0IV,0x0A)) //需要判断中断的类型
{
case TB0IV_NONE:
break;
case TB0IV_TBCCR1:
if (!Count)
{
REdge1 = TB0CCR1;
Count++;
}
else
{
REdge2 = TB0CCR1;
Count=0x0;
// TBCTL &= ~TBIE;
// TBCCTL1 &=~CCIE;
__bic_SR_register_on_exit(LPM0_bits + GIE); // Exit LPM0 on return to main
}
break;
case TB0IV_TBCCR2:
break;
case TBIV_3:
break;
case TBIV_4:
break;
case TBIV_5:
break;
case TBIV_6:
break;
case TB0IV_TBIFG:
break;
default:
break;
}
}