#include "PWM.h"
#define EN_EXT_OSC 0
#define COMPLEMENT_MODE 0x00000020
#define DEAD_ZONE_INTERVAL 0xC8FF0000
#define PWM_ENABLE 0x01010101
#if EN_EXT_OSC
#define PWM_CLOCK_SOURCE 0x00000000 //使用外部振蕩12MHz
#else
#define PWM_CLOCK_SOURCE 0xF0000000 //使用內(nèi)部RC振蕩22.1184MHz
#endif
#define DEAD_ZONE_INTERVAL 0xC8FF0000
#define PWM_ENABLE 0x01010101
#if EN_EXT_OSC
#define PWM_CLOCK_SOURCE 0x00000000 //使用外部振蕩12MHz
#else
#define PWM_CLOCK_SOURCE 0xF0000000 //使用內(nèi)部RC振蕩22.1184MHz
#endif
#define PWM_PRESCALAE 0x0000C731 //PWM01預(yù)分頻0x31(49),PWM23預(yù)分頻0xC7(199)
#define PWM_CLOCK_DIVIDER 0x00004444 //輸入時(shí)鐘分頻1
#define PWM_OUTPUT_INVERT 0x00040000
#define PWM_OUTPUT_ENABLE 0x0000000F //PWM0、1、2、3輸出使能
#define PWM_CLOCK_DIVIDER 0x00004444 //輸入時(shí)鐘分頻1
#define PWM_OUTPUT_INVERT 0x00040000
#define PWM_OUTPUT_ENABLE 0x0000000F //PWM0、1、2、3輸出使能
#define PWM_CMR_VALUE 0x0
#define PWM_CNR_VALUE 0x1000 //4096
/*
PWM頻率=PWMxy_CLK/(prescale+1)*(clock divider)/(CNR+1)
(1)使用外部晶振12MHz
PWM頻率=12000000/(49+1)*4097 =58.57Hz
(2)使用內(nèi)部RC振蕩22.1184MHz
PWM頻率=22118400/(49+1)*4097 =107.97Hz
*/
#define LED_DARKING 0
#define LED_BRIGHTING 1
#define PWM_CNR_VALUE 0x1000 //4096
/*
PWM頻率=PWMxy_CLK/(prescale+1)*(clock divider)/(CNR+1)
(1)使用外部晶振12MHz
PWM頻率=12000000/(49+1)*4097 =58.57Hz
(2)使用內(nèi)部RC振蕩22.1184MHz
PWM頻率=22118400/(49+1)*4097 =107.97Hz
*/
#define LED_DARKING 0
#define LED_BRIGHTING 1
STATIC UINT32 g_unPWMCMRValue=PWM_CNR_VALUE;
STATIC UINT32 g_unLedStat=LED_DARKING;
/****************************************
*函數(shù)名稱:PWMInit
*輸 入:無(wú)
*輸 出:無(wú)
*功 能:PWM初始化
******************************************/
VOID PWMInit(VOID)
{
P2_MFP |= ~(P20_AD8_PWM0 | P21_AD9_PWM1 | P22_AD10_PWM2 | P23_AD11_PWM3);
P2_MFP |= (PWM0 | PWM1 | PWM2 | PWM3); //使能P2.0~P2.3為PWM輸出
P2_PMD &= ~Px0_PMD; //配置P2.0~P2.3為推挽輸出
P2_PMD |= Px0_OUT;
P2_PMD &= ~Px1_PMD;
P2_PMD |= Px1_OUT;
P2_PMD &= ~Px2_PMD;
P2_PMD |= Px2_OUT;
P2_PMD &= ~Px3_PMD;
P2_PMD |= Px3_OUT;
APBCLK |= PWM01_CLKEN | PWM23_CLKEN; //使能PWM0~3時(shí)鐘
CLKSEL1 = PWM_CLOCK_SOURCE; //選擇PWM0~3時(shí)鐘源
PPRA = PWM_PRESCALAE | DEAD_ZONE_INTERVAL; //選擇PWM0~3時(shí)鐘預(yù)分頻和死區(qū)間隔
CSRA = PWM_CLOCK_DIVIDER; //選擇PWM0~3時(shí)鐘分頻
PCRA = 0x08080808 | PWM_OUTPUT_INVERT | COMPLEMENT_MODE; //PWM0~3自動(dòng)重裝載
STATIC UINT32 g_unLedStat=LED_DARKING;
/****************************************
*函數(shù)名稱:PWMInit
*輸 入:無(wú)
*輸 出:無(wú)
*功 能:PWM初始化
******************************************/
VOID PWMInit(VOID)
{
P2_MFP |= ~(P20_AD8_PWM0 | P21_AD9_PWM1 | P22_AD10_PWM2 | P23_AD11_PWM3);
P2_MFP |= (PWM0 | PWM1 | PWM2 | PWM3); //使能P2.0~P2.3為PWM輸出
P2_PMD &= ~Px0_PMD; //配置P2.0~P2.3為推挽輸出
P2_PMD |= Px0_OUT;
P2_PMD &= ~Px1_PMD;
P2_PMD |= Px1_OUT;
P2_PMD &= ~Px2_PMD;
P2_PMD |= Px2_OUT;
P2_PMD &= ~Px3_PMD;
P2_PMD |= Px3_OUT;
APBCLK |= PWM01_CLKEN | PWM23_CLKEN; //使能PWM0~3時(shí)鐘
CLKSEL1 = PWM_CLOCK_SOURCE; //選擇PWM0~3時(shí)鐘源
PPRA = PWM_PRESCALAE | DEAD_ZONE_INTERVAL; //選擇PWM0~3時(shí)鐘預(yù)分頻和死區(qū)間隔
CSRA = PWM_CLOCK_DIVIDER; //選擇PWM0~3時(shí)鐘分頻
PCRA = 0x08080808 | PWM_OUTPUT_INVERT | COMPLEMENT_MODE; //PWM0~3自動(dòng)重裝載
CNR0A = CNR1A = CNR2A = CNR3A = PWM_CNR_VALUE; //PWM0~3計(jì)數(shù)值
CMR0A = CMR1A = CMR2A = CMR3A = PWM_CMR_VALUE; //PWM0~3比較值
CMR0A = CMR1A = CMR2A = CMR3A = PWM_CMR_VALUE; //PWM0~3比較值
PIERA |= PWMIE3 | PWMIE2 | PWMIE1 | PWMIE0 ; //使能PWM0~3中斷
NVIC_ISER |= PWMA_INT; //使能PWM0~3中斷
NVIC_ISER |= PWMA_INT; //使能PWM0~3中斷
POEA = PWM_OUTPUT_ENABLE; //PWM輸出使能
PCRA |= PWM_ENABLE; //PWM使能,啟動(dòng)
}
/****************************************
*函數(shù)名稱:PWMA_IRQHandler
*輸 入:無(wú)
*輸 出:無(wú)
*功 能:中斷服務(wù)函數(shù)-PWMA
******************************************/
VOID PWMA_IRQHandler(VOID)
{
switch(g_unLedStat) //檢查L(zhǎng)ED狀態(tài)
{
case LED_DARKING: //LED狀態(tài)漸暗
{
if(g_unPWMCMRValue < PWM_CNR_VALUE)
{
g_unPWMCMRValue+=50;
}
else
{
g_unLedStat = LED_BRIGHTING;
g_unPWMCMRValue=PWM_CNR_VALUE;
}
}break;
PCRA |= PWM_ENABLE; //PWM使能,啟動(dòng)
}
/****************************************
*函數(shù)名稱:PWMA_IRQHandler
*輸 入:無(wú)
*輸 出:無(wú)
*功 能:中斷服務(wù)函數(shù)-PWMA
******************************************/
VOID PWMA_IRQHandler(VOID)
{
switch(g_unLedStat) //檢查L(zhǎng)ED狀態(tài)
{
case LED_DARKING: //LED狀態(tài)漸暗
{
if(g_unPWMCMRValue < PWM_CNR_VALUE)
{
g_unPWMCMRValue+=50;
}
else
{
g_unLedStat = LED_BRIGHTING;
g_unPWMCMRValue=PWM_CNR_VALUE;
}
}break;
case LED_BRIGHTING: //LED狀態(tài)漸亮
{
if(g_unPWMCMRValue>=50)
{
g_unPWMCMRValue-=50;
}
else
{
g_unLedStat = LED_DARKING;
g_unPWMCMRValue=PWM_CMR_VALUE;
}
}break;
default:break;
}
CMR0A = CMR1A = CMR2A = CMR3A = g_unPWMCMRValue; //設(shè)置PWM0~3比較值
PIIRA = PIIRA;
}
/****************************************
*函數(shù)名稱:main
*輸 入:無(wú)
*輸 出:無(wú)
*功 能:函數(shù)主體
******************************************/
INT32 main(VOID)
{
PROTECT_REG //ISP下載時(shí)保護(hù)FLASH存儲(chǔ)器
(
PWRCON |= XTL12M_EN; //默認(rèn)時(shí)鐘源為外部晶振
while((CLKSTATUS & XTL12M_STB) == 0); //等待12MHz時(shí)鐘穩(wěn)定
CLKSEL0 = (CLKSEL0 & (~HCLK)) | HCLK_12M; //設(shè)置外部晶振為系統(tǒng)時(shí)鐘
PWMInit(); //PWM初始化
)
while(1);
}
{
if(g_unPWMCMRValue>=50)
{
g_unPWMCMRValue-=50;
}
else
{
g_unLedStat = LED_DARKING;
g_unPWMCMRValue=PWM_CMR_VALUE;
}
}break;
default:break;
}
CMR0A = CMR1A = CMR2A = CMR3A = g_unPWMCMRValue; //設(shè)置PWM0~3比較值
PIIRA = PIIRA;
}
/****************************************
*函數(shù)名稱:main
*輸 入:無(wú)
*輸 出:無(wú)
*功 能:函數(shù)主體
******************************************/
INT32 main(VOID)
{
PROTECT_REG //ISP下載時(shí)保護(hù)FLASH存儲(chǔ)器
(
PWRCON |= XTL12M_EN; //默認(rèn)時(shí)鐘源為外部晶振
while((CLKSTATUS & XTL12M_STB) == 0); //等待12MHz時(shí)鐘穩(wěn)定
CLKSEL0 = (CLKSEL0 & (~HCLK)) | HCLK_12M; //設(shè)置外部晶振為系統(tǒng)時(shí)鐘
PWMInit(); //PWM初始化
)
while(1);
}