430F149定时器B捕获PWM表现异常

2019-07-18 14:45发布

本帖最后由 tonyhasadream 于 2017-3-26 19:00 编辑

是这样的,手头上有几个输出为方波的传感器,现在需要使用MSP430F149来解析这个方波。
由于传感器数目多了,所以为了避免麻烦只能使用定时器B的捕获组单元。

但奇怪的是,同一套代码使用定时器A能够很好地解析方波(程序是测占空比的)

但是一旦运用到定时器B上去,就发生了异常,也不知道是不是和锁存器有关系

以下是我的代码:


#include  <msp430x14x.h>

unsigned int tem=0;
unsigned long start=0,temp=0,end=0,overflow=0,hold,length;
double per;

void main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
  P2DIR = 0XFF;                            // 流水灯是P2组IO口
  P2OUT = 0XFF;
  TBCTL = TBSSEL_2 + MC_2 + TBIE;           // SMCLK, contmode, interrupt
  TBCCTL1=CM_1+SCS+CAP+CCIE+CCIS_0;
  P4DIR&=~BIT1;                        //P4.1为输入
  P4SEL|=BIT1;
  /*
  TACTL = TASSEL_2 + MC_2 + TAIE;           // SMCLK, contmode, interrupt
  TACCTL1=CM_1+SCS+CAP+CCIE+CCIS_0;
  P1DIR&=~BIT2;                        //P1.2为输入
  P1SEL|=BIT2;
  */
  while(1)
  {
    length=overflow*65535+temp-start;
    per=hold/1.0/length;
    _BIS_SR(LPM0_bits + GIE);                 // Enter LPM0 w/ interrupt
  }
}

// Timer_B7 Interrupt Vector (TBIV) handler
#pragma vector=TIMERB1_VECTOR
__interrupt void Timer_B(void)
{
switch( TBIV )//(TBIV)
{
   case  2:

         if(TBCCTL1&CM_1)                       //上升沿
         {
           P2OUT |= BIT1;
           tem++;
           if(tem==1)                             //一个周期的开始
           {
             TBCCTL1=(TBCCTL1&(~CM_1))|CM_2;       //更变设置为下降沿触发
             start=TBCCR1;                     //记录初始时间(捕捉产生start)
             overflow=0;                       //溢出计数变量复位
           }
           else if(tem==2)                    //一个完整周期的结束+另一个新周期的开始
           {
             P2OUT ^= BIT2;
             tem=0;
             temp=TBCCR1;                      //把捕获/比较寄存器里的值记录下来
             _DINT();                          //关中断
             LPM0_EXIT;                         //从低功耗0模式退出
           }
         }
          else if(TBCCTL1&CM_2)                  //下降沿
         {  
            P2OUT &= ~BIT1;
            TBCCTL1=(TBCCTL1&(~CM_2))|CM_1;        //更变设置为上升沿触发           
            end=TBCCR1;                        //用start,end,overflow计算脉冲宽度
            hold=overflow*65535+end-start;         
         }

     /*
         if(TACCTL1&CM_1)                       //上升沿
         {
           P2OUT |= BIT1;
           tem++;
           if(tem==1)
           {
             TACCTL1=(TACCTL1&(~CM_1))|CM_2;       //更变设置为下降沿触发
             start=TACCR1;                     //记录初始时间(捕捉产生start)
             overflow=0;                       //溢出计数变量复位
           }
           else if(tem==2)
           {
             P2OUT ^= BIT2;
             tem=0;
             temp=TACCR1;                      //把捕获/比较寄存器里的值记录下来
             _DINT();                          //关中断
             LPM0_EXIT;                         //从低功耗0模式退出
           }
         }
          else if(TACCTL1&CM_2)                  //下降沿
         {  
            P2OUT &= ~BIT1;
            TACCTL1=(TACCTL1&(~CM_2))|CM_1;        //更变设置为上升沿触发           
            end=TACCR1;                        //用start,end,overflow计算脉冲宽度
            hold=overflow*65535+end-start;         
         }
     */
         break;
   case  4: break;                        
   case 14: overflow++;
            P2OUT ^= BIT0;                  // overflow
            break;
}
}


我在三个位置设置了LED灯来观察程序运行的状态。

定时器A和B的溢出中断(对应流水灯P2.0)都是正常的,定时器A的周期开始标志灯P2.1和完整周期结束灯P2.2表现正常数据正确;

但是定时器B的周期开始标志灯和完整周期结束灯抖得像穿了滑板鞋一样,当然数据也是不对的,请问这是为啥啊?
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
6条回答
dirtwillfly
1楼-- · 2019-07-18 14:58
定时器B和A有一些差异,这个资料说的比较清楚,你可以看看https://wenku.baidu.com/view/78b9c693e45c3b3566ec8bb5.html
uptown
2楼-- · 2019-07-18 15:50
uptown
3楼-- · 2019-07-18 19:30
tonyhasadream
4楼-- · 2019-07-18 22:17
dirtwillfly 发表于 2017-3-26 20:55
定时器B和A有一些差异,这个资料说的比较清楚,你可以看看https://wenku.baidu.com/view/78b9c693e45c3b356 ...

后来仔细查看了一下原理图,这个锁存器是比较模块激活时才有用的;
从原理图上看,有一个二选一选择器,锁存器在0号线路上,而捕获模块在1号线路上,应该是不会影响到捕获工作的。
如果我有理解错还希望能纠正。
tonyhasadream
5楼-- · 2019-07-19 01:37
uptown 发表于 2017-3-26 21:45
http://download.csdn.net/download/yinxinerbian/3505874

我采用定时器A捕获已经能完美解析出PWM的参数(数据正确);
定时器B和A采用的是同一套代码,从代码来看,工作模式的配置也是相同的;
采用你提供的第一个链接的定时器B捕获程序肯定有结果,因为我的程序也能进入ISR,但是测出来的数据是错的。
tonyhasadream
6楼-- · 2019-07-19 06:19
 精彩回答 2  元偷偷看……

一周热门 更多>