请问用Timer B捕获PWM计算脉宽,能不能改成Timer A来做

楼主
请问用Timer B捕获PWM计算脉宽,能不能改成Timer A来做
[P]前天在坛子里看到,坛主发的例子,的确很好用,因为之前我是用Timer A来做的,结果总是没有中断响应,我想把下面的这个例子,改成Timer A ,怎么不行啊,问题出在哪?[/P][P]#include<msp430x14x.h>     
 unsigned int width[10]={0,0,0,0,0,0,0,0,0,0};
 unsigned int i=0;

 void main()
{
  WDTCTL=WDTPW+WDTHOLD;         //关闭看门狗

  //P4SEL|=BIT0;                          //P4.0作为捕获模块功能的输入端输入方波
   P1SEL|=BIT1; //换成P1.1作为捕获口                          
   //-------开晶振XT2---------

   BCSCTL1&=~XT2OFF;                //打开XT2振荡器
   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|=CM_2+SCS+CAP;           //下降沿捕获,同步捕获,工作在捕获模式
  TBCCTL0|=CCIE;                     //允许捕获比较模块提出中断请求
  TBCTL|=ID_3;
  TBCTL|=TBSSEL_2;                   //选择时钟MCLK
  TBCTL|=TBCLR;                      //定时器清零,
  //定时器开始计数(连续计数模式0~0xFFFF)
  TBCTL|=MC_2;*/[/P][P]  //把Timer B屏蔽,换成Timer A[/P][P]  TACCTL0&=~(CCIS1+CCIS0);          // 捕获源为P1.1,即CCI0A(也是CCI0B)
  TACCTL0|=CM_2+SCS+CAP;           //下降沿捕获,同步捕获,工作在捕获模式
  TACCTL0|=CCIE;                     //允许捕获比较模块提出中断请求
  TACTL|=ID_3;
  TACTL|=TBSSEL_2;                   //选择时钟MCLK
  TACTL|=TBCLR;                      //定时器清零,
  //定时器开始计数(连续计数模式0~0xFFFF)
  TACTL|=MC_2;*/



  _EINT();

 while(1);
}

//―――――定时器TB的CCR0的中断:用于检测脉冲上升与下降沿――――
#pragma vector=TIMERB0_VECTOR       
__interrupt void TimerB0(void)
{
   /*if(TBCCTL0&CM1)                        //捕获到下降沿
     {
       TBCTL|=TBCLR;
       TBCCTL0=(TBCCTL0&(~CM1))|CM0;    //改为上升沿捕获:CM1置零,CM0置一

     }
   else if(TBCCTL0&CM0)                    //捕获到上升沿
     {
       width[i++]=TBCCR0;                  //记录下结束时间
       TBCCTL0=(TBCCTL0&(~CM0))|CM1;   //改为下降沿捕获:CM0置零,CM1置一
       if(i==10) i=0;
              
     }*/[/P][P] [/P][P]  if(TACCTL0&CM1)                        //捕获到下降沿
     {
       TACTL|=TACLR;
       TACCTL0=(TACCTL0&(~CM1))|CM0;    //改为上升沿捕获:CM1置零,CM0置一

     }
   else if(TACCTL0&CM0)                    //捕获到上升沿
     {
       width[i++]=TACCR0;                  //记录下结束时间
       TACCTL0=(TACCTL0&(~CM0))|CM1;   //改为下降沿捕获:CM0置零,CM1置一
       if(i==10) i=0;
              
     }



}
[/P]
1楼
这里你依然用的是TB的中断向量当然不行了
[CODE]#pragma vector=TIMERB0_VECTOR       
__interrupt void TimerB0(void)[/CODE]
必须要同样换成TA的,我当做这个例子时选用TA的原因很重要一点是,TA会用作其他用途。PWM输出才用TB。
2楼
[P]哦,感谢DC版主及时解惑,
追问一下,我能不能同时用P4.0,P4.1捕获2组PWM脉冲,甚至更多7组[/P]
3楼
如果同时用TA或TB又做PWM输出又想做捕获(输入)的话;这个应用有点复杂。理论上是可以同时PWM又可以捕获的。这个得灵活地使用GPIO的分配。尽量不冲突或复用IO。
4楼
[P]调试过程有遇到问题了[/P][P]我现在要用P4.0-P4.3,同时捕获4路外来的PWM.计算脉宽,但是我同时开启4路捕获,1,2,3路就不工作[/P][P] //TB0[/P][P]  TBCCTL0&=~(CCIS1+CCIS0);          // 捕获源为P4.0,即CCI0A(也是CCI0B)
  TBCCTL0|=CM_2+SCS+CAP;           //下降沿捕获,同步捕获,工作在捕获模式
  TBCCTL0|=CCIE;                     //允许捕获比较模块提出中断请求
  //TB1
  TBCCTL1&=~(CCIS1+CCIS0);          // 捕获源为P4.1,即CCI0A(也是CCI0B)
  TBCCTL1|=CM_2+SCS;//+CAP;           //下降沿捕获,同步捕获,工作在捕获模式
  //TBCCTL1|=CCIE;                     //允许捕获比较模块提出中断请求
  //TB2
  TBCCTL2&=~(CCIS1+CCIS0);          // 捕获源为P4.2,即CCI0A(也是CCI0B)
  TBCCTL2|=CM_2+SCS;//+CAP;           //下降沿捕获,同步捕获,工作在捕获模式
  //TBCCTL2|=CCIE;                     //允许捕获比较模块提出中断请求
  //TB3
  TBCCTL3&=~(CCIS1+CCIS0);          // 捕获源为P4.3,即CCI0A(也是CCI0B)
  TBCCTL3|=CM_2+SCS;//+CAP;           //下降沿捕获,同步捕获,工作在捕获模式
  //TBCCTL3|=CCIE;                     //允许捕获比较模块提出中断请求
 
  TBCTL|=ID_3;
  TBCTL|=TBSSEL_2;                   //选择时钟MCLK
  TBCTL|=TBCLR;                      //定时器清零,
  TBCTL|=MC_2;                       //定时器开始计数(连续计数模式0~0xFFFF)
  _EINT();[/P][P]我原版TB1,TB2,TB3的CCIE 和CAP是没有屏蔽掉的,1,2,3的捕获功能不起作用,[/P][P]后面我把1,2,3屏蔽掉,检测完0路,关闭0路,然后开启1路,检测完1路,再关闭1路,开启2路,依次这样,只能一路一路的检测,这是什么原因,贴一段代码[/P][P]//―――――定时器TB的CCR0的中断:用于检测脉冲上升与下降沿――――
