TACCTL2=CM1+CCIS_1+CAP; //捕获模式,捕获上升沿,捕获内部ACLK
TACTL=TASSEL_2+MC_2+TACLR; //定时器时钟源为SMCLK,启动连续计数,清TAR
TACCTL2 &=~CCIFG; //清CCR2的标志位
while(!(CCIFG&TACCTL2)); //查CCR2标志位
first_value=TACCR2; //第一个捕获值存入first_value
TACCTL2 &=~CCIFG; //清CCR2的标志位
while(!(CCIFG&TACCTL2)); //查CCR2标志位
second_value=TACCR2; //第二个捕获值存入second_value
TACCTL2 &=~CCIFG; //清CCR2的标志位
TACCTL2 &=~MC1; //关定时器A
cap_value=(second_value-first_value);
return 0;
}
通过比较模式,输出得到PWM波形( 脉宽调制,PWM是一种对模拟信号电平进行数字编码的方法,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。)TimerA可以得到两路,分别以CCR0位计数周期。设置CCR1,CCR2的值(小于CCR0)形成一定的占空比。输出时候将IO口设置为外部模块输出。
附程序:
int main( void )
{
WDTCTL=WDTPW+WDTHOLD; //关看门狗
BCSCTL1 =CALBC1_1MHZ; //设定DCO为1MHZ
DCOCTL = CALDCO_1MHZ;
TACTL=TASSEL1+TAR; //SMCLK为时钟源,清TAR
CCR0=512; //设定PWM周期
CCTL1 |=OUTMOD_7; //CCR1输出为reset/set模式
CCR1=384; //CCR1的PWM占空比设定
CCTL2 |=OUTMOD_7; //CCR2输出为reset/set模式
CCR2=128; //CCR2的PWM占空比设定
P1SEL |=BIT2+BIT3; //TA1,TA2输出功能
P1DIR |=BIT2+BIT3;
TACTL |=MC0; //启动定时器A增计数模式
_BIS_SR(CPUOFF);
return 0;
}
中断:
Two interrupt vectors are associated with the 16-bit Timer_A module:
TACCR0 interrupt vector for TACCR0 CCIFG
TAIV interrupt vector for all other CCIFG flags and TAIFG
In capture mode any CCIFG flag is set when a timer value is captured in the
associated TACCRx register. In compare mode, any CCIFG flag is set if TAR
counts to the associated TACCRx value. Software may also set or clear any
CCIFG flag. All CCIFG flags request an interrupt when their corresponding
CCIE bit and the GIE bit are set.
The TACCR1 CCIFG, TACCR2 CCIFG, and TAIFG flags are prioritized and
combined to source a single interrupt vector. The interrupt vector register TAIV
is used to determine which flag requested an interrupt.
For example:
//******************************************************************************
// MSP430F22x4 Demo - Timer_A, Toggle P1.0-3, Cont. Mode ISR, 32kHz ACLK
//
// Description: Use Timer_A CCRx units and overflow to generate four
// independent timing intervals. For demonstration, TACCR0, TACCR1 and TACCR2
// output units are optionally selected with port pins P1.1, P1.2 and P1.3
// in toggle mode. As such, these pins will toggle when respective TACCRx
// registers match the TAR counter. Interrupts are also enabled with all
// TACCRx units, software loads offset to next interval only - as long as the
// interval offset is added to TACCRx, toggle rate is generated in hardware.
// Timer_A overflow ISR is used to toggle P1.0 with software. Proper use
// of the TAIV interrupt vector generator is demonstrated.
// ACLK = TACLK = 32kHz, MCLK = SMCLK = default DCO ~1.2MHz
// //* An external watch crystal on XIN XOUT is required for ACLK *//
//
// As coded and with TACLK = 32768Hz, toggle rates are:
// P1.1 = TACCR0 = 32768/(2*4) = 4096Hz
// P1.2 = TACCR1 = 32768/(2*16) = 1024Hz
// P1.3 = TACCR2 = 32768/(2*100) = 163.84Hz
// P1.0 = overflow = 32768/(2*65536) = 0.25Hz
//
// MSP430F22x4
// -----------------
// /|\| XIN|-
// | | | 32kHz
// --|RST XOUT|-
// | |
// | P1.1/TA0|--> TACCR0
// | P1.2/TA1|--> TACCR1
// | P1.3/TA2|--> TACCR2
// | P1.0|--> Overflow/software
//
// A. Dannenberg
// Texas Instruments Inc.
// April 2006
// Built with IAR Embedded Workbench Version: 3.41A
//******************************************************************************
#include "msp430x22x4.h"
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
P1SEL |= 0x0E; // P1.1 - P1.3 option select
P1DIR |= 0x0F; // P1.0 - P1.3 outputs
TACCTL0 = OUTMOD_4 + CCIE; // TACCR0 toggle, interrupt enabled
TACCTL1 = OUTMOD_4 + CCIE; // TACCR1 toggle, interrupt enabled
TACCTL2 = OUTMOD_4 + CCIE; // TACCR2 toggle, interrupt enabled
TACTL = TASSEL_1 + MC_2 + TAIE; // ACLK, contmode, interrupt enabled
__bis_SR_register(LPM3_bits + GIE); // Enter LPM3 w/interrupt
}
// Timer A0 interrupt service routine
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A0(void)
{
TACCR0 += 4; // Add Offset to TACCR0
}
// Timer_A3 Interrupt Vector (TAIV) handler
#pragma vector=TIMERA1_VECTOR
__interrupt void Timer_A1(void)
{
switch (__even_in_range(TAIV, 10)) // Efficient switch-implementation
{
case 2: TACCR1 += 16; // Add Offset to TACCR1
break;
case 4: TACCR2 += 100; // Add Offset to TACCR2
break;
case 10: P1OUT ^= 0x01; // Timer_A3 overflow
break;
}
}