TI中文支持网
TI专业的中文技术问题搜集分享网站

MSP430FG439,使用捕获功能测频率时中断冲突问题

       使用捕获功能对频率信号进行测量,捕获到第一个上升沿时对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;
    }
}

Susan Yang:

待测频率80Khz是可以测量的,在数据手册内有相关的说明 www.ti.com.cn/…/msp430fg439.pdf 5.6 Inputs Px.y, TAx, TBx 在G2553有相关的测试例程,您可以参考一下写法 dev.ti.com/…/node 抱歉,目前手边没有MSP430FG系列的板子,我回头找一下其他板子来测试一下

user5960447:

回复 Susan Yang:

已参考该例程进行测试,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;    }}

Susan Yang:

回复 user5960447:

好的,谢谢反馈 我手边没有这个板子,拿G2553的板子来测试一下后回复

Susan Yang:

回复 user5960447:

我用G2553的板子测试了一下例程是没有问题的,抱歉没有直接FG439的板子来测试

您使用您自己之前的程序是可以测量频率的?只是当待测频率高于80kHz时会有问题?您现在SMCLK 是多少?可以适当增大一下频率

Timer 用作Capture模式时,测量频率及精度取决于Timer的时钟源以及主频。

需要有足够快的时钟源进行边沿捕获,同时还需要有足够快的响应时间进中断进行数据保存和计算。

user5960447:

回复 Susan Yang:

之前的程序目前还没有低功耗模式切换,没有对COV标志位进行判断,会出现高于80kHz无法测量频率。

第二次测试程序是根据FG439芯片修改例程配置而来,程序会一直运行在检查捕获是否溢出的语句中,从我个人的理解4MHz时钟对80kHz频率捕获,应该不会有太大问题。

测试时频率信号来源为信号发生器。

目前测试用开发板为TI官方的MSP-FET430U80目标板搭配FG439芯片,使用32.768kHz和4MHz两个时钟晶振,是否与硬件有关?

我这边会再次检查程序,希望发现问题。

user5960447:

回复 user5960447:

例程已经可以在开发板跑通,尝试在此程序运行基础上,将更大频率的信号接入开发板,程序会停在while(1)循环内

Susan Yang:

回复 user5960447:

MCLK = 4MHz去捕获80kHz是可行的但不容易实现。程序中4MHz / 80kHz = 50个CPU时钟来处理每个捕获,其中大约一半用于ISR开销。

另外

1__bic_SR_register_on_exit(LPM0_bits + GIE);

这将禁用main中的中断,在该除法运算运行时,会导致COV超限。请尝试:

__ bic_SR_register_on_exit(LPM0_bits);

2 建议在在ISR中执行(Redge2-Redge1)减法

3 请将Redge1,Redge2以及SMCLK_Count_Num声明为“ volatile”试试

赞(0)
未经允许不得转载:TI中文支持网 » MSP430FG439,使用捕获功能测频率时中断冲突问题
分享到: 更多 (0)