4997|0

1140

帖子

0

TA的资源

纯净的硅(初级)

楼主
 

MSP430G2553单片机定时器Timer_A [复制链接]

1,MSP430g2553具有两个16位的定时器:Timer0_A   Timer1_A。分别具有三个捕捉/比较寄存器,具有输入捕捉,输出比较功能。可以产生定时中断,也可以产生PWM。
   2,产生PWM,例子如下:

#include

void Timer_A0_1_init()  //TA0.1输出PWM
{
TACTL|= TASSEL_1+MC_1;//ACLK,增计数
CCTL1=OUTMOD_7;//输出模式为复位/置位
CCR0=328;//时钟频率为32768HZ,100HZ
//CCR1=164;//时钟频率为32768HZ,占空比CCR1/CCR0=50%
CCR1=109;//占空比CCR1/CCR0=1/3                              TA0.1由P1.2 P1.6输出
}

void Timer_A1_2_init()    //TA1.2输出PWM
{
TA1CTL|= TASSEL_1+MC_1;//ACLK,增计数
TA1CCTL2=OUTMOD_7;//输出模式为复位/置位,注意CCTL2要写为TA1CCTL2

TA1CCR0=164;//时钟频率为32768HZ,波形32768/CCR0=199HZ
TA1CCR2=41;//占空比CCR2/CCR0=1/4,注意CCR2要写成TA1CCR2       TA1.2由P2.4 P2.5输出

}

void Timer_A1_1_init()   //TA1.1输出PWM
{
TA1CCTL1=OUTMOD_7;
TA1CCR1=123;   //占空比CCR1/CCR0=3/4,注意CCR1要写成TA1CCR1   TA1.1由P2.1 P2.2输出
}
void IO_init()
{
P1SEL|=BIT2+BIT6;
P1DIR|=BIT2+BIT6;//P1.2 P1.6输出   TA0.1   OUT1

P2SEL|=BIT4+BIT5;
P2DIR|=BIT4+BIT5;//P2.4 P2.5输出   TA1.2   OUT2

P2SEL|=BIT1+BIT2;
P2DIR|=BIT1+BIT2; //P2.1 P2.2输出  TA1.1   OUT1
}

void main(void) {
WDTCTL=WDTPW+WDTHOLD;

    IO_init();

Timer_A0_1_init();
Timer_A1_2_init();
Timer_A1_1_init();


_BIS_SR(CPUOFF);                          // Enter LPM0  进入低功耗模式0 SMCLK ON,ACLK ON
}

  3,Timer_A的捕获/比较寄存器
TAR寄存器是Timer_A的16位的计数寄存器。TACCRx是Timer_A的捕获/比较寄存器,当为捕获模式时:当捕获发生时,把TAR的值装载到TACCRx中。当为比较模式时:TACCRx中装的是要与TAR寄存器相比较的值。
   4,捕获模式
捕获外部输入的信号的上升沿或下降沿或上升沿下降沿都捕捉,当捕捉发生时,把TAR的值装载到TACCRx中,同时也可以进入中断,执行相应的操作。这样利用捕捉上升沿或下降沿就可以计算外部输入信号的周期,得出频率。利用捕捉上升沿和下降沿可以得出输入信号的高电平或低电平的持续时间。也可以算出占空比。下面是一个例子,是Timer_A捕获初始化的程序:
void timer_init()      //使用Timer1_A时要特别注意各个寄存器的写法,因为Timer0_A的寄存器都简写了,所以在写
//Timer1_A的寄存器时,要特别注意与Timer0_A的不同
{
P1SEL |= BIT2;    //选择P12作为捕捉的输入端子  Timer0_A
//TACCTL1 |=CM_3+SCS+CAP+CCIE;  //上下沿都触发捕捉,用于测脉宽,同步模式、时能中断  CCI1A
TACCTL1 |=CM_1+SCS+CAP+CCIE;  //上升沿触发捕捉,同步模式、时能中断  CCI1A
    TACTL |= TASSEL1+MC_2;  //选择SMCLK时钟作为计数时钟源,不分频   增计数模式不行,必须连续计数模式

  P2SEL |= BIT1;    //选择P21作为捕捉的输入端子    Timer1_A
  //TA1CCTL1 |=CM_3+SCS+CAP+CCIE;  //上下沿都触发捕捉,用于测脉宽,同步模式、时能中断  CCI1A
  TA1CCTL1 |=CM_1+SCS+CAP+CCIE;  //上升沿触发捕捉,同步模式、时能中断  CCI1A
  TA1CTL |= TASSEL1+MC_2;  //选择SMCLK时钟作为计数时钟源,不分频   增计数模式不行,必须连续计数模式

}


相对应的中断函数如下:

#pragma vector=TIMER0_A1_VECTOR   //Timer0_A CC1  的中断向量
__interrupt void Timer_A(void)
{

// CCI0A 使用的捕捉比较寄存器是TA0CCR0,TA0CCR0单独分配给一个
    //中断向量TIMER1_A0_VECTOR,所以进入中断后直接就是Timer0_A CC0产生的中断,不用经过类似
   //下面的方法判断中断源了  。
//Timer0_A CC1-4, TA0公用一个中断向量 TIMER0_A1_VECTOR,所以进入了中断后还要用下面
    //的方法进行判断是哪一个中断源产生的中断
  switch(TAIV)    //如果是Timer0_A CC1产生的中断
  {
  case 2:
   {
   flag=1;
   LPM1_EXIT;      //退出低功耗模式
  // _BIC_SR_IRQ(LPM1_bits);
   //_bic_SR_register_on_exit(LPM1_bits);
   break;
   }
  case 4: break;
  case 10:break;
  }
}


