MSP430G2553包含了两个16-bit Timer_A计时/计数器。本文简单介绍了Timer_A的功能和寄存器使用,本文及后续的随笔部分参考了"Scientific Instrument Using the TI MSP430"博客。该博客的MSP430教程文章非常好,建议对MSP430感兴趣的人FQ阅读。
一、介绍
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 三种,如下图所示。调试中发现,修改MCx时会将TASSELx和IDx清零。
- 将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模式由TAxCCRx寄存器的CAP=0来使能。
- 当TAR寄存器计数到TAxCCRx寄存器的值时,可触发中断,由TAxCCTLx寄存器中的CCIE位使能,中断标志位为TAxCCTLx寄存器中的CCIFG位。
四、Capture Block
- capture模式可用时间测量、速度计算。
- 外部输入信号为CCIA或CCIB,对应管脚需查看具体芯片手册。
- capture模式由TAxCCRx寄存器的CAP=1及CMx字段来使能。
- 捕获条件由TAxCCRx寄存器的CMx字段设置,默认为00(关闭)。捕获条件可以为仅上升沿、仅下降沿、上升/下降沿三种之一。
- 建议设置TAxCCRx寄存器的SCS位,从而将捕获产生信号与时钟信号同步。
- 当上一次捕获产生信号被读取前又有了新的捕获产生信号、即capture overflow时,TAxCCRx寄存器的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 }