今晚看了把Timer_A的例程看完一遍了,趁热小结一下帖上来,有错误的地方请大家指正。
从例程看来,Timer_A有三个作用,一是做定时功能、二是PWM,输出可控波形、三是UART的辅助。
一、定时功能方面:
相比于51常用的delay函数,用Timer_A做定时的好处是低功耗,操作起来也简便,真正符合430的简单易用与低功耗俱全的优良特性。而且430的定时方式灵活,可以选择多个时钟源、多种计数方式和不同的中断方式。我们看下两个官方的例子:
例一、msp430g2xx3_ta_05:
#include
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
P1DIR |= 0x01; // P1.0 output
CCTL0 = CCIE; // CCR0 interrupt enabled
CCR0 = 1000-1;
TACTL = TASSEL_1 + MC_1; // ACLK, upmode
_BIS_SR(LPM3_bits + GIE); // Enter LPM3 w/ interrupt
}
// Timer A0 interrupt service routine
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A (void)
{
P1OUT ^= 0x01; // Toggle P1.0
}
例子一用的时钟源是ACLK,由于ACLK默认有LFXT1CLK提供,所以我们要把lunchpad附送的32768HZ的晶振焊上去。TAR的模式是增计数模式,当计数到CCR0的时候就触发中断,继而TAR又回到0重新计数,就这样周而复始。中断里面取反P1.0,控制LED的亮灭,闪烁频率是32768/(2*1000) = 16.384Hz 。
例子二、msp430g2xx3_ta_06:
#include
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
P1DIR |= 0x01; // P1.0 output
CCTL1 = CCIE; // CCR1 interrupt enabled
CCR1 = 50000;
TACTL = TASSEL_2 + MC_2; // SMCLK, Contmode
_BIS_SR(LPM0_bits + GIE); // Enter LPM0 w/ interrupt
}
// Timer_A3 Interrupt Vector (TA0IV) handler
#pragma vector=TIMER0_A1_VECTOR
__interrupt void Timer_A(void)
{
switch( TA0IV )
{
case 2: // CCR1
{
P1OUT ^= 0x01; // Toggle P1.0
CCR1 += 50000; // Add Offset to CCR1
}
break;
case 4: break; // CCR2 not used
case 10: break; // overflow not used
}
}
从TACTL寄存器看出,例子二的时钟是SMCLK,来自于DCO(默认1MHZ)。TAR的模式是连续计数模式,当TAR==CCR1的时候就触发,亮灭LED。在中断函数中每次都把CCR1加50000,所以50000个时钟周期后LED再次亮或者灭。功能跟例子一差不多,可是频率不同,大概是(1000k)/(50k*2)=10HZ 。
我们看到例子一用了CCR0、例子二用了CCR1,功能差不多,CCTLx和TACTL的设置也相似。但是中断函数却不同(关于寄存器的配置用户手册讲的很清楚)。原因是CCR0和CCR1有两个不同的中断入口。CCR0的单源中断,优先级高于CCR1;CCR1的中断向量的多源中断,被CCR1、CCR2、定时器溢出共用,在中断函数中需要判定是哪个中断源触发了该中断。TA0IV为2时是CCR1、为4时为CCR2、为10时为定时器溢出 触发的。
二、PWM输出
以上的例子以一定的频率控制LED的亮灭,但是理论上讲他们的亮度的一样的,要控制LED的亮度,要用到PWM(当然PWM不仅仅用于控制LED亮度)。
PWM的输出也可以自由选择LFXT1、DCO、VLO作为时钟源。输出方式也有置位复位、复位置位等四种,不过都大同小异。
#include
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
P1DIR |= 0x0C; // P1.2 and P1.3 output
P1SEL |= 0x0C; // P1.2 and P1.3 TA1/2 options
CCR0 = 512-1; // PWM Period //=CCR0
CCTL1 = OUTMOD_7; // CCR1 reset/set
CCR1 = 384; // CCR1 PWM duty cycle
TACTL = TASSEL_2 + MC_1; // SMCLK, up mode
_BIS_SR(CPUOFF); // Enter LPM0
}
我们看到这个例程简单明了,CPU只执行了几条语句,就一直处于关闭状态,PWM的输出由Timer_A自动完成。输出方式用了模式7复位置位方式,TAR增计数,时钟是SMCLK,来自于DCO。另外P1.2没有接LED,我们可以改动程序把PWM输出到P1.6。
三是UART的波特率产生等,还没看。
以上纯粹个人理解,有不妥之处请高人指教,我是新手,还在入门的水平,高手可以直接无视这段文字哈。