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.

MSP430在没有捕获事件发生时,TBR 的值也会保存到TBCCRx 中

Other Parts Discussed in Thread: MSP430F1611

您好!

     有个问题困扰好久了,我在做定时器的捕获实验,发现MSP430F1611在没有捕获事件发生时,TBR 的值也会保存到TBCCRx 中,可是MSP430用户指南里明确说明了当一个捕获被执行时,TBR 才会被复制到 TBCCRx 寄存器中,还有捕获测时间间隔,发现每次都少了60us,这是为什么呢???我的信号源是通过PWM输出的,很稳定。

      弄了两天了,还没找到原因,拜托各位大神拯救一下菜鸟!!!!!!

  • 如果方便的话,建议提供下程序代码。

    不容易猜到。

  • 您好,发现你帮我回答几次了,真的非常感谢!!!!那个很抱歉今天才回复,昨天晚上不知怎么回事,代码一直不能插入。

    对于MSP430在没有发生捕获时,TBR的值也会保存在TBCCRX的问题,我知道原因了,我当时是在单步执行时检测TBCCRX的值,这种做法就是错的,因为虽然代码暂停运行了,但外部信号源还是在变化,所以此时测TBCCRX的值也就有问题了。

    但是现在又不幸发现新的问题了,对于不同频率的信号源所测的时间间隔精确度不同,时钟源为4M,是不是定时器溢出的代码写的有问题呢??下表是在不同频率信号源下,测得TBCCRX误差个数

            信号源频率            实际测得误差的个数(都是比计算值少测的个数)
    100hz 20个
    1khz 120个
    10khz  1个
    100khz 0个

    再次麻烦您帮我看一下了!!!感激不尽!!!!   O(∩_∩)O  
    #include<msp430f1611.h>
    #define uchar unsigned char
    #define uint unsigned int
    uint width[15]={0};
    uint i=0;
    double cap_ave=0;
    uint new_cap=0;
    uint old_cap=0;
    uint cap_diff=0;
    uint diff_array[16];                // RAM array for differences
    uint capture_array[16];             // RAM array for captures
    uchar index=0;
    uint count = 0;
    uint test=0;
    void main()
    {
      WDTCTL=WDTPW+WDTHOLD; //关闭看门狗
      P4SEL |=BIT0; //P4.0 作为捕获模块功能的输入端输入方波
      P4DIR &=~BIT0;
      P5SEL |=BIT4+BIT5;//SMCLK,MCLK频率输出
      P5DIR |=BIT4+BIT5;
      //P1SEL |= BIT0;
      //P1DIR |=BIT0;
      //-------开晶振 XT2---------BCSCTL1&=~XT2OFF; //打开 XT2 振荡器
      BCSCTL1&=~XT2OFF; 
      do
      {
        IFG1 &= ~OFIFG; // 清除振荡器失效标志
        for (i=256;i>0;i--); // 延时,等待 XT2 起振
      }
      while ((IFG1 & OFIFG) != 0); // 判断 XT2 是否起振
      BCSCTL2 =SELM_2+SELS; //选择 MCLK=SMCLK 为 XT2
      //-----------------------------TBCCTL0&=~(CCIS1+CCIS0); // 捕获源为 P4.0,即 CCI0A(也是 CCI0B)
      TBCCTL0&=~(CCIS1+CCIS0); // 捕获源为 P4.0,即 CCI0A(也是 CCI0B)
      TBCCTL0|=CM_3+SCS+CAP; //下降沿捕获,同步捕获,工作在捕获模式
      TBCCTL0|=CCIE; //允许捕获比较模块提出中断请求
    //  TBCTL|=ID_1;   //8分频 ,MCLK 1Mhz
      TBCTL|=TBSSEL_2; //选择时钟 MCLK
      TBCTL|=TBCLR; //定时器清零,
      //定时器开始计数(连续计数模式 0~0xFFFF)
      TBCTL|=MC_2;
      _EINT();
      while(1)
     {
         if(TBCTL&TBIFG)  //定时器溢出清零
        {
          TBCTL&=~TBIFG;
          count++;
        }
        
        if(TBCCTL0&COV)  //二次捕获溢出逻辑清零
        { 
          TBCTL|=MC_0;
          TBCCTL0 &=~COV;
          TBCTL|=MC_2;
        }
      }
    }
    //―――――定时器 TB 的 CCR0 的中断:用于检测脉冲上升与下降沿――――
    #pragma vector=TIMERB0_VECTOR
    __interrupt void TimerB0(void)
    {
     
      if( TBCCTL0 &CCIFG)
      {
        //下降沿检测
         new_cap= TBCCR0+count*65536; //记录下结束时间
         count=0;
         cap_diff = new_cap -old_cap;
         width[i++] = cap_diff;
         old_cap=new_cap;
         if(i==3) 
         {
              for(uint n=1;n<i;n++)
                cap_ave +=(double)(width[n]); 
              cap_ave =cap_ave/(i-1);
              i=0;  
              cap_ave=0;   
         }
      }
       TBCCTL0 &=~CCIFG;
    }