TIM--怎么输出具有相位差的PWM波形

在有些电机,等一些常见特殊应用场合经常遇到需要输出具备有一定相位差的PWM波形

实现一

利用定时器的翻转模式:

翻转模式手册介绍:即当计数器计数到比较值时会翻转对应通道值电平,原理如下草图。那么只要比较值设的不同,即可实现类似的效果。

但有个限制,这种只能实现百分之50占空比。

void TIM1_Phase_shift_Init1( void )
{
    GPIO_InitTypeDef GPIO_InitStructure={0};
    TIM_OCInitTypeDef TIM_OCInitStructure={0};
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure={0};

    RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOD |RCC_APB2Periph_GPIOC | RCC_APB2Periph_TIM1, ENABLE );

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init( GPIOD, &GPIO_InitStructure );
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
    GPIO_Init( GPIOC, &GPIO_InitStructure );

    TIM_TimeBaseInitStructure.TIM_Period = 100-1;
    TIM_TimeBaseInitStructure.TIM_Prescaler = 4800-1;
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit( TIM1, &TIM_TimeBaseInitStructure);

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;//翻转模式
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OCInitStructure.TIM_Pulse = 0;
    TIM_OC1Init( TIM1, &TIM_OCInitStructure );
    TIM_OCInitStructure.TIM_Pulse = 99;//Phase shift 90
    TIM_OC4Init( TIM1, &TIM_OCInitStructure );

    TIM_CtrlPWMOutputs(TIM1, ENABLE );
    TIM_OC1PreloadConfig( TIM1, TIM_OCPreload_Disable );
    TIM_OC4PreloadConfig( TIM1, TIM_OCPreload_Disable );
    TIM_ARRPreloadConfig( TIM1, ENABLE );
    TIM_Cmd( TIM1, ENABLE );
}

实现效果:

实现二

上述方法只能输出50百分比,如果想实现占空比可改,又可以移相那么就需要两个定时器,用到定时器的主从触发

主从触发设置讲解可参考该链接:https://www.cnblogs.com/wchmcu/p/17177773.html 

实现原理:定时器一做主,定时器二做从,利用定时器一的OC1触发(即定时器计数到比较捕获值时 从而触发定时器二启动)

void TIM1_Phase_shift_Init2( void )
{
    GPIO_InitTypeDef GPIO_InitStructure={0};
    TIM_OCInitTypeDef TIM_OCInitStructure={0};
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure={0};

    RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_TIM1, ENABLE );
    RCC_APB1PeriphClockCmd(  RCC_APB1Periph_TIM2, ENABLE );

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_4;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init( GPIOD, &GPIO_InitStructure );

    TIM_TimeBaseInitStructure.TIM_Period = 100-1;
    TIM_TimeBaseInitStructure.TIM_Prescaler = 4800-1;
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit( TIM1, &TIM_TimeBaseInitStructure);
    TIM_TimeBaseInit( TIM2, &TIM_TimeBaseInitStructure);

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
    TIM_OCInitStructure.TIM_Pulse = 10;//Phase shift 90
    TIM_OC1Init( TIM1, &TIM_OCInitStructure );
    TIM_OCInitStructure.TIM_Pulse = 10;
    TIM_OC1Init( TIM2, &TIM_OCInitStructure );

    TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable);
    TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_OC1Ref);

    TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Trigger);
    TIM_SelectInputTrigger(TIM2, TIM_TS_ITR0);

    TIM_CtrlPWMOutputs(TIM1, ENABLE );

    TIM_OC1PreloadConfig( TIM1, TIM_OCPreload_Disable );
    TIM_OC1PreloadConfig( TIM2, TIM_OCPreload_Disable );
    TIM_ARRPreloadConfig( TIM1, ENABLE );
    TIM_ARRPreloadConfig( TIM2, ENABLE );
    TIM_Cmd( TIM1, ENABLE );
}

实现效果:

 

posted @ 2025-03-19 17:17  WCH_CH32  阅读(404)  评论(0)    收藏  举报