一、介绍
Timer_A可实现的功能有
- multiple compare:判断计时器时间是否到达设定条件,触发事件
- multiple capture:捕获某个事件发生的时间
- PWM output:脉冲调制信号输出
- interval timing
Timer_A的构造框图如下所示。
二、Timer Block
- 包含了一个16-bit的timer/counter寄存器TAR。
- 时钟源可以由TAxCTL寄存器的TASSELx位段选择,为SMCLK、ACLK、TACLK、INCLK四者中的一个。其中TACLK、INCLK为外部输入的信号,对应管脚需查看具体芯片手册。
- 分频比由TAxCTL寄存器的IDx位段选择,支持1/2/4/8分频。
- Timer的开关及运行模式由TAxCTL寄存器的MCx位段选择,默认为00(Timer关闭)。运行模式支持up mode, continuous mode, up/down mode 三种,如下图所示。
- 将TAxCTL寄存器的TACLR位置0,可实现将TAR清零,同时TAxCTL寄存器的IDx、MCx位段也会被清零。
- Timer overflow时可产生中断,由TACTL寄存器的TAIE使能,中断标志位为TACTL寄存器的TAIFG位。
三、Compare Block
- 每个Timer_A包含两个(TAxCCR0、TAxCCR1)或三个(TAxCCR0、TAxCCR1、TAxCCR2)capture/compare register。如MSP430G2553的每个Timer_A包含三个capture/compare register。
- compare模式可以产生PWM信号,和特定时间间隔的中断。
- compare模式由TAxCCTLx寄存器的CAP=0来使能。
- 当TAR寄存器计数到TAxCCTLx寄存器的值时,可触发中断,由TAxCCTLx寄存器中的CCIE位使能,中断标志位为TAxCCTLx寄存器中的CCIFG位。
四、Capture Block
- capture模式可用时间测量、速度计算。
- 外部输入信号为CCIA或CCIB,对应GPIO管脚或其他外设输出,需查看具体芯片手册。
- capture模式由TAxCCTLx寄存器的CAP=1及CMx位段来使能。
- 捕获条件由TAxCCTLx寄存器的CMx位段设置,默认为00(关闭)。捕获条件可以为仅上升沿、仅下降沿、上升/下降沿三种之一。
- 建议设置TAxCCTLx寄存器的SCS位,从而将捕获产生信号与时钟信号同步。
- 当上一次捕获产生信号被读取前又有了新的捕获产生信号、即capture overflow时,TAxCCTLx寄存器的COV标志位会置1。
- 捕获事件发生时,产生的中断标志位与compare模式相同,为TAxCCTLx寄存器中的CCIFG位。亦由TAxCCTLx寄存器中的CCIE位使能。
五、一个简单例子
利用MSP430G2553 Timer0_A的compare mode,产生频率为0.1Hz的方波,驱动LED进行显示。代码在中断程序中又进行了一次计数,以实现长时间间隔定时。
复制代码
1 #include "io430.h"
2
3 #define LED1 BIT0 //red led on G2 Launchpad
4
5 //global variables
6 char i = 0;
7
8 void main(void)
9 {
10 // Stop watchdog timer to prevent time out reset
11 WDTCTL = WDTPW + WDTHOLD;
12
13 P1OUT = 0;
14 P1DIR |= LED1;
15
16 // set DCO freq = 1MHz
17 BCSCTL1 = CALBC1_1MHZ;
18 DCOCTL = CALDCO_1MHZ;
19
20 // BCM+ initial state:
21 // DCOCLK -> MCLK
22 // DCOCLK -> SMCLK
23 // comprare/capture mode -> compare mode
24
25 TA0CCR0 = 62550 - 1;
26 TA0CCTL0 = CCIE; // enable compare interrupt
27 TA0CTL = TASSEL_2 + ID_3 + MC_1 + TACLR;
28 // input clock: SMCLK/8 -> 125kHz;
29 // timer overflow freq: 125k/(TA0CCR0+1) -> 2Hz
30 // clear and start the timer, up mode
31
32 __enable_interrupt();
33
34 while(1)
35 {
36
37 }
38
39 }
40
41 //interrupt service routines
42 #pragma vector = TIMER0_A0_VECTOR
43 __interrupt void CCR0_ISR(void)
44 {
45 if(++i == 10) // interval: 1/2 * 10 = 5s, freq: 0.2Hz
46 {
47 // no flag clearing necessary; CCR0 has only one source,
48 // so it's automatic.
49 P1OUT ^= LED1; // the sqaure wave freq: 0.2Hz/2 -> 0.1Hz
50 i = 0;
51 }
52 }