(10)MSP430F5529 定时器Timer_A

6.4  捕获比较模块

这是在以上介绍的基础上正式讲TA的重要功能。

先看一个寄存器TACCTL0-TACCTL6:(TA中最复杂的寄存器,用到的时候查表啦) 

CMx:捕获模式设定    00 不捕获  01 上升沿捕获  10 下降沿捕获  11上升和下降沿都捕获

CCISx捕获源的选择           00 CCIxA  01 CCIxB  10 GND  11 VCC 

SCS:同步捕获源,设定是否与时钟同步   0 异步捕获  同步捕获 

SCCI:选择的CCI输入信号EQUx信号锁存,并可通过该位读取。

CAP 0-比较模式     1-捕获模式

OUTMOD输出模式控制位(之后会在输出模块详细解释)     

CCIE中断使能,该位允许相应的CCIFG标志中断请求 。 0-中断禁止      1 -中断允许 

CCI3 捕获比较输入,所选择的输入信号可以通过该位读取

OUT  对于输出模式0,该位直接控制输出状态 0-输出低电平    1-输出高电平

COV捕获溢出位。该位表示一个捕获溢出发出,COV必须由软件复位。 0-没有捕获溢出发生   1-有捕获溢出发生

CCIFG捕获比较中断标志位。 0-没有中断挂起    1-有中断挂起

最后一个寄存器TAIV:(还记得外部中断寄存器吗,里面同样存储的只是一个中断代号)里面没有TACCR0的中断标志,因为TACCR0优先级最高,有一个专门的中断向量)

这里面的标志位需要软件手动清零。一种情况例外:两个中断同时发生,先响应优先级高的中断,当该中断服务程序结束后,该位的中断标志会自动清零,然后去响应另外一个中断。

6.4.1比较模式

  TA启动时默认为比较模式。CAP=0时选择比较模式)

  比较模式简介:(也就是一般意义上的定时计时模式)

  这是定时器的默认模式,当在比较模式下的时候,与捕获模式相关的硬件停止工作,如果这个时候开启定时器中断,然后设置定时器终值(将终值写入TACCRx),开启定时器,当TAR的值增加到和某个TACCRx里面的值相等的的时候,相应的中断标志位CCIFGx置一,同时中断标志位TAIFG置位。若中断允许未开启则只将中断标志位CCIFGx置一。还记得51单片机的定时器吗)

  注意:当Timer_A要用到TACCR0的值作为终值来计数(也就是增模式或者增减模式),很显然TACCR0的值一定要大于其TACCRx的值,否则那些比TACCR0大的计数值就没有存在的意义了。

  所谓的比较就是,如果计数器TAR中的值和某个TACCRx中的值相等了,那么相应的标志位就会置位。

   这只是一个原理,实际应用的时候,会很灵活,通过一个一个设定每次的TACCR值,可以得到想要的各种时间间隔。

         总结:比较模式用于选择PWM输出信号或在特定的时间间隔中断。当TAR计数到TACCRx的值时: 

         ○相应的中断标志CCIFG置位;

  ○内部信号EQUx=1 

         EQUx根据输出模式来影响输出信号 

         ○输入信号CCI锁存到SCCI 

6.4.2  捕获模式

   CAP=1时,选择捕获模式。捕获模式用于记录时间事件,比如速度估计或时间测量。捕获输入CCIXACCLXB连接外部的引脚或内部的信号,这通过CCISX位来选择。CMX位选择捕获输入信号触发沿;上升沿、下降沿或两者都捕获。当输入信号的触发沿到来时,捕获事件发生: 

   定时器的TAR值复制到TACCRX寄存器中 

  ○中断标志位CCIFG置位 

注意:捕获信号可能会和定时器时钟不同步,并导致竞争条件的发生。将SCS位置位可以在下个定时器时钟使捕获同步

              如果第二次捕获发生时,第一次捕获的TAR值还没有及时被存到TACCRx,捕获比较寄存器就会产生一个溢出逻辑,COV位在此时置位, COV位必须软件清除。

6.5 输出模块

  传统的定时器,都是通过标志位的判断来定时触发事件的。而430则具有输出模块,通过和定时结合起来,可以方便的产生PWM信号或者其它控制信号

  每个捕获/比较器都有一个输出口,P1.1-P1.5对应TA0.0-TA0.45个捕获比较器的输出

  输出模式: 输出模式由OUTMODx位来确定,如下表对于所有模式来说(模式0除外),OUTx信号随着定时器时钟的上升沿而改变。输出模式2367对输出模式0无效,因为此模式下,EQUx=EQU0(复位指的是置0

OUTMODX

模式

说明

000

输出

输出信号OUTxOUT位定义。当OUT位更

新时,OUTx信号立刻更新 

001

置位

当定时器计数到TACCRX值时,输出置位,并保

持置位直到定时器复位或选择了另一个输出模式

010

翻转/复位

当定时器计数到TACCRX值时,输出翻转。当定

时器计数到TACCR0值时,输出复位 

011

置位/复位

当定时器计数到TACCRX值时,输出置位。当定

时器计数到TACCR0值时,输出复位 

100

翻转

当定时器计数到TACCRX值时,输出翻转。输出

信号的周期将是定时器的2

101

复位

当定时器计数到TACCRX值时,输出复位,并保

持复位直到选择了另一个输出模式 

110

翻转/置位

当定时器计数到TACCRX值时,输出翻转。当定

时器计数到TACCR0值时,输出置位

111

复位/置位

当定时器计数到TACCRX值时,输出复位。当定

时器计数到TACCR0值时,输出置位 

举一个例子:结合上表看下图 

              注意:在模式转换的时候,一定要保持OUTMOD至少一位置位,除非转向0模式。所以最好的做法是:先把OUTMOD置为7,然后再清除掉不需要的位。

              做一个说明:比较模式下,当计数器TAR中的值和TACCRX中的设计值相等时,相应捕获/比较器的EQUx就会置位。那么EQU0EQUxOUTMOD是怎么来影响输出的呢?以模式2(翻转/复位)为例,该模式的定义是这样的:当定时器计数到TACCRX值时,输出翻转。当定时器计数到TACCR0值时,输出复位。于是,这句话就也可以翻译成在模式2的条件下,当EQUX=1时,输出翻转;当EQU0等于1的时候,输出复位。这两个信号这里相当于两个触发(使能)信号了。 

总结

实验一:

/*利用Timer_A比较模式下的多路定时,让LED闪烁*/

#include <msp430f5529.h>

void main(void)

{

   WDTCTL=WDTPW+WDTHOLD;

   P1DIR|=(BIT1+BIT2+BIT3+BIT4+BIT5);  //P1.1-P1.5为输出方向

   P1OUT=0x00;                     //全部拉低,初始化LED全灭

   TA0CCTL1=CCIE;                  //捕获比较器1开启CCIFG位中断

   TA0CCR1=13107;                      //置入要比较的数值0xff/5=13107

   TA0CCTL2=CCIE;                 //捕获比较器2开启中断

   TA0CCR2=26214;                  //13107*2=26214

   TA0CCTL3=CCIE;                 //捕获比较器3开启中断

   TA0CCR3=39321;                     //13107*3=39321

   TA0CCTL4=CCIE;                  //捕获比较器4开启中断

   TA0CCR4=52428;                  //13107*4=52428

   TA0CTL|=TACLR+TAIE;              //开启中断并清零

   TA0CTL|=TASSEL_1+MC_2+TAIE;     //选择SCLK32.768KHZ作为时钟,选用连续模式,并开启中断

   /*这样的话,5个灯闪一遍的时间为0xffff/32768=2S*/

   __enable_interrupt();    //开启总中断

   while(1);

}

/*TIMER0_A0_VECTOR是计时器0的CCR0的中断寄存器,TIMER0_A1_VECTOR是计时器0的CCR1-CCR4、TA的寄存器*/

/*同理定时器TA1也是分为两个TIMER1_A0_VECTOR和TIMER1_A1_VECTOR*/

#pragma vector=TIMER0_A1_VECTOR

__interrupt void TimerA(void)

{

   switch(__even_in_range(TA0IV,14))

   /* 这句话的意思是:只有在TA0IV的值是在0--14内的偶数时才会执行switch函数内的语句

            其作用是提高switch语句的效率*/

   {

      case 2:P1OUT=BIT1;break; //TACCR1 CCIFG置位,表明计数值和设定的13107相等了,也就是说计了0.4S了

      case 4:P1OUT=BIT2;break; //TACCR2 CCIFG置位,表明计了0.8S了

      case 6:P1OUT=BIT3;break; //TACCR3 CCIFG置位,表明计了1.2S了

      case 8:P1OUT=BIT4;break; //TACCR4 CCIFG置位,表明计了1.6S了

      case 14:P1OUT=BIT5;break;   //TAIFG置位,表明计了2S了

      default:break;

   }

}

 

实验二:比较模式-增减模式输出PWM

/*在比较和增减模式下产生PWM波(矩形波) */

/*提一个PWM波的用处:驱动直流电机。我们知道对于直流电机,驱动它的电流的频率并不影响转速 ,只有占空比会影响转速*/

/*开发板上P2.0是有外接排针的,所以用这一端口输出PWM*/

/*看CPU引脚发现,P2.0为TA1.1,也就是定时器A1的1号捕获比较器输出口*/

#include <msp430.h>

void main(void)

{

   WDTCTL=WDTPW+WDTHOLD;

   P2SEL|=BIT0;             //声明有特殊功能,不做普通I/O使用

   P2DIR|=BIT0;             //输出

   P2DS |=BIT0;            //全力驱动,否则可能无法驱动电机

   P2OUT&=~BIT0;            //初始化输出低电平

   /*把SMCL配置为XT2 4MHZ*/

   P5SEL=BIT2+BIT3;           //声明特殊功能,将用作外部时钟晶振XT2输入

   UCSCTL6&=~XT2OFF;         //开启XT2

   while(SFRIFG1 & OFIFG)

   {

      UCSCTL7 &=~(XT2OFFG+DCOFFG+XT1LFOFFG);//清除3种时钟错误标志

      SFRIFG1&=~(OFIFG);       //清除时钟错误标志位

   }                    //直到XT2从起振到振荡正常,没有错误发生

   UCSCTL4|=SELS_5;           //把SMCLK的时钟源选为XT2 4MHZ

   TA1CCTL0=CCIE;              //定时器A1的捕获比较器0开启CCIFG位中断

   TA1CCR0=200;                //置入计数终值,则PWM频率为10KHZ

   TA1CCTL1=CCIE;               //捕获比较器1开启中断

   TA1CCR1=50;                 //占空比为75%

   TA1CTL|=TACLR;              //将计时器A1清零

   TA1CTL|=TASSEL_2+MC_3;         //定时器选择SMCLK作为时钟源,且为增减模式

   TA1CCTL1=OUTMOD_4;        //定时器A1中的捕获比较器1,输出模式为4翻转

   while(1);

}

 //呼吸灯//

//  介绍: 该程序利用TIMER A 的 UP模式 在P1.3脚产生PWM输出

//  将CCR0设置为1500来定义PWM的周期,利用循环不断改变CCR1的值,

//  实现利用改变PWM的占空比来改变LED亮度.

//  SMCLK = MCLK = TACLK = default DCO

#include <msp430f5529.h>

void delay_nms(unsigned int n)// 延时函数

  {

    unsigned int j;

    for (j=0;j<(n);j++)

    {

      __delay_cycles(400);   //太短会使LED显得好像在常亮,太长就要等较长时间来观察了

    }

  }

void main(void)

{

  unsigned const PWMPeriod = 1500; //设置PWM周期参数,const声明此值不允许改变.该数值太大,会导致LED闪烁

  volatile unsigned int i;        //声明变量i是随时可变的,系统不要去优化这个值

  WDTCTL = WDTPW + WDTHOLD;   // 关闭看门狗

  P1DIR |=BIT3;              // 设置 P1.3为输出

  P1SEL |=BIT3;              // 设置 P1.3为TA0.2输出

  TA0CCR0 = PWMPeriod;           // 设置PWM 周期

  TA0CCTL2 = OUTMOD_7;           // 设置PWM 输出模式为:7 - PWM复位/置位模式,

                              // 即输出电平在TAR的值等于CCR2时复位为0,当TAR的值等于CCR0时置位为1,改变CCR2,从而产生PWM。其实模式2也可以

  TA0CTL= TASSEL_2 +MC_1;    // 设置TIMERA的时钟源为SMCLK, 计数模式为up,到CCR0再自动从0开始计数

  while(1)

  {

   TA0CCR2=0;//确保最开始是暗的

    //渐亮过程:不断设置TA0CCR2的值,使翻转的时间变长,改变PWM的占空比

    for(i=0;i<PWMPeriod;i+=1)

    {

      TA0CCR2=i;

      delay_nms(4-(i/500));  //占空比变化的延时,调整延迟时间可改变呼吸灯变暗的速度

                             //在暗的时候延长delay时间,可增强效果

     }

    //渐暗过程:不断设置TA0CCR2的值,使翻转的时间变短,改变PWM的占空比

    for(i=PWMPeriod;i>0;i-=1)

    {

      TA0CCR2=i;

      delay_nms(4-(i/500));           //占空比变化的延时,调整延迟时间可改变呼吸灯变暗的速度

                                    //在暗的时候延长delay时间,可增强效果

    }

     TA0CCR2=0;  //确保灯暗

     delay_nms(250); //时间长一点,增强视觉效果

  }

}

 文章摘录于:http://blog.lehu.shu.edu.cn/879836630/A450185.html

posted @ 2015-03-22 10:04  水木_清风  阅读(6691)  评论(1编辑  收藏  举报