STM32F103单片机定时器自带互补PWM波形输出功能,利用定时器输出比较模式,不仅可以输出互补的 PWM波,还可以设置输出方波的起始相位和死区时间。
下面就总结一下如何实现PWM互补输出。
- void TIM1_PWM_DeadtimeInit( u16 arr, u16 psc, u16 ccr1, u16 ccr2, u16 deadtime )
- {
- GPIO_InitTypeDef GPIO_InitSturcture;
- TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
- TIM_OCInitTypeDef TIM_OCInitStructure;
- TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
- RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE );
- RCC_APB2PeriphClockCmd( RCC_APB2Periph_TIM1, ENABLE );
- //TIM1 互补PWM CH1->PA8 CH2->PA9 CH1N->PB13 CH2N->PB14
- GPIO_InitSturcture.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
- GPIO_InitSturcture.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_InitSturcture.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init( GPIOA, &GPIO_InitSturcture );
- GPIO_InitSturcture.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14;
- GPIO_InitSturcture.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_InitSturcture.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init( GPIOB, &GPIO_InitSturcture );
- //定时器设置
- TIM_TimeBaseInitStructure.TIM_Period = arr;
- TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
- TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
- TIM_TimeBaseInitStructure.TIM_ClockDivision = 0x00;
- TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0x00;
- TIM_TimeBaseInit( TIM1, &TIM_TimeBaseInitStructure );
- //通道1 捕获比较模式设置
- TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle; //翻转,当 TIMx_CCR1=TIMx_CNT时,翻转OC1REF的电平
- TIM_OCInitStructure.TIM_Pulse = ccr1; //100
- TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //CCER的CC1P,输入/捕获输出极性
- TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCPolarity_High;
- TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //CER的CC1N,输入/捕获输出使能
- TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
- TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; //OIS1位
- TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset; //CR2的OIS1N位,当MOE位0时,输出空闲状态位OIS1N.
- TIM_OC1Init( TIM1, &TIM_OCInitStructure );
- //通道2 设置
- TIM_OCInitStructure.TIM_Pulse = ccr2; //316
- TIM_OC2Init( TIM1, &TIM_OCInitStructure );
- //刹车和死区设置
- TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; //OSSR:运行模式下“关闭状态”选择
- TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; //OSSI:空闲模式下“关闭状态”选择
- TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1; //锁定设 置,级别为1
- TIM_BDTRInitStructure.TIM_DeadTime = deadtime; //死区延时时间
- TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable; //禁止刹车输 入
- TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_Low; //刹车输入极性
- TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; //自动输出使能
- TIM_BDTRConfig( TIM1, &TIM_BDTRInitStructure );
- TIM_CtrlPWMOutputs( TIM1, ENABLE );
- TIM_OC1PreloadConfig( TIM1, TIM_OCPreload_Enable );
- TIM_OC2PreloadConfig( TIM1, TIM_OCPreload_Enable );
- TIM_ARRPreloadConfig( TIM1, ENABLE );
- TIM_Cmd( TIM1, ENABLE );
- }
复制代码
首先初始化IO口,这里使用的是定时器1的通道1和通道2。
PA8为定时器1通道1输出口,PB13为定时器1通道1互补输出口。
PA9为定时器1通道2输出口, PB14为定时器1通道2互补输出口。
下来初始化定时器,参数arr设置输出PWM波频率,psc设置定时器时钟分频系数。定时器初始化之后,设置定时器工作模式为输出比较模式,其中参数 ccr1 设置通道1的输出方波起始相位,参数cc2设置通道2输出方波起始相位。参数 deadtime 设置互补PWM波形的死区时间。初始化结束后启动定时器。
关于输出比较模式的详细说明参考STM32输出比较模式和PWM模式 比较这篇文章。
下面看主函数设置
- #include "sys.h"
- #include "delay.h"
- #include "usart.h"
- #include "led.h"
- #include "pwm_ch_chn.h"
- // LED0 PA8 LED1 PD2
- int main(void)
- {
- delay_init(); //延时函数初始化
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
- LED_Init();
- LED0 = 1;
- LED1 = 1;
- delay_ms(500);
- LED0 = 0;
- LED1 = 0;
- // Tout=(719+1)*(0+1)/72M=10us 72M/720=0.1M=100K
- TIM1_PWM_DeadtimeInit(719,0,0,0,72);//50KHz
- while(1)
- {
-
- }
- }
复制代码
主函数中设置自动装载值为 720,分频系数为0,那么输出方波频率为 72MHz / 720 = 0.1MHz,也就是输出波形频率为100K,由于此处用的是定时器的输出比较模式,所以输出频率为计算值的一半,所以实际输出方波频率为50KHz。ccr1值设置为0,也就是定时器1通道1的输出波形起始相位为0,ccr2的值为0,所以起始相位也为0。死区时间设置为72,为周期数的1/10,也就是2us。
下面看一下输出波形
黄色为 TIM1_CH1波形,绿色为TIM1_CH1N波形,这两个波形是通道1互补波形。
蓝色为 TIM1_CH2波形,粉色为TIM1_CH2N波形,这两个波形是通道2互补波形。
黄色和蓝色波形起始相位相同。
原波形和互补波形死区时间为1us,刚才计算的死区时间是2us,这里为什么是1us?因为死区时间是上升沿时间差+下降沿时间差,是两个对称的区间。这里只测了一个区间,所以为总时间的一半。
下来同时改变ccr1和ccr2的初始值,看看输出波形相位有没有发生变化。
- TIM1_PWM_DeadtimeInit(719,0,72,144,72);//50KHz
复制代码
输出波形为
蓝色波形下降沿比黄色波形下降沿滞后了一点,说明起始相位已经发生了改变。
放大波形后可以看到,下降沿滞后的时间为1us,和死区时间相同。
|