MSP430F1612 TimerA PWM輸出

       這裏使用TimerA的PWM功能,配置TACCTL1輸出3路佔空比相同的PWM方波。TimerA模塊由計數器TAR,3個輸入捕獲/輸出比較器(Capature/compare Model)組成。其中CCM0的寄存器CCR0,是定時器的週期寄存器,所以CCM0很特殊,不適合做PWM輸出和輸入捕獲。這裏使用CCM1來輸出三路波形相同的PWM方波。

涉及寄存器



TACCTL1用來配置輸出PWM方波,只需要關掉輸入捕獲,然後選擇PWM輸出模式即可。CM[1:0]=00(默認), OUTMOD[2:0]=111;

然後配置寄存器TACCR1,裝載在TACCR1中的值發揮的作用由OUTMOD的選擇決定。

PWM輸出模式介紹如下:

      

       OUTMODE[2:0]三位是決定了TAR計數器計數到與TACCR0和TACCR1時,輸出電平的翻轉變化。當OUTMOD[2:0]=111時,TAR計數到TACCR1是輸出電平置0,直到TAR計數到TACCR0時置1,然後循環往復,輸出佔空比爲 (TACCR0 - TACCR1)/TACCR0*100%的PWM方波。

       要想輸出PWM波,當然是需要配置定時器的,只是不使能中斷,以定時器時鐘爲基準輸出PWM波。

C程序代碼 

#include <msp430x16x.h>
 
void Clock_init(void);
//void Clock_output(void);  //just for debug
void TimerA_init(void);
void Gpio_init(void);
 
int main( void )
{
 //Stop watchdog timer to prevent time out reset
 WDTCTL = WDTPW + WDTHOLD;
 
 Clock_init();
 //Clock_output();  //just for debug
 TimerA_init();
 Gpio_init();
 
 _EINT();          //enable the general interrupt
 LPM0;             //enter LPM0 mode
 while(1)
  {
   
  }
}
 
void TimerA_init(void)
{
 TACTL |= TASSEL0 + TACLR;  //select ACLK , clear TAR
 TACCR0 = 1024;             //ft =ACLK/4096
 TACTL |= MC0;             //increase counter model
 
 //set the compare mode, generate the PWM
 TACCTL1 |= OUTMOD2 + OUTMOD1 + OUTMOD0;  //OUTMOD7 reset/set, no capture
 TACCR1 = 512;
}
 
void Gpio_init(void)
{
 P1SEL |= BIT2;  //set P1.2 multiplex function, TA1 output, PWM channel 1
 P1DIR |= BIT2;  //set P1.2 asoutput
 
 P1SEL |= BIT6;  //set P1.6 multiplex function, TA1 output, PWM channel 2
 P1DIR |= BIT6;
 
  P2SEL |= BIT3; //set P2.3 multiplex function, TA1 output, PWM channel 3
 P2DIR |= BIT3;
}
 
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 XT2as 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
}


運行結果


我配置的ACLK=4096Hz,TimerA時鐘源選擇ACLK,1分頻,TimerA時鐘爲4096Hz。TACCR0=1024,那麼PWM週期就是1/4s=250ms. TACCR1=512,那麼佔空比就是(1024-512)/1024 = 50%.與測試結果相符。

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