#pragma vector=TIMER1_A1_VECTOR      //Timer1_A CC1  的中断向量
__interrupt void Timer_A1(void)
{

// P1OUT|=BIT0;  //led调试用的
// LPM1_EXIT;      //退出低功耗模式  因为使用的是CCI0A 使用的捕捉比较寄存器是TA1CCR0,TA1CCR0单独分配给一个
                //中断向量TIMER1_A0_VECTOR,所以进入中断后直接就是Timer1_A CC0产生的中断,不用经过类似
               //下面注释掉的方法判断  。
               //而Timer1_A CC1-4, TA1则公用一个中断向量 TIMER1_A1_VECTOR,所以进入了中断后还要用下面
       //的方法进行判断是哪一个中断源产生的中断
  switch(TA1IV)    //如果是Timer1_A CC1产生的中断
  {
  case 2:
   {
   flag=2;
   LPM1_EXIT;      //退出低功耗模式

  // _BIC_SR_IRQ(LPM1_bits);
   //_bic_SR_register_on_exit(LPM1_bits);
   break;
   }
  case 4:break;
  case 10:break;
  }
}

//如果要测量更低频率的信号的话,可以在中断中判断溢出中断发生的次数,这样就可以得到溢出的次数,从而可以测量更
//低频率的信号

  5,Timer_A的计数模式
计数模式有:增计数模式,连续计数模式和增减计数模式。具体的各个模式的详解,参见用户指南。
   6,定时器的定时中断
在使用定时器的定时中断时,要注意定时器计数模式的选择。在使用中断时,要注意中断向量的使用和中断源的判断,下面就举一个例子,注释的也较详细:
#include

unsigned int t=0;

void main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
  P1DIR |= 0x01;                            // P1.0 output

  CCTL0 = CCIE;   // CCTLx是捕获/比较控制寄存器   interrupt enabled  CCIE=0x0010  时能定时器A中断

  CCR0 = 50000;   //捕获/比较寄存器   设置计数器CCR0的初值  16位寄存器,最大值为65535
                //默认SMCLK使用的是DCO,默认的DCO大约为800KHz,而CCR0=50000,所以中断产生的频率大约为16Hz
  TACTL = TASSEL_2 + MC_2;                  // SMCLK, contmode  连续计数模式从0计到0FFFFh
  //TACTL = TASSEL_2 + MC_1;                  // SMCLK, upmode  增计数模式从0计到CCR0

  _BIS_SR(LPM0_bits + GIE);                 // Enter LPM0 w/ interrupt  进入低功耗模式0,允许中断
}

// Timer A0 interrupt service routine
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A (void)    //CCIFG中断被响应后,该标志位自动清零

{
  //P1OUT ^= 0x01;                            // Toggle P1.0
t++;
if(t==5)
{
P1OUT ^= BIT0;           // Toggle P1.0
t=0;
}

  CCR0 += 50000;                            // Add Offset to CCR0  增加CCR0偏移


  //定时器总是从0开始往上计数,一直到计满再从0开始,在连续计数模式下,当定时器的值等于CCR0时,产生中断
  //在中断中对CCR0增加50000,这样的话定时器从当前值到下一时刻再次等于CCR0时的间隔为50000,恒定
  //这样产生中断的时间间隔就相等了
//所以在连续计数模式下,要想使中断的时间间隔一定,就要有CCR0 += n;这句话
                                              //在中断中CCR0不需要从新赋值,区别于51
}

中断的使用注意情况:还是把举个例子吧:
#include

void main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
  P1DIR |= 0x01;                            // P1.0 output
  TACTL = TASSEL_2 + MC_2 + TAIE;           // SMCLK, contmode, interrupt  TAIE允许定时器溢出中断

  _BIS_SR(LPM0_bits + GIE);                 // Enter LPM0 w/ interrupt  GIE允许中断
}

// Timer_A3 Interrupt Vector (TA0IV) handler
#pragma vector=TIMER0_A1_VECTOR
__interrupt void Timer_A(void)
{
switch( TA0IV )    //TAIV中断向量寄存器  用于
{
   case  2: break;                          // CCR1 not used   捕获/比较器1
   case  4: break;                          // CCR2 not used    捕获/比较器2
   case 10: P1OUT ^= 0x01;                  // overflow  定时器溢出
            break;
}
}



  7,注意:定时器Timer0_A的时钟可以选择为外接时钟输入TACLK(P10),这样当外接一个信号时,定时器Timer0_A就相当于一个计数器使用。这样就可以用Timer0_A接外接信号,Timer1_A接标准的时钟如32768Hz的晶振,就可以实现等精度测频了。其实Timer1_A的时钟也可以外接的,但是在g2553中没有这个外接管脚(P37),所以就只能选择正常的时钟了。
Timer0_A的外接时钟输入TACLK(P10)的设置如下:下面是我实现等精度测频时,两个定时器的初始化程序:
void timer0_init()
{
TACTL |= TASSEL_0+MC_2+TACLR;  //选择TACLK时钟作为计数时钟源,不分频   必须连续计数模式

P1SEL |= BIT0;   //P10为Timer0_A的时钟TACLK输入,接外部待测信号,这样Timer0_A就当作计数器用
}
//Timer1_A采用ACLK作为时钟源计数,这样ACLK就相当于是标准信号,这样两个定时器相当于都工作在计数器方式,
//ACLK 32768Hz作为标准信号,这样可以实现等精度测频
void timer1_init()
{

TA1CCTL0 = CCIE;
TA1CCR0 = 32768;    //1s定时

TA1CTL |= TASSEL_1+MC_2+TACLR;  //选择ACLK时钟作为计数时钟源,不分频   必须连续计数模式

}
8,用定时器和比较器可以实现DAC
   使用定时器也可以实现串口通信

 
点赞 关注

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表