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相位的改变,可用于控制移相全桥。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