歡迎使用CSDN-markdown編輯器

MSP430之 PWM源文件及頭文件

源文件:(注意:TA1配置還未驗證,可先屏蔽)

/*
* Copyright (c)
* All rights reserved.
*
* 文件名稱:TA_PWM.c
* 文件標識:NO
* 硬件描述:NO
* 功能描述:PWM庫函數,可利用Timer_A生成三種PWM。
*
* 當前版本:V1.0
* 作者:Clover
* 完成日期:2015.2.
*
* 取代版本:NO
* 原作者:Administrator
* 完成日期:2013-4-8
*/

#include "msp430g2553.h"
#define DEADTIME 20                         //預設死區時間,以TA的CLK爲單位
/*******TA輸出IO設定********/
#define TA01_SET    P1SEL |= BIT6; P1DIR |= BIT6        //P1.6  P1SEL:Port 1 Selection
#define TA02_SET    P3SEL |= BIT0; P3DIR |= BIT0        //P3.0
#define TA11_SET    P2SEL |= BIT2; P2DIR |= BIT2        //P2.2
#define TA12_SET    P2SEL |= BIT4; P2DIR |= BIT4        //P2.4

#define TA01_OFF    P1SEL &= ~BIT6                         //P1.6
#define TA02_OFF    P3SEL &= ~BIT0                         //P3.0
#define TA11_OFF    P2SEL &= ~BIT2                         //P2.2
#define TA12_OFF    P2SEL &= ~BIT4                     //P2.4
/******************************************************************************************************
* 名       稱:TA0_PWM_Init()
* 功       能:TA0定時器作爲PWM發生器的初始化設置函數
* 入口參數:CLK:時鐘源 'S'=SMCLK;   'A'=ACLK ;   'E'=TACLK(外部輸入); 'e'= TACLK(TACLK取反)
           Div:時鐘分頻係數: 1/2/4/8
           Mode1:通道1的輸出模式 'F'設爲超前PWM(模式7),'B'滯後PWM(模式3) ,'D'帶死區增PWM(模式6),0=禁用
           Mode2:通道2的輸出模式 'F'設爲超前PWM(模式7),'B'滯後PWM (模式3),'D'帶死區減PWM(模式2),0=禁用
            設置輸出帶死區控制的PWM時,兩通道均需使用,且均爲死區模式。
* 出口參數:1表示設置成功,0表示參數錯誤,設置失敗。
* 說 明 : 在調用PWM相關函數之前,需要調用該函數設置Time_A的模式和時鐘源。
* 範 例 : TA0_PWM_Init('A',1,'F','F')TA時鐘設爲ACLK,通道1和通道2均爲超前PWM輸出
        TA0_PWM_Init('S',4,'D','D')TA時鐘設爲SMCLK/4, 通道1爲死區增PWM、通道2爲死區減PWM
        TA0_PWM_Init('A',1,'F',0)TA時鐘設爲ACLK,通道1超前PWM輸出,通道2不作TA用。
 ******************************************************************************************************/
char TA0_PWM_Init(char Clk,char Div,char Mode1,char Mode2)
{
    TA0CTL =0;                                          // 清除以前設置

    switch(Mode1)                                       //爲定時器選擇計數模式
    {
        case 'F': case 'f':                             //普通PWM
        TA0CTL |=MC_1; break;                           //主定時器爲增計數
        case 'B':case 'b':
        TA0CTL |=MC_1; break;                           //主定時器爲增計數
        case 'D': case 'd':                             //死區PWM
        TA0CTL |=MC_3; break;                           //主定時器爲增減計數
        default : return(0);                            //其他情況都是設置參數有誤,返回0
    }

    switch(Clk)                                         //爲定時器TA選擇時鐘源
    {
        case 'A': case 'a':     TA0CTL|=TASSEL_1; break; //ACLK
        case 'S': case 's':     TA0CTL|=TASSEL_2; break; //SMCLK
        case 'E':               TA0CTL|=TASSEL_0; break; //外部輸入(TACLK)
        case 'e':               TA0CTL|=TASSEL_3; break; //外部輸入(TACLK取反)
        default :  return(0);                            //設置參數有誤,返回0
    }
    switch(Div)                                         //爲定時器TA選擇分頻係數
    {
        case 1:   TA0CTL|=ID_0; break;   //1
        case 2:   TA0CTL|=ID_1; break;   //2
        case 4:   TA0CTL|=ID_2; break;   //4
        case 8:   TA0CTL|=ID_3; break;   //8
        default :  return(0);                           //設置參數有誤,返回0
    }
    switch(Mode1)                                       //設置PWM通道1的輸出模式。
    {
        case 'F':   case 'f':
        TA0CCTL1 = OUTMOD_7;
        TA01_SET;
        break;
        case 'B':   case 'b':
        TA0CCTL1 = OUTMOD_3;
        TA01_SET;
        break;
        case 'D': case'd':
        TA0CCTL1 = OUTMOD_6;
        TA01_SET;
        break;
        case '0':case 0:                                    //如果設置爲禁用
        TA01_OFF;                                           //TA0.1恢復爲普通IO口
        break;
        default :  return(0);                               //設置參數有誤,返回0
    }
    switch(Mode2)                                           //設置PWM通道2的輸出模式。
    {
        case 'F':    case 'f':
        TA0CCTL2 = OUTMOD_7;
        TA02_SET;  break;
        case 'B':   case 'b':
        TA0CCTL2 = OUTMOD_3;
        TA02_SET;
        break;
        case 'D': case 'd':
        TA0CCTL2 = OUTMOD_2;
        TA02_SET;
        break;
        case '0':case 0:                                        //如果設置爲禁用
        TA02_OFF;                                               //TA0.1恢復爲普通IO口
        break;
        default :  return(0);                                   //設置參數有誤,返回0
    }
    return(1);
}

