您的位置:首页 > 其它

MSP430F1612 TimerA 定时功能配置

2017-02-22 17:24 134 查看
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 debug
void 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,达到了预期的效果。至于波形不太标准,是因为电压不够稳定吧。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息