#pragma vector=TIMERB0_VECTOR        
__interrupt void TimerB0(void)
{
   if(TBCCTL0&CM_2)                        //捕获到下降沿
     {
      TBCTL|=TBCLR;
      TBCCTL0=(TBCCTL0&(~CM_2))|CM_1;    //改为上升沿捕获:CM1置零,CM0置一[/P][P]     }
   else if(TBCCTL0&CM_1)                    //捕获到上升沿
     {
      width[i++]=TBCCR0;                  //记录下结束时间
      TBCCTL0=(TBCCTL0&(~CM_1))|CM_2;   //改为下降沿捕获:CM0置零,CM1置一
      if(i==10)
        {
          i=0;
          sample_flag0=1;
          TBCCTL0&=~CCIE;          //[COLOR=#ff0000]关闭TB0  
[/COLOR]           TBCCTL1|=CCIE+CAP;       //[COLOR=#ff0000]开启TB1
[/COLOR]           TBCTL|=TBCLR;
        }
      }[/P][P] [/P][P]// Timer_B7 Interrupt Vector (TBIV) handler
#pragma vector=TIMERB1_VECTOR
__interrupt void Timer_B(void)
{
 switch( TBIV )
 {
   case  2:
         if(TBCCTL1&CM_2)
           {
             TBCTL|=TBCLR;
             TBCCTL1=(TBCCTL1&(~CM_2))|CM_1;    //改为上升沿捕获:CM1置零,CM0置一
           }
         else if(TBCCTL1&CM_1)                    //捕获到上升沿
           {
             width[i++]=TBCCR1;                  //记录下结束时间
             TBCCTL1=(TBCCTL1&(~CM_1))|CM_2;   //改为下降沿捕获:CM0置零,CM1置一
             if(i==10)
               {
                 i=0;
                 sample_flag0=1;
                 TBCCTL1&=~CCIE;             //[COLOR=#ff0000]关闭TB1
[/COLOR]                  TBCCTL2|=CCIE+CAP;          //[COLOR=#ff0000]开启TB2
[/COLOR]                  TBCTL|=TBCLR;
               }
           }
         break;                            // CCR1
   case  4:
         if(TBCCTL2&CM_2)
           {
             TBCTL|=TBCLR;
             TBCCTL2=(TBCCTL2&(~CM_2))|CM_1;    //改为上升沿捕获:CM1置零,CM0置一
           }
         else if(TBCCTL2&CM_1)                    //捕获到上升沿
           {
             width[i++]=TBCCR2;                  //记录下结束时间
             TBCCTL2=(TBCCTL2&(~CM_1))|CM_2;   //改为下降沿捕获:CM0置零,CM1置一
             if(i==10)
               {
                 i=0;
                 sample_flag0=1;
                 TBCCTL2&=~CCIE;
                 TBCCTL3|=CCIE+CAP;
                 TBCTL|=TBCLR;
               }
           }
          break;                          // CCR2
   case  6:
         if(TBCCTL3&CM_2)
           {
             TBCTL|=TBCLR;
             TBCCTL3=(TBCCTL3&(~CM_2))|CM_1;    //改为上升沿捕获:CM1置零,CM0置一
           }
         else if(TBCCTL3&CM_1)                    //捕获到上升沿
           {
             width[i++]=TBCCR3;                  //记录下结束时间
             TBCCTL3=(TBCCTL3&(~CM_1))|CM_2;   //改为下降沿捕获:CM0置零,CM1置一
             if(i==10)
               {
                 i=0;
                 sample_flag0=1;
                 TBCCTL3&=~CCIE;
               }
           }
          break;                          // CCR3
   case 14: P1OUT ^= 0x01;                  // overflow
          break;
  }
}[/P][P] [/P][P]}[/P]
5楼
DC版主,像你请教一个问题:上面这个捕获计算脉宽的程序,为啥不考虑定时器计数到0xffff后溢出的情形呢?也就是说定时器不是在一直计数吗,我外部一直没有被捕捉的脉冲过来,此时没有捕捉中断,但是我定时器还在计数啊,那此时定时器计数到0xffff时,怎么办?

电脑版 Page created in 0.0620 seconds width 2 queries.