/******************************************************************************************************
* 名       稱:TA0_PWM_SetPeriod()
* 功       能:設置PWM發生器的週期
* 入口參數:Channel: TA0=0, TA1=1
*           Period:週期(0~65535) 時鐘個數
* 出口參數:1:設置成功     0:設置失敗
* 說       明 : 普通PWM與帶死區PWM週期相差一倍
* 範       例 : TA0_PWM_SetPeriod(500)設置PWM方波週期爲500或1000個時鐘週期
 ******************************************************************************************************/
char TA0_PWM_SetPeriod(unsigned int Period)
{
    if (Period>65535)   return(0);
    TA0CCR0 = Period;
    return(1);
}

/******************************************************************************************************
* 名    稱:TA0_PWM_SetPermill()
* 功    能:設置PWM輸出的佔空比(千分比)
* 入口參數:Channel: 當前設置的通道號  1/2
            Duty: PWM高電平有效時間的千分比 (0~1000),
* 出口參數:1設置成功,0設置失敗
* 說    明: 1000=100.0%  500=50.0% ,依次類推。死區模式時,兩channel同時設定。
* 範    例: TA0_PWM_SetPermill(1,300)設置PWM通道1方波的佔空比爲30.0%
         TA0_PWM_SetPermill(2,,825)設置PWM通道2方波的佔空比爲82.5%
 ******************************************************************************************************/
char TA0_PWM_SetPermill(char Channel,unsigned int Duty)
{
    unsigned char Mod = 0;
    unsigned int DeadPermill=0;
    unsigned long int Percent=0;                    //防止乘法運算時溢出
    Percent=Duty;
    DeadPermill=((DEADTIME*1000)/TACCR0);           //將絕對死區時間換算成千分比死區時間
    switch (Channel)                                //先判斷出通道的工作模式
    {
        case 1:
        Mod = (TA0CCTL1& 0x00e0)>>5;        break;  //讀取輸出模式,OUTMOD0位於5-7位
        case 2:
        Mod = (TA0CCTL2 & 0x00e0)>>5;       break;  //讀取輸出模式,OUTMOD1位於5-7位
        default:    return(0);
    }

    switch(Mod)                                     //根據模式設定TACCRx
    {
        case 2: case 6:         /**死區模式2,6時,需要判斷修正死區時間,且同時設定TA0CCR1/2 的值*/
        {
            if((1000-2*Percent)<=DeadPermill)       //預留死區時間
                Percent=(1000-DeadPermill)/2;
            TA0CCR1=Percent*TA0CCR0/1000;
            TA0CCR2= TA0CCR0-TA0CCR1;
            break;
        }
        case 7:
        {
            if(Percent>1000)    Percent=1000;
            if(Channel==1) TA0CCR1=Percent* TA0CCR0/1000;
            if(Channel==2) TA0CCR2=Percent* TA0CCR0/1000;
            break;
        }
        case 3:     //佔空比一律爲正脈寬,所以需要 TA0CCR0減去佔空比
        {
            if(Percent>1000)    Percent=1000;
            if(Channel==1) TA0CCR1= TA0CCR0-Percent*TA0CCR0/1000;
            if(Channel==2) TA0CCR2= TA0CCR0-Percent*TA0CCR0/1000;
            break;
        }
        default: return(0);
    }
    return (1);
}

