STM32F1定时器输出两路相位可调PWM(可用于移相全桥控制或硬开关逆变全桥)
STM32F1定时器输出两路相位可调PWM(可用于移相全桥控制或硬开关逆变全桥)
STM32F1定时器输出两路相位可调PWM(可用于移相全桥控制或硬开关逆变全桥)
引言
假设现在要驱动一个H桥(如下图所示)实现DC/AC的变换。
理想情况下所需要保证的是
1、开关管组1:S1和S4同时导通。
2、开关管组2:S2和S3同时导通。
两组开关交替导通,为保证桥臂上开关管不直通,交替导通的开关管需要留有一定的死区时间。
这样就给开关管的驱动信号提出了要求:
1、两路驱动信号需要保证相位始终为180°(互补)。
2、PWM占空比相同(桥臂管子开关需要对称)。
3、需要留有一定死区(为了效果明显,假设死区为10%)。
方法描述
通过查阅数据手册,可采用两个定时器同步的模式(定时器级联)来进行驱动,采用主从模式进行控制。具体实现为主定时器TIM1输出两路PWM信号,其中通道1(CH1)用作管子驱动,通道2(CH2)设定比较值为周期的一半(实现主定时器TIM1通道1和从定时器TIM2通道1的固定相位差),配置MMS寄存器为100,将其比较有效信号OC2REF设定为主定时器TIM1输出,用于触发从定时器TIM2进行复位。定时器TIM2设置为从模式(SMS)复位模式(100),将触发信号TS设置为内部触发ITRx(具体实施需对照数据手册,定时器主从对照表)。
对应数据手册功能描述及寄存器说明
主从定时器控制结构示意图

用到寄存器描述
1、TIM_CR2 配置主模式

2、TIM_SMCR TS配置触发信号 SMS 配置从模式


3、主从定时器内部触发连接表
主从定时器运用举例——使用一个定时器使能另一个定时器

程序示例
具体程序实现,实验平台为STM32F103ZE,用到TIM2做主定时器CH4为触发信号输出通道,TIM1做从定时器复位模式。
1、定时器配置
void TIM1_PWM_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); // 使能定时器3时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO, ENABLE); // 使能GPIO外设和AFIO复用功能模块时钟
GPIO_PinRemapConfig(GPIO_FullRemap_TIM1, ENABLE); // Timer3部分重映射 TIM3_CH2->PB5
// 设置该引脚为复用输出功能,输出TIM3 CH2的PWM脉冲波形 GPIOB.5
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_10; // TIM_CH2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &GPIO_InitStructure); // 初始化GPIO
// 初始化TIM1
TIM_TimeBaseStructure.TIM_Period = 899; // 设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler = 1 - 1; // 设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = 0; // 设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // TIM向上计数模式
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
// 初始化TIM3 Channel2 PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // 比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OCInitStructure.TIM_Pulse = 899 / 2;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
TIM_OC2Init(TIM1, &TIM_OCInitStructure); // 根据T指定的参数初始化外设TIM3 OC2
TIM_SelectSlaveMode(TIM1, TIM_SlaveMode_Reset);
TIM_SelectInputTrigger(TIM1, TIM_TS_ITR1);
TIM_ARRPreloadConfig(TIM1, ENABLE);
TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable); // 使能TIM3在CCR2上的预装载寄存器
TIM_SetCompare2(TIM1, 0);
TIM_CtrlPWMOutputs(TIM1, ENABLE); // 开启OC和OCN输出
TIM_Cmd(TIM1, ENABLE); // 使能TIM3
}
void TIM2_PWM_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // 使能定时器3时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); // 使能GPIO外设和AFIO复用功能模块时
GPIO_PinRemapConfig(GPIO_FullRemap_TIM2, ENABLE); // Timer3部分重映射 TIM3_CH2->PB5
// 设置该引脚为复用输出功能,输出TIM3 CH2的PWM脉冲波形 GPIOB.5
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11; // TIM_CH2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure); // 初始化GPIO
// 初始化TIM1
TIM_TimeBaseStructure.TIM_Period = 899;
TIM_TimeBaseStructure.TIM_Prescaler = 1 - 1;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; // 选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // 比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; // 输出极性:TIM输出比较极性高
TIM_OCInitStructure.TIM_Pulse = 899 / 2;
TIM_OC3Init(TIM2, &TIM_OCInitStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; // 选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // 比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; // 输出极性:TIM输出比较极性高
TIM_OCInitStructure.TIM_Pulse = 899 / 2;
TIM_OC4Init(TIM2, &TIM_OCInitStructure);
TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);
TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_OC4Ref);
// TIM_ARRPreloadConfig(TIM5,ENABLE);
TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable); // 使能TIM3在CCR2上的预装载寄存器
TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable); // 使能TIM3在CCR2上的预装载寄存器
TIM_SetCompare3(TIM2, 0);
TIM_Cmd(TIM2, ENABLE); // 使能TIM3
}
2、主函数程序
int main(void)
{
TIM1_PWM_Init();
TIM2_PWM_Init();
TIM_SetCompare2(TIM1, 100);
TIM_SetCompare3(TIM2, 100);
while (1)
{
TIM_Cmd(TIM1, DISABLE);
TIM_Cmd(TIM2, DISABLE);
delay_ms(1);
TIM_Cmd(TIM1, ENABLE);
TIM_Cmd(TIM2, ENABLE);
delay_ms(1);
}
}
效果展示
用到keil内置的逻辑分析工具,将TIM对应引脚添加为输入,设定为BIT模式。
1、设置输入

2.仿真效果

上图所示,定时器2通道3和4相位相差180°,且在定时器2通道4变为高电平的同时定时器1通道也变为高电平,实现了两个定时器的同步。
注意事项:
1、主定时器配置的时候,为实现相位移动,需要将使用的两个通道配成不同的PWM模式,上面给出的程序示例中一个是PWM1,另一个是PWM2。
2、可以通过修改TIM2 CH4 的比较值CRR来实现两路PWM相位的改变,可用于控制移相全桥。
更多推荐



所有评论(0)