MSP430F1612 TimerA 定時功能配置

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,達到了預期的效果。至於波形不太標準,是因爲電壓不夠穩定吧。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章