普通定时器输出互补PWM带死区
一般来说三相半桥电路需要互补PWM驱动,而且互补PWM需要带死区,死区的大小跟管子的性能参数有关。公司为了省成本,在云台上把电机驱动芯片替换成三相半桥。用6个MOS驱动无刷电机。这下就需要用到互补PWM了。
然后选型的单片机只有一路高级定时器tim1,另外一个电机的PWM驱动分别是tim3,tim4.不同的定时器怎么实现互补PWM而且带死区呢。
1、定时器主从功能
2、定时器中心对齐模式
3、tim3使用PWM1模式,tim4使用PWM2模式
4、输出PWM时占空比预留死区
在我的项目中互补PWM都已经实现,死区也已经实现,但是发现板子驱动电流还是很大,达不到要求,在经历了几天各种怀疑硬件问题的过程当中也寻找了很多解决办法。PWM配置问题等。。。
后来发现,波形的高电平有重叠。再次记住高电平不能有重叠的现象,要不就会出现短路导致电流过大。
具体配置代码如下:
tim1为主定时器
void bsp_InitTMR1_PWM1(uint16_t arr,uint16_t psc)
{
GPIO_InitType GPIO_InitStructure;
TMR_TimerBaseInitType TMR_TMReBaseStructure;
TMR_OCInitType TMR_OCInitStructure;
NVIC_InitType NVIC_InitStructure;
TMR_BRKDTInitType TIM_BDTRInitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_GPIOB, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_TMR1, ENABLE);
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pins = GPIO_Pins_8 | GPIO_Pins_9 | GPIO_Pins_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pins = GPIO_Pins_13 | GPIO_Pins_14 | GPIO_Pins_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
TMR_TimeBaseStructInit(&TMR_TMReBaseStructure);
TMR_TMReBaseStructure.TMR_Period = arr;
TMR_TMReBaseStructure.TMR_DIV = psc;
TMR_TMReBaseStructure.TMR_ClockDivision = 0;
TMR_TMReBaseStructure.TMR_CounterMode = TMR_CounterDIR_Up;
TMR_TimeBaseInit(TMR1, &TMR_TMReBaseStructure);
TIM_BDTRInitStruct.TMR_OSIMRState = TMR_OSIMRState_Enable;
TIM_BDTRInitStruct.TMR_OSIMIState = TMR_OSIMIState_Enable;
TIM_BDTRInitStruct.TMR_LOCKgrade = TMR_LOCKgrade_OFF;
TIM_BDTRInitStruct.TMR_DeadTime = 0x40;
TIM_BDTRInitStruct.TMR_Break = TMR_Break_Disable;
TIM_BDTRInitStruct.TMR_BreakPolarity = TMR_BreakPolarity_High;
TIM_BDTRInitStruct.TMR_AutomaticOutput = TMR_AutomaticOutput_Enable;
TMR_BRKDTConfig(TMR1, &TIM_BDTRInitStruct);
TMR_OCStructInit(&TMR_OCInitStructure);
TMR_OCInitStructure.TMR_OCMode = TMR_OCMode_PWM1;
TMR_OCInitStructure.TMR_OutputState = TMR_OutputState_Enable;
TMR_OCInitStructure.TMR_OutputNState = TMR_OutputNState_Enable;
TMR_OCInitStructure.TMR_Pulse = 1000;
TMR_OCInitStructure.TMR_OCPolarity = TMR_OCPolarity_High;
TMR_OCInitStructure.TMR_OCNPolarity = TMR_OCNPolarity_High;
TMR_OCInitStructure.TMR_OCIdleState = TMR_OCIdleState_Reset;
TMR_OCInitStructure.TMR_OCNIdleState = TMR_OCNIdleState_Reset;
TMR_OC1Init(TMR1, &TMR_OCInitStructure);
TMR_OC2Init(TMR1, &TMR_OCInitStructure);
TMR_OC3Init(TMR1, &TMR_OCInitStructure);
TMR_OC1PreloadConfig(TMR1, TMR_OCPreload_Enable);
TMR_OC2PreloadConfig(TMR1, TMR_OCPreload_Enable);
TMR_OC3PreloadConfig(TMR1, TMR_OCPreload_Enable);
TMR_ARPreloadConfig(TMR1, ENABLE);
TMR_Cmd(TMR1, ENABLE);
TMR_CtrlPWMOutputs(TMR1, ENABLE);
TMR_INTConfig(TMR1,TMR_INT_CC1,ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = TMR1_CC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TMR_SelectOutputTrigger(TMR1, TMR_TRGOSource_OC1);
TMR_SelectMasterSlaveMode(TMR1, TMR_MasterSlaveMode_Enable);
}
volatile uint32_t TMR1_Count = 0;
void TMR1_CC_IRQHandler(void)
{
if (TMR_GetINTStatus(TMR1, TMR_INT_CC1) != RESET)
{
TMR_ClearITPendingBit(TMR1, TMR_INT_CC1);
TMR1_Count ++;
}
}
tim3为从定时器
void bsp_InitTMR3_PWM(void)
{
GPIO_InitType GPIO_InitStructure;
TMR_TimerBaseInitType TMR_TMReBaseStructure;
TMR_OCInitType TMR_OCInitStructure;
NVIC_InitType NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1PERIPH_TMR3, ENABLE);
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pins = GPIO_Pins_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pins = GPIO_Pins_0 | GPIO_Pins_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
TMR_TimeBaseStructInit(&TMR_TMReBaseStructure);
TMR_TMReBaseStructure.TMR_Period = CYCLE - 1;
TMR_TMReBaseStructure.TMR_DIV = 1;
TMR_TMReBaseStructure.TMR_ClockDivision = 0;
TMR_TMReBaseStructure.TMR_CounterMode = TMR_CounterDIR_CenterAligned1;
TMR_TMReBaseStructure.TMR_RepetitionCounter = 0x0000;
TMR_TimeBaseInit(TMR3, &TMR_TMReBaseStructure);
TMR_OCStructInit(&TMR_OCInitStructure);
TMR_OCInitStructure.TMR_OCMode = TMR_OCMode_PWM1;
TMR_OCInitStructure.TMR_OutputState = TMR_OutputState_Enable;
TMR_OCInitStructure.TMR_OutputNState = TMR_OutputNState_Disable;
TMR_OCInitStructure.TMR_Pulse = 1000;
TMR_OCInitStructure.TMR_OCPolarity = TMR_OCPolarity_High;
TMR_OCInitStructure.TMR_OCIdleState = TMR_OCIdleState_Reset;
TMR_OC1Init(TMR3, &TMR_OCInitStructure);
TMR_OC3Init(TMR3, &TMR_OCInitStructure);
TMR_OC4Init(TMR3, &TMR_OCInitStructure);
TMR_SelectMasterSlaveMode(TMR3, TMR_MasterSlaveMode_Enable);
TMR_SelectInputTrigger(TMR3, TMR_TRGSEL_ITR0);
TMR_SelectSlaveMode(TMR3, TMR_SlaveMode_Trigger);
TMR_OC1PreloadConfig(TMR3, TMR_OCPreload_Enable);
TMR_OC3PreloadConfig(TMR3, TMR_OCPreload_Enable);
TMR_OC4PreloadConfig(TMR3, TMR_OCPreload_Enable);
TMR_ARPreloadConfig(TMR3, ENABLE);
TMR_Cmd(TMR1, ENABLE);
TMR_CtrlPWMOutputs(TMR1, ENABLE);
}
tim4为从定时器
void bsp_InitTMR4_PWM(void)
{
GPIO_InitType GPIO_InitStructure;
TMR_TimerBaseInitType TMR_TMReBaseStructure;
NVIC_InitType NVIC_InitStructure;
TMR_OCInitType TMR_OCInitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1PERIPH_TMR4, ENABLE);
GPIO_InitStructure.GPIO_Pins = GPIO_Pins_6 | GPIO_Pins_7 | GPIO_Pins_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
TMR_TimeBaseStructInit(&TMR_TMReBaseStructure);
TMR_TMReBaseStructure.TMR_Period = CYCLE - 1;
TMR_TMReBaseStructure.TMR_DIV = 1;
TMR_TMReBaseStructure.TMR_ClockDivision = 0;
TMR_TMReBaseStructure.TMR_CounterMode = TMR_CounterDIR_CenterAligned1;
TMR_TMReBaseStructure.TMR_RepetitionCounter = 0x0000;
TMR_TimeBaseInit(TMR4, &TMR_TMReBaseStructure);
TMR_SelectMasterSlaveMode(TMR4, TMR_MasterSlaveMode_Enable);
TMR_SelectInputTrigger(TMR4, TMR_TRGSEL_ITR0);
TMR_SelectSlaveMode(TMR4, TMR_SlaveMode_Trigger);
TMR_OCStructInit(&TMR_OCInitStructure);
TMR_OCInitStructure.TMR_OCMode = TMR_OCMode_PWM1;
TMR_OCInitStructure.TMR_OutputState = TMR_OutputState_Enable;
TMR_OCInitStructure.TMR_OutputNState = TMR_OutputNState_Disable;
TMR_OCInitStructure.TMR_Pulse = 1050;
TMR_OCInitStructure.TMR_OCPolarity = TMR_OCPolarity_Low;
TMR_OCInitStructure.TMR_OCIdleState = TMR_OCIdleState_Reset;
TMR_OC1Init(TMR4, &TMR_OCInitStructure);
TMR_OC2Init(TMR4, &TMR_OCInitStructure);
TMR_OC3Init(TMR4, &TMR_OCInitStructure);
TMR_OC1PreloadConfig(TMR4, TMR_OCPreload_Enable);
TMR_OC2PreloadConfig(TMR4, TMR_OCPreload_Enable);
TMR_OC3PreloadConfig(TMR4, TMR_OCPreload_Enable);
TMR_ARPreloadConfig(TMR4, ENABLE);
TMR_Cmd(TMR1, ENABLE);
TMR_CtrlPWMOutputs(TMR1, ENABLE);
}
设置占空比是预留tim3 tim4占空比不一样,即可实现死区
TMR_SetCompare1(TMR3, (uint32_t)w_time_ph_a);
TMR_SetCompare1(TMR4, (uint32_t)(w_time_ph_a + 20));
TMR_SetCompare3(TMR3, (uint32_t)w_time_ph_b);
TMR_SetCompare2(TMR4, (uint32_t)(w_time_ph_b + 20));
TMR_SetCompare4(TMR3, (uint32_t)w_time_ph_c);
TMR_SetCompare3(TMR4, (uint32_t)(w_time_ph_c + 20));
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)