在MSP-TS430PN80的目标板上用MSP430F2619的芯片,采用4M的外部晶振,定时器timerB无法准确捕捉到高于20K的频率,请问是哪里出现了问题?

MSP-TS430PN80的目标板上用MSP430F2619的芯片,采用4M的外部晶振,定时器timerB无法准确捕捉到高于20K的频率,请问是哪里出现了问题?

程序代码如下:

void SetupClock()
{
    uint16_t tmpv;
    BCSCTL1 &= ~XT2OFF;         //开启外部振荡器
    BCSCTL3 |= XT2S_2;          //选择频率范围3- to 16-MHz
    do
    {
        IFG1 &= ~OFIFG;           //清除晶振失效标志
        for (tmpv = 0xff; tmpv > 0; tmpv--);
    }
    while((BCSCTL3 & XT2OF) == 1);    //*等待外部晶振就绪
    BCSCTL2 |= SELM_2+SELS;           //选择MCLK,选择SMCLK //+DIVM_1
}

void Capture_Pos(void)//TIMER_B 捕获/比较寄存器 0
{
 
    TB0CTL |= TBSSEL_2 + ID_0 + MC_2 + TBCLR + TBIE;
    TBCCTL0 = CM_1+CCIS_1+SCS+CAP+CCIE;//T,上升沿触发,同步捕获,使能中断CCI1A
}

#pragma vector = TIMERB0_VECTOR
__interrupt void Timer_B0 (void)
{
    static double Pre_T_Frequency = 0;
    if(TBCCTL0 & CM0)
    {
        T_CaptureNum++;
        if(T_CaptureNum == 1)
        {
            T_cap_count_first = TBCCR0;
        }else if(T_CaptureNum >= 2)
        {
            T_cap_count_second = TBCCR0;
            if(T_cap_count_second>T_cap_count_first)
            {
                T_count_num = T_cap_count_second-T_cap_count_first;
            }else{
                T_count_num = 0xFFFF+T_cap_count_second-T_cap_count_first;
            }
            T_Frequency = ((float)4000000)/T_count_num;
            T_CaptureNum = 0;

            if(T_Frequency != Pre_T_Frequency)
            {
                Pre_T_Frequency = T_Frequency;
            }else{
                close_T_capture();
            }

        }
    }
}

3 个回复

  • 根据您的程序,个人感觉timerB的ISR中断服务程序内的运算太多,可能会导致在高信号频率下可能会超速运行。您只需在ISR中获取新的CCR0,进行减法并将结果存储在全局变量中,然后返回即可。建议您让main执行其余的算术运算。

    另外建议使用int运算而不是使用float运算。

     

    若是该回复回答了您的问题,请点击“确认此为答案”,谢谢

    If a post answers your question, please mark it with the "verify answer" button.

  • 回复 Susan Yang:

    该建议应该有效。但解决该问题,应是修改了时钟初始化程序
    原初始化程序为
    void SetupClock()
    {
    uint16_t tmpv;
    BCSCTL1 &= ~XT2OFF; //开启外部振荡器
    do
    {
    IFG1 &= ~OFIFG; //清除晶振失效标志
    for (tmpv = 0xff; tmpv > 0; tmpv--);
    }
    while((BCSCTL3 & XT2OF) == 1); //*等待外部晶振就绪,该句有误
    BCSCTL2 |= SELM_2+SELS; //选择MCLK,选择SMCLK //
    }

    如此写,是因为在研产品未在LFXT1连接32.768kHz低频晶振,仅在XT2接口连接8MHz高频晶振,如判断OFIFG置零,则陷入死循环。

    在使用MSP-TS430PN80目标板进行验证时,LFXT1连接32.768kHz低频晶振,XT2接口连接4MHz高频晶振,若初始化程序维持上述代码,则故障同样出现。

    更改初始化程序如下后

    void SetupClock()
    {
    unsigned int i;
    BCSCTL1 &= ~XT2OFF; //打开XT2振荡器
    BCSCTL2 |= SELM_2+SELS; //MCLK为8MHZ,SMCLK为8MHZ
    do{
    IFG1 &= ~OFIFG; //清楚振荡器错误标志
    for(i=0;i<100;i++)
    _NOP();
    }
    while ((IFG1&OFIFG)!=0); //如果标志位1,则继续循环等待
    IFG1 &= ~OFIFG;
    }

    其中修改 while((BCSCTL3 & XT2OF) == 1) 为 while ((IFG1&OFIFG)!=0)后,
    目标板运行正常,频率采样正常。

    初始化程序对运行会有这样的影响吗?

    强调,更换初始化程序后,问题解决。
  • 回复 user5960447:

    谢谢您的反馈

    具体您可以看一下 https://www.ti.com.cn/cn/lit/ug/slau144j/slau144j.pdf 

    在ti例程内是如下操作

      volatile unsigned int i;
    
      WDTCTL = WDTPW+WDTHOLD;                   // Stop WDT
      BCSCTL1 &= ~XT2OFF;                       // Activate XT2 high freq xtal
      BCSCTL3 |= XT2S_2;                        // 3 – 16MHz crystal or resonator
    
      // Wait for xtal to stabilize
      do
      {
      IFG1 &= ~OFIFG;                           // Clear OSCFault flag
      for (i = 0x47FF; i > 0; i--);             // Time for flag to set
      }
      while ((IFG1 & OFIFG));                   // OSCFault flag still set?
      
      BCSCTL2 |= SELM_2;                        // MCLK = XT2 HF XTAL (safe)

     

    若是该回复回答了您的问题,请点击“确认此为答案”,谢谢

    If a post answers your question, please mark it with the "verify answer" button.