没有前言(*)直接深入
要求:输出6路互补带死区的PWM
参考官方例程
- 初始化配置
1.1 时钟配置
系统时钟配置在启动文件里的SystemInit()函数(不放了看官方例程,函数放这有点占地方)
主要时修改 system_gd32f4xx.c 里面的宏 __SYSTEM_CLOCK_168M_PLL_8M_HXTAL
//外设时钟
void Clock_Init(void)
{
#ifdef USE_GD32F407
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_GPIOB);
rcu_periph_clock_enable(RCU_GPIOC);
rcu_periph_clock_enable(RCU_GPIOD);
rcu_periph_clock_enable(RCU_GPIOE); /* 使能GPIO时钟*/
rcu_periph_clock_enable(RCU_DAC); /* 使能 DAC 时钟*/
rcu_periph_clock_enable(RCU_ADC0); /* 使能 ADC 0时钟*/
rcu_periph_clock_enable(RCU_ADC1); /* 使能 ADC1 时钟*/
rcu_periph_clock_enable(RCU_ADC2); /* 使能 ADC2 时钟*/
rcu_periph_clock_enable(RCU_TIMER0); /* 使能 TIMER0 时钟*/
rcu_periph_clock_enable(RCU_SPI1); /* 使能 SPI1 时钟*/
rcu_periph_clock_enable(RCU_USART2); /* 使能 USART2 时钟*/
rcu_periph_clock_enable(RCU_TIMER2); /* 使能 TIMER2 时钟*/
rcu_periph_clock_enable(RCU_TIMER3); /* 使能 TIMER3 时钟*/
rcu_periph_clock_enable(RCU_USBHS); /* 使能 USBHS 时钟*/
rcu_periph_clock_enable(RCU_SPI2); /* 使能 SPI2 时钟*/
#endif
}
1.2 I/O配置
H文件
/* MCPWM_UH PE8/TIMER0_CH0_ON */
#define MCPWM_UH_PORT GPIOE
#define MCPWM_UH_PIN GPIO_PIN_8
#define MCPWM_UH_CHANNEL TIMER0_CH0_ON
/* MCPWM_UL PE9/TIMER0_CH0 */
#define MCPWM_UL_PORT GPIOE
#define MCPWM_UL_PIN GPIO_PIN_9
#define MCPWM_UL_CHANNEL TIMER0_CH0
/* MCPWM_VH PE10/TIMER0_CH1_ON */
#define MCPWM_VH_PORT GPIOE
#define MCPWM_VH_PIN GPIO_PIN_10
#define MCPWM_VH_CHANNEL TIMER0_CH1_ON
/* MCPWM_VL PE11/TIMER0_CH1 */
#define MCPWM_VL_PORT GPIOE
#define MCPWM_VL_PIN GPIO_PIN_11
#define MCPWM_VL_CHANNEL TIMER0_CH1
/* MCPWM_WH PE12/TIMER0_CH2_ON */
#define MCPWM_WH_PORT GPIOE
#define MCPWM_WH_PIN GPIO_PIN_12
#define MCPWM_WH_CHANNEL TIMER0_CH2_ON
/* MCPWM_WL PE13/TIMER0_CH2 */
#define MCPWM_WL_PORT GPIOE
#define MCPWM_WL_PIN GPIO_PIN_13
#define MCPWM_WL_CHANNEL TIMER0_CH2
/* MCPWM_FAULT PE15/TIMER0_BRKIN */
#define MCPWM_FAULT_PORT GPIOE
#define MCPWM_FAULT_PIN GPIO_PIN_15
#define MCPWM_FAULT_CHANNEL TIMER0_BRKIN
C文件
/* MCPWM*/
gpio_mode_set(MCPWM_UH_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, MCPWM_UH_PIN);
gpio_output_options_set(MCPWM_UH_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,MCPWM_UH_PIN);
gpio_af_set(MCPWM_UH_PORT, GPIO_AF_1, MCPWM_UH_PIN);
gpio_mode_set(MCPWM_UL_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, MCPWM_UL_PIN);
gpio_output_options_set(MCPWM_UL_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,MCPWM_UL_PIN);
gpio_af_set(MCPWM_UL_PORT, GPIO_AF_1, MCPWM_UL_PIN);
gpio_mode_set(MCPWM_VH_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, MCPWM_VH_PIN);
gpio_output_options_set(MCPWM_VH_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,MCPWM_VH_PIN);
gpio_af_set(MCPWM_VH_PORT, GPIO_AF_1, MCPWM_VH_PIN);
gpio_mode_set(MCPWM_VL_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, MCPWM_VL_PIN);
gpio_output_options_set(MCPWM_VL_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,MCPWM_VL_PIN);
gpio_af_set(MCPWM_VL_PORT, GPIO_AF_1, MCPWM_VL_PIN);
gpio_mode_set(MCPWM_WH_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, MCPWM_WH_PIN);
gpio_output_options_set(MCPWM_WH_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,MCPWM_WH_PIN);
gpio_af_set(MCPWM_WH_PORT, GPIO_AF_1, MCPWM_WH_PIN);
gpio_mode_set(MCPWM_WL_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, MCPWM_WL_PIN);
gpio_output_options_set(MCPWM_WL_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,MCPWM_WL_PIN);
gpio_af_set(MCPWM_WL_PORT, GPIO_AF_1, MCPWM_WL_PIN);
/*configure PE15(TIMER0 BKIN) as alternate function*/
gpio_mode_set(MCPWM_FAULT_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, MCPWM_FAULT_PIN);
gpio_output_options_set(MCPWM_FAULT_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,MCPWM_FAULT_PIN);
gpio_af_set(MCPWM_FAULT_PORT, GPIO_AF_1, MCPWM_FAULT_PIN);
1.3 定时器初始化
H文件
#define MCPWM_TIM TIMER0
#define MCPWM_U_CHANNEL TIMER_CH_0
#define MCPWM_V_CHANNEL TIMER_CH_1
#define MCPWM_W_CHANNEL TIMER_CH_2
/* ------------------------------PWM控制接口-------------------------------- */
#define P_HIGH__N_HIGH 1
#define P_HIGH__N_LOW 2
#define P_LOW__N_HIGH 3
#define P_LOW__N_LOW 4
#define N_HIGH__P_LOW 1
#define N_LOW__P_HIGH 2
/* 改变引脚驱动电平 */
//#define PRE_DRIVER_POLARITY P_HIGH__N_HIGH /* 预驱预动极性设置 上管高电平有效,下管高电平有效 */
//#define PRE_DRIVER_POLARITY P_HIGH__N_LOW /* 预驱预动极性设置 上管高电平有效,下管低电平有效 */
//#define PRE_DRIVER_POLARITY P_LOW__N_HIGH /* 预驱预动极性设置 上管高电平有效,下管低电平有效 */
#define PRE_DRIVER_POLARITY P_LOW__N_LOW /* 预驱预动极性设置 上管低电平有效,下管低电平有效 */
/* 改变引脚输出 */
#define MCPWM_TIM_SWAP N_HIGH__P_LOW /* PWM脚位 CH0 为下桥臂 CH0N 为上桥臂 */
//#define MCPWM_TIM_SWAP N_LOW__P_HIGH /* PWM脚位 CH0 为上桥臂 CH0N 为下桥臂 */
/*
* TIMER_OC_MODE_TIMING 冻结模式,不输出
* TIMER_OC_MODE_ACTIVE 输出比较模式0
* TIMER_OC_MODE_INACTIVE 输出比较模式1 实现通道的对调
* TIMER_OC_MODE_LOW 强制变为低电平
* TIMER_OC_MODE_HIGH 强制变为高电平
* TIMER_OC_MODE_PWM0 PWM模式0 TIMER0_CH0_ON 输出比较值
* TIMER_OC_MODE_PWM1 PWM模式1 TIMER0_CH0 输出比较值
*/
#if (MCPWM_TIM_SWAP == N_HIGH__P_LOW)
#define MCPWM_OC_MODE TIMER_OC_MODE_PWM1
#endif
#if (MCPWM_TIM_SWAP == N_LOW__P_HIGH)
#define MCPWM_OC_MODE TIMER_OC_MODE_PWM0
#endif
/* ----------------------MCPWM 频率及死区定义----------------------------------- */
#define MCU_MCLK (168000000) /* PWM模块运行主频 */
#define PWM_MCLK (MCU_MCLK) /* PWM模块运行主频 */
#define PWM_PRSC ((u8)0) /* PWM模块运行预分频器 */
#define PWM_FREQ ((u16)16000) /* PWM斩波频率 */
/* 电机控制PWM 周期计数器值 168M/(2*16K)=5250*/
#define PWM_PERIOD ((u16) (PWM_MCLK / (u32)(2 * PWM_FREQ *(PWM_PRSC+1))))
/* PFC控制PWM 周期计数器值 */
#define PFC_PERIOD ((u16) (PWM_MCLK / (u32)(2 * PFC_FREQ *(PWM_PRSC+1))))
#define PWM_CKDIV (0) /* PWM模块死区时间和数字滤波器采样时钟分频 0,1,2*/
#ifdef USE_GD32F407
#define PWM_CKDIV_DEADTIME (MCU_MCLK >> PWM_CKDIV) /* PWM模块死区时间和数字滤波器采样时钟 */
#endif
/* 死区时间分区 单位ns */
/*假设频率为168MHz
* 0~127 0~755
* 128~191 760~1510
* 192~223 1520~3000
* 224~255 3040~6000
* */
#define DEADTIME_NS_127 ((127)*1000000000/ (PWM_CKDIV_DEADTIME))
#define DEADTIME_NS_191 (((64+63)*1000000000/ (PWM_CKDIV_DEADTIME))<<1)
#define DEADTIME_NS_223 (((32+31)*1000000000/ (PWM_CKDIV_DEADTIME))<<3)
#define DEADTIME_NS_255 (((32+31)*1000000000/ (PWM_CKDIV_DEADTIME))<<4)
#define DEADTIME_NS (1000) /* 死区时间 单位ns */
#if (DEADTIME_NS <= DEADTIME_NS_127)
#define DEADTIME (u16)(((unsigned long long)PWM_CKDIV_DEADTIME * (unsigned long long)DEADTIME_NS)/1000000000uL)
#elif (DEADTIME_NS <= DEADTIME_NS_191)
#define DEADTIME (u16)(((((unsigned long long)PWM_CKDIV_DEADTIME * (unsigned long long)DEADTIME_NS)/1000000000uL)>>1)+64)
#elif (DEADTIME_NS <= DEADTIME_NS_223)
#define DEADTIME (u16)(((((unsigned long long)PWM_CKDIV_DEADTIME * (unsigned long long)DEADTIME_NS)/1000000000uL)>>3)-32+192)
#elif (DEADTIME_NS <= DEADTIME_NS_255)
#define DEADTIME (u16)(((((unsigned long long)PWM_CKDIV_DEADTIME * (unsigned long long)DEADTIME_NS)/1000000000uL)>>4)-32+224)
#endif
```c
/* 互补通道的输出控制关系 详情见 STM32F4参考手册(RM0090) P382 GD32F4用户手册 P364
* GD: ST:
* POEN: TIMERx_CCHP(15) timer_primary_output_config() 输出使能 MOE: TIMx_BDTR(15)
* ROS: TIMERx_CCHP(11) timer_breakpara.runoffstate 运行模式:输出使能打开时 OSSR: TIMx_BDTR(11)
* IOS: TIMERx_CCHP(10) timer_breakpara.ideloffstate 空闲模式:输出使能关闭时 OSSI: TIMx_BDTR(10)
* CHxEN: TIMERx_CHCTL2(0) timer_ocintpara.outputstate CCx: TIMx_CCER(0)
* CHxnEN: TIMERx_CHCTL2(2) timer_ocintpara.outputnstate CCxE: TIMx_CCER(2)
* |---------------控制位---------------|----------输出状态---------|
* | POEN | ROS | IOS | CHxEN | CHxnEN | OCx输出状态 | OCxN输出状态 |
* |----------------------------------------------------------------|
* | -0-- | -x- | -0- | --0-- | --0--- | 禁止输出 输出低电平 |
* |----------------------------------------------------------------|
* | -0-- | -x- | -0- | --0-- | --1--- | 0.禁止输出 |
* | -0-- | -x- | -0- | --1-- | --0--- | 1.先输出极性电平 |
* | -0-- | -x- | -0- | --1-- | --1--- | 2.死区之后输出空闲电平 |
* |----------------------------------------------------------------|
* | -0-- | -x- | -1- | --0-- | --0--- | 禁止输出,输出极性电平 |
* |----------------------------------------------------------------|
* | -0-- | -x- | -1- | --0-- | --1--- | 0.关闭输出 |
* | -0-- | -x- | -1- | --1-- | --0--- | 1.先输出极性电平 |
* | -0-- | -x- | -1- | --1-- | --1--- | 2.死区之后输出空闲电平 |
* |----------------------------------------------------------------|
* | -1-- | -0- | -x- | --0-- | --0-- | 禁止输出 输出低电平 |
* | -1-- | -0- | -x- | --0-- | --1-- |禁止输出输出低电平| PWM |
* | -1-- | -0- | -x- | --1-- | --0-- | PWM |禁止输出输出低电平|
* | -1-- | -0- | -x- | --1-- | --1-- | PWM | PWM |
* | -1-- | -1- | -x- | --0-- | --0-- | 输出极性 | 输出极性 |
* | -1-- | -1- | -x- | --0-- | --1-- | 输出极性 | PWM |
* | -1-- | -1- | -x- | --1-- | --0-- | PWM | 输出极性 |
* | -1-- | -1- | -x- | --1-- | --1-- | PWM | PWM |
* */
timer_oc_parameter_struct timer_ocintpara; /* 通道输出参数结构定义 */
timer_parameter_struct timer_initpara; /*计时器初始化参数结构定义*/
timer_break_parameter_struct timer_breakpara; /* 中断参数结构定义 */
/* 预分频
* 主频168M APB2 (Fmax=84MHz) 定时器时钟源为168M
* GD: RCU_CFG1 |= (1<<24); ST: RCC_DCKCFGR |= (1<<24);
*/
rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL2);
/*reset clock*/
timer_deinit(MCPWM_TIM);
/* TIMER0 configuration */
/* 定时器初始化
* GD: ST:
* 预分频 TIMER1_PSC = PWM_PRSC; TIM1_PSC = PWM_PRSC; 硬件自 +1
* 对齐模式 TIMER1_CTL0 |= TIMER_COUNTER_CENTER_BOTH ; TIM1_CR1 |= TIMER_COUNTER_CENTER_BOTH; (5,6)
* 计数方向 TIMER1_CTL0 |= TIMER_COUNTER_UP; TIM1_CR1 |= TIMER_COUNTER_UP; (4)
* 周期自动重装载 TIMER1_CAR |= PWM_PERIOD; TIM1_ARR |= PWM_PERIOD;
* 时钟分频 TIMER1_CTL0 |= TIMER_CKDIV_DIV1; TIM1_CR1 |= TIMER_CKDIV_DIV1 (8,9)
* 重复计数值 TIMER1_CREP = xx; TIM1_RCR = xx;
* 初始化计数器 TIMER1_SWEVG |= 0X01; TIM1_EGR |= 0X01;
* * * * * * * */
timer_initpara.prescaler = PWM_PRSC; /* 预分频值 */
timer_initpara.alignedmode = TIMER_COUNTER_CENTER_BOTH; /* 对齐模式 中心对齐模式 */
timer_initpara.counterdirection = TIMER_COUNTER_UP; /* 计数方向 */
timer_initpara.period = PWM_PERIOD; /* 周期 */
timer_initpara.clockdivision = CTL0_CKDIV(PWM_CKDIV); /* 时钟分频因子 */
timer_initpara.repetitioncounter = 0; /* 重复计数器值 用来产生中断*/
timer_init(MCPWM_TIM,&timer_initpara);
/* 通道初始化
* GD: ST:
* 使能通道P TIMER1_CHCTL2 |= TIMER_CCX_ENABLE; TIM1_CCER |= TIMER_CCX_ENABLE; (0)
* 通道P极性 TIMER1_CHCTL2 |= TIMER_OC_POLARITY_LOW; TIM1_CCER |= TIMER_CCX_ENABLE; (1)
* 使能通道N TIMER1_CHCTL2 |= TIMER_CCXN_ENABLE; TIM1_CCER |= TIMER_CCXN_ENABLE; (2)
* 通道N极性 TIMER1_CHCTL2 |= TIMER_OCN_POLARITY_LOW; TIM1_CCER |= TIMER_OCN_POLARITY_LOW; (3)
* 通道P的空闲状态输出 TIMERx_CTL1 |= TIMER_OC_IDLE_STATE_HIGH; TIM1_CR2 |= TIMER_OC_IDLE_STATE_HIGH; (8)
* 通道N的空闲状态输出 TIMERx_CTL1 |= TIMER_OCN_IDLE_STATE_HIGH; TIM1_CR2 |= TIMER_OCN_IDLE_STATE_HIGH; (9)
*/
#if (PRE_DRIVER_POLARITY == P_HIGH__N_HIGH) /* 改变输出有效值 */
{
/* CH0/CH0N,CH1/CH1N and CH2/CH2N configuration in timing mode */
timer_ocintpara.outputstate = TIMER_CCX_ENABLE; /* 通道输出状态 使能 */
timer_ocintpara.outputnstate = TIMER_CCXN_ENABLE; /* 互补通道输出状态 使能 */
timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_LOW; /* 通道输出极性 */
timer_ocintpara.ocnpolarity = TIMER_OCN_POLARITY_LOW; /* 互补通道输出极性 */
timer_ocintpara.ocidlestate = TIMER_OC_IDLE_STATE_HIGH; /* 空闲状态下通道输出 */
timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_HIGH; /* 空闲状态下互补通道输出 */
}
#elif (PRE_DRIVER_POLARITY == P_HIGH__N_LOW) /* 改变输出有效值 */
{
/* CH0/CH0N,CH1/CH1N and CH2/CH2N configuration in timing mode */
timer_ocintpara.outputstate = TIMER_CCX_ENABLE; /* 通道输出状态 使能 */
timer_ocintpara.outputnstate = TIMER_CCXN_ENABLE; /* 互补通道输出状态 使能 */
timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_LOW; /* 通道输出极性 */
timer_ocintpara.ocnpolarity = TIMER_OCN_POLARITY_LOW; /* 互补通道输出极性 */
timer_ocintpara.ocidlestate = TIMER_OC_IDLE_STATE_HIGH; /* 空闲状态下通道输出 */
timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_HIGH; /* 空闲状态下互补通道输出 */
}
#elif (PRE_DRIVER_POLARITY == P_LOW__N_HIGH) /* 改变输出有效值 */
{
/* CH0/CH0N,CH1/CH1N and CH2/CH2N configuration in timing mode */
timer_ocintpara.outputstate = TIMER_CCX_ENABLE; /* 通道输出状态 使能 */
timer_ocintpara.outputnstate = TIMER_CCXN_ENABLE; /* 互补通道输出状态 使能 */
timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_LOW; /* 通道输出极性 */
timer_ocintpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH; /* 互补通道输出极性 */
timer_ocintpara.ocidlestate = TIMER_OC_IDLE_STATE_HIGH; /* 空闲状态下通道输出 */
timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW; /* 空闲状态下互补通道输出 */
}
#elif (PRE_DRIVER_POLARITY == P_LOW__N_LOW) /* 改变输出有效值 */
{
/* CH0/CH0N,CH1/CH1N and CH2/CH2N configuration in timing mode */
timer_ocintpara.outputstate = TIMER_CCX_ENABLE; /* 通道输出状态 使能 */
timer_ocintpara.outputnstate = TIMER_CCXN_ENABLE; /* 互补通道输出状态 使能 */
timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_LOW; /* 通道输出极性 */
timer_ocintpara.ocnpolarity = TIMER_OCN_POLARITY_LOW; /* 互补通道输出极性 */
timer_ocintpara.ocidlestate = TIMER_OC_IDLE_STATE_HIGH; /* 空闲状态下通道输出 */
timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_HIGH; /* 空闲状态下互补通道输出 */
}
#endif
timer_channel_output_config(MCPWM_TIM,MCPWM_U_CHANNEL,&timer_ocintpara);
timer_channel_output_config(MCPWM_TIM,MCPWM_V_CHANNEL,&timer_ocintpara);
timer_channel_output_config(MCPWM_TIM,MCPWM_W_CHANNEL,&timer_ocintpara);
#if 0
/* 用于触发ADC采样 */
timer_ocintpara.outputstate = TIMER_CCX_ENABLE; /* 通道输出状态 */
timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE; /* 互补通道输出状态 */
timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_LOW; /* 通道输出极性 */
timer_ocintpara.ocnpolarity = TIMER_OCN_POLARITY_LOW; /* 互补通道输出极性 */
timer_ocintpara.ocidlestate = TIMER_OC_IDLE_STATE_HIGH; /* 空闲状态下通道输出 */
timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_HIGH; /* 空闲状态下互补通道输出 */
timer_channel_output_config(MCPWM_TIM,TIMER_CH_3,&timer_ocintpara);
#endif
/* 通道输出比较模式初始化
* GD: ST:
* 输出比较值即占空比 TIMER1_CH0CV |= xx; TIMx_CCMR1 |= xx;
* TIMER_OC_MODE_TIMING : 冻结模式,不输出
* TIMER_OC_MODE_ACTIVE : 输出比较模式0
* TIMER_OC_MODE_INACTIVE :输出比较模式1 实现通道的对调
* TIMER_OC_MODE_LOW : 强制变为低电平
* TIMER_OC_MODE_HIGH : 强制变为高电平
* TIMER_OC_MODE_PWM0 : PWM模式0 TIMER0_CH0_ON 输出比较值
* TIMER_OC_MODE_PWM1 : PWM模式1 TIMER0_CH0 输出比较值
* 输出模式 TIMER1_CHCTL0 |= TIMER_OC_MODE_TIMING; TIMx_CCMR1 |= TIMER_OC_MODE_TIMING; (4,6)
* 通道输出比较清0使能 TIMER1_CHCTL0 |= TIMER_OC_SHADOW_ENABLE; TIMx_CCMR1 |= TIMER_OC_SHADOW_ENABLE; (7)
*/
timer_channel_output_pulse_value_config(MCPWM_TIM,MCPWM_U_CHANNEL,PWM_PERIOD);
timer_channel_output_mode_config(MCPWM_TIM,MCPWM_U_CHANNEL,TIMER_OC_MODE_TIMING);/* 冻结模式不输出 */
timer_channel_output_shadow_config(MCPWM_TIM,MCPWM_U_CHANNEL,TIMER_OC_SHADOW_ENABLE);
timer_channel_output_pulse_value_config(MCPWM_TIM,MCPWM_V_CHANNEL,PWM_PERIOD>>1);
timer_channel_output_mode_config(MCPWM_TIM,MCPWM_V_CHANNEL,TIMER_OC_MODE_TIMING);
timer_channel_output_shadow_config(MCPWM_TIM,MCPWM_V_CHANNEL,TIMER_OC_SHADOW_ENABLE);
timer_channel_output_pulse_value_config(MCPWM_TIM,MCPWM_W_CHANNEL,PWM_PERIOD>>2);
timer_channel_output_mode_config(MCPWM_TIM,MCPWM_W_CHANNEL,TIMER_OC_MODE_TIMING);
timer_channel_output_shadow_config(MCPWM_TIM,MCPWM_W_CHANNEL,TIMER_OC_SHADOW_ENABLE);
/* 故障模式初始化
* GD: ST:
* 运行模式中故障时输出 TIMER1_CCHP |= TIMER_ROS_STATE_ENABLE; TIM1_BDTR |= TIMER_ROS_STATE_ENABLE; (11)
* 空闲模式中故障时输出 TIMER1_CCHP |= TIMER_IOS_STATE_ENABLE; TIM1_BDTR |= TIMER_IOS_STATE_ENABLE; (10)
* 死区时间 TIMER1_CCHP |= DEADTIME; TIM1_BDTR |= DEADTIME; (0,7)
* BRKIN 的极性 TIMER1_CCHP |= TIMER_BREAK_POLARITY_LOW; TIM1_BDTR |= TIMER_BREAK_POLARITY_LOW; (13)
* 自动输出使能 TIMER1_CCHP |= TIMER_OUTAUTO_ENABLE; TIM1_BDTR |= TIMER_OUTAUTO_ENABLE; (14)
* 写保护 TIMER1_CCHP |= TIMER_CCHP_PROT_OFF; TIM1_BDTR |= TIMER_CCHP_PROT_OFF; (8,9)
* 短路使能 TIMER1_CCHP |= TIMER_BREAK_ENABLE; TIM1_BDTR |= TIMER_BREAK_ENABLE; (12)
*/
/* automatic output enable, break, dead time and lock configuration*/
timer_breakpara.runoffstate = TIMER_ROS_STATE_ENABLE;/* 运行模式下“关闭状态”配置 */
timer_breakpara.ideloffstate = TIMER_IOS_STATE_ENABLE;/* 空闲模式下“关闭状态”配置 */
timer_breakpara.deadtime = DEADTIME;/*死区时间*/
timer_breakpara.breakpolarity = TIMER_BREAK_POLARITY_HIGH;/* TIMER_BREAK_POLARITY_LOW 这里有问题*/
timer_breakpara.outputautostate = TIMER_OUTAUTO_ENABLE;
timer_breakpara.protectmode = TIMER_CCHP_PROT_OFF;
timer_breakpara.breakstate = TIMER_BREAK_ENABLE;/* TIMER_BREAK_ENABLE */
timer_break_config(MCPWM_TIM,&timer_breakpara);
/* 当产生断点时,是否保持计数器的计数值不变
* GD: ST:
* TIMER0 保持位 DBG_CTL2 |=0X01 DBGMCU_APB2_FZ |= 0X01;
*/
dbg_periph_enable(DBG_TIMER0_HOLD);
dbg_periph_disable(DBG_TIMER0_HOLD);
/* TIMER0 primary output function enable */
/* 输出使能
* TIMERx_CCHP |= TIMER_CCHP_POEN; TIMx_BDTR |= TIMER_CCHP_POEN; (15)
*/
timer_primary_output_config(MCPWM_TIM,ENABLE);
/* TIMER0 channel control update interrupt enable */
/* 中断使能 */
timer_interrupt_enable(MCPWM_TIM,TIMER_INT_CMT);
/* TIMER0 break interrupt disable */
/* 禁止中断 */
timer_interrupt_disable(MCPWM_TIM,TIMER_INT_BRK);
timer_update_event_enable(MCPWM_TIM);
/* TIMER0 counter enable */
/* TIMER0_CTL0 |= TIMER_CTL0_CEN; (0) */
timer_enable(MCPWM_TIM);
1.4PWM输出
timer_channel_output_pulse_value_config(MCPWM_TIM,MCPWM_U_CHANNEL,PWM_PERIOD>>2);/* 占空比*/
timer_channel_output_mode_config(MCPWM_TIM,MCPWM_U_CHANNEL,MCPWM_OC_MODE);
// timer_channel_output_pulse_value_config(MCPWM_TIM,MCPWM_V_CHANNEL,PWM_PERIOD>>2);
timer_channel_output_mode_config(MCPWM_TIM,MCPWM_V_CHANNEL,MCPWM_OC_MODE);
// timer_channel_output_pulse_value_config(MCPWM_TIM,MCPWM_W_CHANNEL,PWM_PERIOD>>2);
timer_channel_output_mode_config(MCPWM_TIM,MCPWM_W_CHANNEL,MCPWM_OC_MODE);
不同配置的波形输出的图片
1.5 遇到的问题
1.5.1 驱动延时问题
由于硬件原因(GPIO->光耦->反短逻辑->驱动->MOS参照野火的驱动板),开通延时400ns,关断200ns,后续在控制中应做补偿
1.5.2 关于中止信号的问题
正常时TIMER0_BKIN电平为高电平,软件中中止极性要设置成高电平才不会触发保护。这问题不理解与参考手册相反。