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_ */