MSP430F1612 TimerA 定时功能配置

来源:互联网 发布:生辰八字高分起名软件 编辑:程序博客网 时间:2024/06/05 00:53

MSP430的TimerA功能强大,可以用作定时器、PWM发生器和输入捕获器,这里我们介绍TimerA用作定时器时该怎么配置寄存器。

涉及寄存器


   

TACTL是TimerA的控制寄存器,我们需要使用TimerA的功能都必须对它进行配置。

       TASSELx位于寄存器的第9、8位,用于选择TimerA模块的时钟源。这里我选择ACLK(被配置为4096Hz),即TASSEL[1:0]= 01.

       IDx是对时钟源进行分频,这里我1分频(不分频),ID[1:0]=00.

       MCx是定时器模式选择,这里我选择增模式(up mode),MC[1:0]=01.

增模式时序图如下:

      

          计数器TAR中的值从0开始递增到与TACCR0值相等,然后复位,继续递增,如此循环往复。

       TACLR是计数器TAR的清除位,置1则TAR复位为0.

       TAIE位很鸡肋,是TimerA的溢出中断使能位,其实就是在TAR中的值等于TACCR0的值时,产生一个中断,置位溢出中断标志位TAIFG。使用CCIE完全是同样的效果。

 

        TAR 定时器TimerA的16位计数器,每经过一个TimerA的时钟周期,计数器自增1.我选的定时器时钟为4096Hz/1=4096Hz,也就是说1秒钟,TAR可以从0增加到4096.



TACCTLx是一系列的寄存器,这里定时器功能只需要使用TACCTL0中的一个位CCIE,使能输出比较/输入捕获模块0的中断,其他位默认就行。至于CCIFG位,我完全不知道怎么用,到了中断函数里边就清零了,也许可以关中断查询一下吧*_*

 

还有一个寄存器需要用,TACCR0。这个寄存器用作TimerA整个模块的周期寄存器,我们需要在这个16位寄存器中载入初值。这个初值就是TAR自增到与之相等时复位的值。譬如说,定时器的时钟是4096Hz,我在TACCR0中写了4096,这样配置的话,不出意外1S进行一次中断。

 

C程序代码

#include <msp430x16x.h> void Clock_init(void);//void Clock_output(void);  //just for debugvoid Led_init(void);void TimerA_init(void); int main( void ){ //Stop watchdog timer to prevent time out reset WDTCTL = WDTPW + WDTHOLD;  Clock_init(); //Clock_output();  //just for debug Led_init(); TimerA_init();  _EINT();          //enable the general interrupt LPM0;             //enter LPM0 mode while(1)  {     }} #pragma vector=TIMERA0_VECTOR__interrupt void TIMERA0_ISR(void){   if(P4OUT & BIT7)     P4OUT &= ~BIT7;   else     P4OUT |= BIT7;} void TimerA_init(void){ TACTL |= TASSEL0 + TACLR; //select ACLK , clear TAR TACCR0 = 4096;     TACTL |= MC0;     //increase counter mode CCTL0 |= CCIE;    //enable interrupt of TACCR0} void Led_init(void){ P4SEL &= ~BIT7;  //select IO function, P4.7 P4DIR |= BIT7;   //set P4.7 as output P4OUT &= ~BIT7;  //output low level} void Clock_init(void){ unsigned int i;  //set ACLK = 4096Hz ; start XT2 BCSCTL1 &= ~XT2OFF; //XT2OFF = 0; BCSCTL1 &= ~XTS;    //XTS = 0XT1 low frequence 32.768KHz BCSCTL1 |= DIVA1 + DIVA0; //DIVAx = 11, ACLK = fosc/8 = 32.768KHz/8 = 4096Hz  //set SMCLK = 1MHz BCSCTL2 |= SELS;        //set XT2 as the clock source of SMCLK BCSCTL2 |= DIVS1 + DIVS0;//DIVSx = 11, SMCLK = fosc/8 = 8MHz/8 =1MHz   //set MCLK = 1MHz BCSCTL2 |= SELM1;  //SELMx = 10,select XT2CLK as the clock source of MCLK BCSCTL2 &= ~SELM0; BCSCTL2 |= DIVM1 + DIVM0; //DIVMx = 11, MCLK = fosc/8 = 8MHz / 8 = 1MHz   do  {   IFG1 &= ~OFIFG;          //clear oscillator fault flag   for(i = 0xff; i > 0; i--); //delay some time ,wait for the oscillator works nomally }while ((IFG1 & OFIFG) != 0); //do-while when oscillator fault occurs } void Clock_output(void){ //set P2.0 to output ACLK P2DIR |= BIT0;   //set P2.0 as output P2SEL |= BIT0;   //set multiplex function , ACLK output  P1DIR |= BIT4;  P1SEL|= BIT4;  //set P5.4 to output MCLK P5DIR |= BIT4;   //set P5.4 as output P5SEL |= BIT4;   //select multiplex function MCLK output}


 

运行结果


      这是我用示波器测量P4.7引脚得到的波形,大致就是1s变换一次电平了,我也可以看到LED灯亮和灭的时间大致是1s,达到了预期的效果。至于波形不太标准,是因为电压不够稳定吧。

1 0
原创粉丝点击