STM32F103输出互补PWM波

这是我参与更文挑战的第18天,活动详情查看: 更文挑战

        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,和死区时间相同。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享