/*************TA1*******************/

/******************************************************************************************************
* 名       稱:TA1_PWM_Init()
* 功       能:TA1定時器作爲PWM發生器的初始化設置函數
* 入口參數:Clk:時鐘源 'S'=SMCLK;   'A'=ACLK ;   'E'=TACLK(外部輸入); 'e'= TACLK(TACLK取反)
           Div:時鐘分頻係數: 1/2/4/8
           Mode1:通道1的輸出模式 'F'設爲超前PWM(模式7),'B'滯後PWM (模式3),'D'帶死區增PWM(模式6),0=禁用
           Mode2:通道2的輸出模式 'F'設爲超前PWM(模式7),'B'滯後PWM (模式3),'D'帶死區減PWM(模式2),0=禁用
            設置輸出帶死區控制的PWM時,兩通道均需使用,且均爲死區模式。
* 出口參數:1表示設置成功,0表示參數錯誤,設置失敗。
* 說       明 : 在調用PWM相關函數之前,需要調用該函數設置TA的模式和時鐘源。
* 範       例 : TA1_PWM_Init('A',1,'F','F')TA時鐘設爲ACLK,通道1和通道2均爲超前PWM輸出
          TA1_PWM_Init('S',4,'D','D')TA時鐘設爲SMCLK/4, 通道1爲死區增PWM、通道2爲死區減PWM
          TA1_PWM_Init('A',1,'F',0)  TA時鐘設爲ACLK,通道1超前PWM輸出,通道2不作TA用。
 ******************************************************************************************************/
char TA1_PWM_Init(char Clk,char Div,char Mode1,char Mode2)
{
  TA1CTL =0;                                                                // 清除以前設置

  switch(Mode1)                                                         //爲定時器選擇計數模式
  {
      case 'F': case 'f':                                                       //普通PWM
          TA1CTL |=MC_1; break;                                     //主定時器爲增計數
      case 'B':case 'b':
          TA1CTL |=MC_1; break;                                     //主定時器爲增計數
      case 'D': case 'd':                                                       //死區PWM
          TA1CTL |=MC_3; break;                                     //主定時器爲增減計數
      default : return(0);                                                  //其他情況都是設置參數有誤,返回0
  }

  switch(Clk)                                                               //爲定時器TA選擇時鐘源
  {
    case 'A': case 'a':     TA1CTL|=TASSEL_1; break;            //ACLK
    case 'S': case 's':     TA1CTL|=TASSEL_2; break;            //SMCLK
    case 'E':                   TA1CTL|=TASSEL_0; break;            //外部輸入(TACLK)
    case 'e':                   TA1CTL|=TASSEL_3; break;            //外部輸入(TACLK取反)
    default :  return(0);                                                       //設置參數有誤,返回0
  }
  switch(Div)                                                                       //爲定時器TA選擇分頻係數
  {
    case 1:   TA1CTL|=ID_0; break;   //1
    case 2:   TA1CTL|=ID_1; break;   //2
    case 4:   TA1CTL|=ID_2; break;   //4
    case 8:   TA1CTL|=ID_3; break;   //8
    default :  return(0);                                                       //設置參數有誤,返回0
  }
  switch(Mode1)                                                                 //設置PWM通道1的輸出模式。
  {
     case 'F':  case 'f':
              TA1CCTL1 =OUTMOD_7;
              TA11_SET;
              break;
     case 'B':  case 'b':
              TA1CCTL1 =OUTMOD_3;
              TA11_SET;
              break;
     case 'D': case'd':
         TA1CCTL1 =OUTMOD_6;
             TA11_SET;
             break;
      case '0':case 0:                                  //如果設置爲禁用
             TA11_OFF;                                  //TA0.1恢復爲普通IO口
              break;
     default :  return(0);                              //設置參數有誤,返回0
  }
  switch(Mode2)                                         //設置PWM通道2的輸出模式。
  {
      case 'F':  case 'f':
              TA1CCTL2 =OUTMOD_7;
              TA12_SET;
      case 'B': case 'b':
              TA1CCTL2 =OUTMOD_3;
              TA12_SET;
                break;
      case 'D': case 'd':
               TA1CCTL2 =OUTMOD_2;
               TA12_SET;
               break;
      case '0':case 0:                                  //如果設置爲禁用
                TA12_OFF;                               //TA0.1恢復爲普通IO口
                break;
      default :  return(0);                             //設置參數有誤,返回0
   }
  return(1);
}
/******************************************************************************************************
* 名       稱:TA1_PWM_SetPeriod()
* 功       能:設置PWM發生器的週期
* 入口參數:Channel: TA0=0, TA1=1
*                     Period:週期(0~65535) 時鐘個數
* 出口參數:1:設置成功     0:設置失敗
* 說       明 : 普通PWM與帶死區PWM週期相差一倍
* 範       例 : TA1_PWM_SetPeriod(500)設置PWM方波週期爲500或1000個時鐘週期
 ******************************************************************************************************/
