1、就msp430x2xx系列单片机而言,常有Timer_A、Timer_B、Watch Dog Timer中一个或多个,本文先讲述Timer_A定时器,其它的定时器原理类同。
2、Timer_A定时器简介Timer_A定时器是16位定时/计数器,具有多路捕捉与比较功能。其中,定时器时钟可以选择TACLK、ACLK、SMCLK、INCLK。ACLK是辅助时钟,SMCLK是子系统时钟,可由TASSELx选择时钟源。
3、观察上图,需要知道的是(1)通过IDx可以对输入时钟源加以分频,/1/2/4/8分频;(2)TAR是定时器的16位计数器,对分频后时钟加以计数,边沿计数;(3)TAR计数值可以与诸如CCR1/CCR2值比较,如果使能相应比较中断,则计数值计数到CCRx值时会产生相应中断信号。(4)如果需要使用输入捕获/比较功能,则需要设置捕获/比较模块,暂不介绍。输出示例如下所示:
4、设置定时器步骤:(1)如果需要PWM信号输出,则需要配置引脚功能;(2)设置定时器基础计数器CCR0值,也就是设置PWM周期;(3)设置定时器CCR1/CCR2,设置PWM的占空比;(4)设置定时器中断,以及比较输出模式;(5)选择定时器时钟源,推荐使用SMCLK或ACLK,设置定时器工作模式,开启系统中断GIE;(6)编写中断服务程序。如下所示,在配置Timer_A时常需要配置如下寄存器:
5、需要注意的是,对于同一个定时器,但是有2个中断向量地址。一个事CCR0定时器溢出中断;另一个是CCR1/CCR2或TAR计数溢出中断,如下所示代码:/*********************忮氽阝另*********************************************** Timer A0 interrupt service routine*/#pragma vector=TIMER0_A0_VECTOR __interrupt void Timer_A0 (void) { //CCR0 interrupt service}而CCR1/CCR2以及TAR计数溢出中断则是下面中断服务程序:/******************************************************************** Timer_A2 Interrupt Vector (TA0IV) handler*/#pragma vector=TIMER0_A1_VECTOR __interrupt void Timer_A1(void) { switch( TA0IV ) { case 2: //CCR1 += 1000; // Add Offset to CCR1 //P1OUT ^= 0x01; break; case 10: //P1OUT ^= 0x01; // Timer_A3 overflow break; } }其中TA0IV是中断向量寄存器,用于区别定时器中断源,如果TA0IV=2,则是CCR1中断;如果TA0IV=10,则是定时器TAR计数溢出中断。
6、小编编写代码:/*** timer_A initialize and configurate* 酆璁冻嘌freq: 1000 -> 1000 Hz* duty: 50.2 -> 50.2%*/void TIM_timerAInit(unsigned int freq,float duty){ P1SEL |= BIT6; // P1.6 option select P1DIR |= BIT6; // P1.6 outputs //CCR0 = 512-1; // PWM Period TIM_timerAPwmFreqSet(freq); //CCR1 = 109; // CCR1 PWM duty cycle TIM_timerAPwmDutySet(freq,duty); CCTL0 = CCIE; // CCTL1 = OUTMOD_7 + CCIE; // CCR1 reset/set, interrupt enabled TACTL = TASSEL_2 + MC_0 + TACLR; // SMCLK, stop mode}/****/void TIM_timerAPwmFreqSet(unsigned int freq){ CCR0 = 16000000/freq - 1; //pwm pulse period}/****/void TIM_timerAPwmDutySet(unsigned int freq,float duty){ CCR1 = (unsigned int)(duty*160000/freq); //high percent}以上只是示例代码,其中Timer_A选择时钟是SMCLK时钟,SMCLK=16MHz。而开启或关闭定时器,可以通过下面函数控制:/****/void TIM_timerACtl(unsigned char ctl){ if(ctl == TIM_TIMER_A_RUN) { TACTL |= MC_1; //Run,timer_A run } else if(ctl == TIM_TIMER_A_STOP) { TACTL &= ~(BIT5+BIT4); //Stop, timer halted }}一开始的时候MC_0时,定时器是关闭状态并不会工作的,不清楚的话请查看MSP430x2xx系列单片机说明书。