MSP430F5529LP共有四个定时器,分别是Timer_A定时器3个和Timer_B定时器1个其中捕获和比较寄存器的个数有Timer0_A(5个),Timer1_A(3个),Timer2_A(3个)、Timer0_B(7个)。
我们用定时器A来做例子,简述其简单应用。
定时作用
先初始化灯和定时器配置
void LED_Init(void)
{
P1DIR|=BIT0;
P4DIR|=BIT7;
P1OUT|=BIT0;
P4OUT|=BIT7;
}
void TimerA0_Init(void)
{
TA0CTL=TASSEL_2 + TACLR + MC_1; //选择SCMLK时钟和向上计数模式
TA0CCTL0 = CCIE;
TA0CCR0 = 20000-1; //设定计数值20000,1MHZ时耗时20MS
TA0CTL &= ~TAIFG;
_bis_SR_register(GIE); //开启中断
}
再编写中断服务函数,计数达到反转灯的亮灭。
#pragma vector = TIMER0_A0_VECTOR
__interrupt void Timer_A(void)
{
P1OUT^=BIT0;
P4OUT^=BIT7;
}
产生PWM方波
初始化定时器配置,设置引脚p1.2和p1.3为输出模式及复用,再设置控制器为输出模式7,其中TAA0CCR0可以设置波的周期。公式为:频率=时钟频率/TA0CCR0,其后的TA0CCRX可以用于调节占空比:占空比=TA0CCRX/TA0CCR0。下面代码即在两个引脚产生一个百分之75和百分之25占空比的pwm波形频率都为64HZ
P1DIR |= BIT2 | BIT3;
P1SEL |= BIT2 | BIT3; //设置为定时器复用
TA0CCR0 = 512; //PWM周期,频率=32768/512=64HZ
TA0CCTL1 = OUTMOD_7; //CCR1输出模式7
TA0CCR1 = 384; //CCR1 PWM占空比设置为384/512=75%
TA0CCTL2 = OUTMOD_7; //CCR2输出模式7
TA0CCR2 =128; //CCR2 PWM占空比设置为128/512=25%
//开启定时器
TA0CTL = TASSEL_1 + MC_1 + TACLR; //定时器时钟设置为32768Hz的ACLK,配置为增模式,清空TA0R
捕获作用
我们可以用上面产生的pwm波来进行捕获测量其周期。我们用Timer1_A定时器来进行捕获。
捕获输入引脚我们查阅手册得为p2.0引脚,将其设置为上升沿捕获模式。
首先,我们先定义一些变量。
unsigned int cap_new = 0; // 首次捕捉的ta1r值
unsigned int cap_old = 0; // 二次捕捉的ta1r值
unsigned int cap_data =0;
在此,我们将SMCLK时钟调成了4MHZ可以去其他文章看看如何调时钟频率。
P2OUT&=~BIT0;
P2DIR&=~BIT0;
P2SEL|=BIT0;
*-捕获值存储在TA1CCR1中。
* TASSEL:SNCLK; 分频:4MHz/8 = 500k;计数模式:0 ==> 0xFFFF;
* TA1CCTL1:上升沿捕获 ;同步捕捉;捕获模式;CCI1A输入;
TA1CTL = TASSEL__SMCLK + ID__8 + MC_2 + TACLR + TAIE;
TA1CCTL1 = CM_1 + SCS +CAP + CCIE + CCIS_0;
定时器配置完成后,编写中断服务函数,(别忘了开启总中断!)
#pragma vector=TIMER1_A1_VECTOR
__interrupt void TIMER0_A1_ISR(void)
{
switch(__even_in_range(TA1IV,14))
{
case 0:break; // No interrupt
case 2:
state = TA1CCTL1 >> 14;
TA1CCTL1 &= ~CCIFG;
if( TA1CCTL1 & CM_1){
cap_new = TA1CCR1;
TA1CCTL1 &= ~CM_1;
TA1CCTL1 |= CM_2;
}else if ( TA1CCTL1 & CM_2){
cap_old = TA1CCR1;
cap_data = ( cap_old - cap_new );
TA1CCTL1 &= ~CM_2;
TA1CCTL1 |= CM_1;
}
break; // CCR1 not used
case 4: break; // CCR2 not used
case 6: break; // reserved
case 8: break; // reserved
case 10: break; // reserved
case 12: break; // reserved
case 14:
TA1CTL &= ~TAIFG;
break; // overflow
default: break;
}
}
介于本人水平有限, 本文有所错误之处,请直接提出。