char TA1_PWM_SetPeriod(unsigned int Period)
{
    if (Period>65535)   return(0);
     TA1CCR0 = Period;
    return(1);
}

/******************************************************************************************************
* 名    稱:TA1_PWM_SetPermill()
* 功    能:設置PWM輸出的佔空比(千分比)
* 入口參數:Channel: 當前設置的通道號  1/2
             Duty: PWM高電平有效時間的千分比 (0~1000),
* 出口參數:1設置成功,0設置失敗
* 說    明: 1000=100.0%  500=50.0% ,依次類推。死區模式時,兩channel同時設定。
* 範    例: TA1_PWM_SetPermill(1,300)設置PWM通道1方波的佔空比爲30.0%
            TA1_PWM_SetPermill(2,,825)設置PWM通道2方波的佔空比爲82.5%
 ******************************************************************************************************/
char TA1_PWM_SetPermill(char Channel,unsigned int Duty)
{
    unsigned char Mod;
    unsigned long int Percent=0;                                //防止乘法運算時溢出
    Percent=Duty;
    switch (Channel)                                                    //先判斷出通道的工作模式
    {
        case 1:
            Mod = (TA1CCTL1 & 0x00e0)>>5;       break;  //讀取輸出模式,OUTMOD0位於5-7位
        case 2:
            Mod = (TA1CCTL2 & 0x00e0)>>5;       break;  //讀取輸出模式,OUTMOD1位於5-7位
        default:    return(0);
    }

    switch(Mod)         //根據模式設定TACCRx
    {
        case 2: case 6:         /**死區模式2,6時,需要判斷修正死區時間,且同時設定TA1CCR1/2 的值*/
        {
            if((1000-2*Percent)<=DEADTIME)  //預留死區時間
                Percent=(1000-DEADTIME)/2;
            TA1CCR1=Percent* TA1CCR0/1000;
            TA1CCR2= TA1CCR0-TA1CCR1;
            break;
        }
        case 7:
        {
            if(Percent>1000)    Percent=1000;
            if(Channel==1) TA1CCR1=Percent* TA1CCR0/1000;
            if(Channel==2) TA1CCR2=Percent* TA1CCR0/1000;
            break;
        }
        case 3:     //佔空比一律爲正脈寬,所以需要 TA1CCR0減去佔空比
        {
            if(Percent>1000)    Percent=1000;
            if(Channel==1) TA1CCR1= TA1CCR0-Percent* TA1CCR0/1000;
            if(Channel==2) TA1CCR2= TA1CCR0-Percent* TA1CCR0/1000;
            break;
        }
        default: return(0);
    }
    return (1);
}

頭文件:

/*
* Copyright (c)
* All rights reserved.
*
* 文件名稱:TA_PWM.h
* 文件標識:NO
* 硬件描述:NO
* 功能描述:PWM庫函數的頭文件,可利用Timer_A生成三種PWM。
*
* 當前版本:V1.0
* 作者:Clover
* 完成日期:2015.2.
*
* 取代版本:NO
* 原作者:Administrator
* 完成日期:2013-4-8
*/

#ifndef TA_PWM_H_
#define TA_PWM_H_

extern char TA0_PWM_Init();  //extern 可置於變量或者函數前,以表示變量或者函數的定義在別的文件中,
                 //提示編譯器遇到此變量和函數時在其他模塊中尋找其定義
extern char TA0_PWM_SetPeriod();
extern char TA0_PWM_SetPermill();


extern char TA1_PWM_Init();

extern char TA1_PWM_SetPeriod();
extern char TA1_PWM_SetPermill();

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