#include "bsp_pwm.h"
#include "bsp_led.h"
//Timer0 配置
static void App_Timer0Cfg(uint16_t u16Period, en_bt_cr_timclkdiv_t pclk_div, uint16_t u16CHxACompare, uint16_t DeadTime)
{
uint16_t u16CntValue;
uint8_t u8ValidPeriod;
stc_bt_mode23_cfg_t stcBtBaseCfg;
stc_bt_m23_compare_cfg_t stcBtPortCmpCfg;
stc_bt_m23_adc_trig_cfg_t stcBtTrigAdc;
stc_bt_m23_dt_cfg_t stcBtDeadTimeCfg;
stc_bt_m23_bk_input_cfg_t stcBtBrakeCfg;
DDL_ZERO_STRUCT(stcBtBaseCfg);
DDL_ZERO_STRUCT(stcBtPortCmpCfg);
DDL_ZERO_STRUCT(stcBtTrigAdc);
DDL_ZERO_STRUCT(stcBtDeadTimeCfg);
Sysctrl_SetPeripheralGate(SysctrlPeripheralBaseTim, TRUE); //Base Timer外设时钟使能
stcBtBaseCfg.enWorkMode = BtWorkMode3; //三角波模式
stcBtBaseCfg.enCT = BtTimer; //定时器功能,计数时钟为内部PCLK
stcBtBaseCfg.enPRS = pclk_div;//BtPCLKDiv16; //PCLK/x 分频
//stcBtBaseCfg.enCntDir = BtCntUp; //向上计数,在三角波模式时只读
stcBtBaseCfg.enPWMTypeSel = BtComplementaryPWM; //互补输出PWM
stcBtBaseCfg.enPWM2sSel = BtSinglePointCmp; //单点比较功能
stcBtBaseCfg.bOneShot = FALSE; //循环计数
stcBtBaseCfg.bURSSel = FALSE; //上下溢更新
Bt_Mode23_Init(TIM0, &stcBtBaseCfg); //TIM0 的模式23功能初始化
Bt_M23_ARRSet(TIM0, u16Period, TRUE); //设置重载值,并使能缓存
Bt_M23_CCR_Set(TIM0, BtCCR0A, u16CHxACompare); //设置比较值A,(PWM互补模式下只需要设置比较值A)
stcBtPortCmpCfg.enCH0ACmpCtrl = BtPWMMode2; //OCREFA输出控制OCMA:PWM模式2
stcBtPortCmpCfg.enCH0APolarity = BtPortPositive; //正常输出
stcBtPortCmpCfg.bCh0ACmpBufEn = TRUE; //A通道缓存控制
stcBtPortCmpCfg.enCh0ACmpIntSel = BtCmpIntNone; //A通道比较控制:无
stcBtPortCmpCfg.enCH0BCmpCtrl = BtPWMMode2; //OCREFB输出控制OCMB:PWM模式2(PWM互补模式下也要设置,避免强制输出)
stcBtPortCmpCfg.enCH0BPolarity = BtPortPositive; //正常输出
//stcBtPortCmpCfg.bCH0BCmpBufEn = TRUE; //B通道缓存控制使能
stcBtPortCmpCfg.enCH0BCmpIntSel = BtCmpIntNone; //B通道比较控制:无
Bt_M23_PortOutput_Cfg(TIM0, &stcBtPortCmpCfg); //比较输出端口配置
stcBtBrakeCfg.bEnBrake = TRUE; /*刹车使能*/
stcBtBrakeCfg.enBkCH0AStat = BtCHxBksLow; /*IO输出为低*/
stcBtBrakeCfg.enBkCH0BStat = BtCHxBksLow; /*IO输出为低*/
Bt_M23_BrakeInput_Cfg(TIM0, &stcBtBrakeCfg);
u8ValidPeriod = 1; //事件更新周期设置,0表示三角波每半个周期更新一次,每+1代表延迟半个周期
Bt_M23_SetValidPeriod(TIM0,u8ValidPeriod); //间隔周期设置
stcBtDeadTimeCfg.bEnDeadTime = TRUE;
stcBtDeadTimeCfg.u8DeadTimeValue = DeadTime;
Bt_M23_DT_Cfg(TIM0, &stcBtDeadTimeCfg); //死区配置
u16CntValue = 0;
Bt_M23_Cnt16Set(TIM0, u16CntValue); //设置计数初值
Bt_ClearAllIntFlag(TIM0); //清中断标志
Bt_Mode23_EnableIrq(TIM0,BtUevIrq); //使能TIM0 UEV更新中断
EnableNvic(TIM0_IRQn, IrqLevel0, TRUE); //TIM0中断使能
}
//端口配置初始化
static void BSP_Timer0PortCfg(void)
{
stc_gpio_cfg_t stcTIM0Port;
//结构体初始化清零
DDL_ZERO_STRUCT(stcTIM0Port);
Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE); //GPIO 外设时钟使能
stcTIM0Port.enDir = GpioDirOut;
Gpio_Init(GpioPortA, GpioPin0, &stcTIM0Port);
Gpio_SetAfMode(GpioPortA,GpioPin0,GpioAf7); //PA00设置为TIM0_CHA
Gpio_Init(GpioPortA, GpioPin1, &stcTIM0Port);
Gpio_SetAfMode(GpioPortA,GpioPin1,GpioAf3); //PA01设置为TIM0_CHB
}
/*带死区的周期4ms的互补PWM*/
void BSP_PWM_Config(void)
{
App_Timer0Cfg(6000, BtPCLKDiv16,3000,0x80); //Timer0 配置:周期 6000(T= 4ms); 通道A比较值2400; 通道B比较值互补模式不需要设置
BSP_Timer0PortCfg(); //Timer0 Port端口配置
Bt_M23_EnPWM_Output(TIM0, TRUE, FALSE); //TIM0 端口输出使能
Bt_M23_Run(TIM0); //TIM0 运行
}
/*带死区的2路互补pwm输出(250ms+150usHighPuls)*/
void BSP_2Comp_PWM_Config(void)
{
uint16_t BCompare = 100; // 理论计算值为15
App_Timer0Cfg(23700, BtPCLKDiv256, 23700 - BCompare, 0x80); // 通道B比较值互补模式不需要设置
BSP_Timer0PortCfg(); //Timer0 Port端口配置
Bt_M23_EnPWM_Output(TIM0, TRUE, FALSE); //TIM0 端口输出使能
Bt_M23_Run(TIM0); //TIM0 运行
}
/*duty : 0~99*/
void BSP_PWM_SetDuty(uint8_t duty)
{
Bt_M23_CCR_Set(TIM0, BtCCR0A, 6000 - 6000*duty/100); //设置通道A比较值
}
/*******************************************************************************
* TIM0中断服务函数
******************************************************************************/
void Tim0_IRQHandler(void)
{
//Timer0 模式23 更新中断
if(TRUE == Bt_GetIntFlag(TIM0, BtUevIrq))
{
Bt_ClearIntFlag(TIM0,BtUevIrq); //清中断标志
}
}
pwm周期变换的时候我们想到的做法是: