完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
普通定时器输出互补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; /* 使能GPIO时钟 */ RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_GPIOB, ENABLE); /* 使能TMR1时钟 */ RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_TMR1, ENABLE); /* 配置GPIO */ 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; //TIM1_CH1N,TIM1_CH2N GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); /* 配置TMR1 */ TMR_TimeBaseStructInit(&TMR_TMReBaseStructure); TMR_TMReBaseStructure.TMR_Period = arr; /* PWM周期 */ TMR_TMReBaseStructure.TMR_DIV = psc; /* 120分频,即1MHz */ TMR_TMReBaseStructure.TMR_ClockDivision = 0; /* 时钟除频 */ TMR_TMReBaseStructure.TMR_CounterMode = TMR_CounterDIR_Up; /* 向上计数 */ TMR_TimeBaseInit(TMR1, &TMR_TMReBaseStructure); /* Set the default configuration */ 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;//DTG[7:0]死区发生器配置:(死区时间DT) ,注意死区时间要设成100ns左右,否则过大会导致MOS栅极PWM波形异常,太小导致上下臂短路 //TDTS = 125nS(8MHz) //DTG[7: 5] = 0xx => DT = DTG[7: 0] * Tdtg, Tdtg = TDTS; //DTG[7: 5] = 10x => DT =(64+DTG[5: 0]) * Tdtg, Tdtg = 2 * TDTS; //DTG[7: 5] = 110 => DT =(32+DTG[4: 0]) * Tdtg, Tdtg = 8 * TDTS; //DTG[7: 5] = 111=> DT =(32 + DTG[4: 0]) * Tdtg, Tdtg = 16 * TDTS; TIM_BDTRInitStruct.TMR_Break = TMR_Break_Disable; //刹车配置:使能刹车 TIM_BDTRInitStruct.TMR_BreakPolarity = TMR_BreakPolarity_High;//刹车输入极性选择:高电平有效 TIM_BDTRInitStruct.TMR_AutomaticOutput = TMR_AutomaticOutput_Enable;//自动输出使能配置:MOE只能软件置1 TMR_BRKDTConfig(TMR1, &TIM_BDTRInitStruct); //配置互补输出死区时间 /* 配置PWM从TMR1_CH1输出 */ TMR_OCStructInit(&TMR_OCInitStructure); TMR_OCInitStructure.TMR_OCMode = TMR_OCMode_PWM1; /* PWM模式 */ TMR_OCInitStructure.TMR_OutputState = TMR_OutputState_Enable; /* 使能输出 */ TMR_OCInitStructure.TMR_OutputNState = TMR_OutputNState_Enable; TMR_OCInitStructure.TMR_Pulse = 1000; /* PWM占空比 */ 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); /* 使能定时器TIM1在CCM上的周期值 */ TMR_OC1PreloadConfig(TMR1, TMR_OCPreload_Enable); TMR_OC2PreloadConfig(TMR1, TMR_OCPreload_Enable); TMR_OC3PreloadConfig(TMR1, TMR_OCPreload_Enable); /* 使能TIM3在AR上的预装载寄存器 */ TMR_ARPreloadConfig(TMR1, ENABLE); /* 使能TMR1 */ 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) //24k 42us { if (TMR_GetINTStatus(TMR1, TMR_INT_CC1) != RESET) // TIM_IT_CC1 { TMR_ClearITPendingBit(TMR1, TMR_INT_CC1); // 清除中断标志位 TMR1_Count ++; // all_foc_update(); } tim3为从定时器 void bsp_InitTMR3_PWM(void) { GPIO_InitType GPIO_InitStructure; TMR_TimerBaseInitType TMR_TMReBaseStructure; TMR_OCInitType TMR_OCInitStructure; NVIC_InitType NVIC_InitStructure; /* 使能GPIO时钟 */ RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_GPIOB, ENABLE); /* 使能TMR1时钟 */ RCC_APB1PeriphClockCmd(RCC_APB1PERIPH_TMR3, ENABLE); /* 配置GPIO */ 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; //TIM1_CH1N,TIM1_CH2N GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); /* 配置TMR1 */ TMR_TimeBaseStructInit(&TMR_TMReBaseStructure); TMR_TMReBaseStructure.TMR_Period = CYCLE - 1; /* PWM周期 */ TMR_TMReBaseStructure.TMR_DIV = 1; /* 120分频,即1MHz */ TMR_TMReBaseStructure.TMR_ClockDivision = 0; /* 时钟除频 */ TMR_TMReBaseStructure.TMR_CounterMode = TMR_CounterDIR_CenterAligned1; /* 向上计数 */ TMR_TMReBaseStructure.TMR_RepetitionCounter = 0x0000; TMR_TimeBaseInit(TMR3, &TMR_TMReBaseStructure); /* 配置PWM从TMR1_CH1输出 */ TMR_OCStructInit(&TMR_OCInitStructure); TMR_OCInitStructure.TMR_OCMode = TMR_OCMode_PWM1; /* PWM模式 */ TMR_OCInitStructure.TMR_OutputState = TMR_OutputState_Enable; /* 使能输出 */ TMR_OCInitStructure.TMR_OutputNState = TMR_OutputNState_Disable; TMR_OCInitStructure.TMR_Pulse = 1000; /* PWM占空比 */ TMR_OCInitStructure.TMR_OCPolarity = TMR_OCPolarity_High; /* 高电平有效 */ // TMR_OCInitStructure.TMR_OCNPolarity = TMR_OCNPolarity_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); /* 使能定时器TIM1在CCM上的周期值 */ TMR_OC1PreloadConfig(TMR3, TMR_OCPreload_Enable); TMR_OC3PreloadConfig(TMR3, TMR_OCPreload_Enable); TMR_OC4PreloadConfig(TMR3, TMR_OCPreload_Enable); /* 使能TIM3在AR上的预装载寄存器 */ TMR_ARPreloadConfig(TMR3, ENABLE); /* 使能TMR1 */ 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; /* 使能GPIO时钟 */ RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_GPIOB, ENABLE); /* 使能TMR1时钟 */ RCC_APB1PeriphClockCmd(RCC_APB1PERIPH_TMR4, ENABLE); /* 配置GPIO */ 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); /* 配置TMR4 */ TMR_TimeBaseStructInit(&TMR_TMReBaseStructure); TMR_TMReBaseStructure.TMR_Period = CYCLE - 1; /* PWM周期 */ TMR_TMReBaseStructure.TMR_DIV = 1; /* 120分频,即1MHz */ 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); /* 配置PWM从TMR1_CH1输出 */ TMR_OCStructInit(&TMR_OCInitStructure); TMR_OCInitStructure.TMR_OCMode = TMR_OCMode_PWM1; /* PWM模式 */ TMR_OCInitStructure.TMR_OutputState = TMR_OutputState_Enable; /* 使能输出 */ TMR_OCInitStructure.TMR_OutputNState = TMR_OutputNState_Disable; TMR_OCInitStructure.TMR_Pulse = 1050; /* PWM占空比 */ TMR_OCInitStructure.TMR_OCPolarity = TMR_OCPolarity_Low; /* 高电平有效 */ // TMR_OCInitStructure.TMR_OCNPolarity = TMR_OCNPolarity_High; TMR_OCInitStructure.TMR_OCIdleState = TMR_OCIdleState_Reset; TMR_OC1Init(TMR4, &TMR_OCInitStructure); TMR_OC2Init(TMR4, &TMR_OCInitStructure); TMR_OC3Init(TMR4, &TMR_OCInitStructure); /* 使能定时器TIM1在CCM上的周期值 */ TMR_OC1PreloadConfig(TMR4, TMR_OCPreload_Enable); TMR_OC2PreloadConfig(TMR4, TMR_OCPreload_Enable); TMR_OC3PreloadConfig(TMR4, TMR_OCPreload_Enable); /* 使能TIM3在AR上的预装载寄存器 */ TMR_ARPreloadConfig(TMR4, ENABLE); /* 使能TMR1 */ 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)); |
|
|
|
只有小组成员才能发言,加入小组>>
3278 浏览 9 评论
2955 浏览 16 评论
3455 浏览 1 评论
8987 浏览 16 评论
4050 浏览 18 评论
1102浏览 3评论
570浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
568浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2301浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1857浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 09:15 , Processed in 1.178046 second(s), Total 81, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号