×
单片机 > 单片机程序设计 > 详情

STM32输出 PWM频率 占空比 连续可调

发布时间:2020-05-30 发布时间:
|

话不多说 直接上代码 我的平台是 stm32F407VGT6 PA0 输出 使用定时器TIM2



//编程输出可调的硬件PWM,频率范围1Hz - 1MHz,占空比0 - 100 %


uint32_t TIM2_PWM_FQ = 50;             /* TIM2_CH1_PWM输出 频率设置值,1-1000000 */

uint32_t TIM2_PWM_FQ_Old  = 0;

uint16_t TIM2_PWM_Pulse = 50;          /* TIM2_CH1_PWM输出 占空比设置值,0-100 */

uint16_t TIM2_PWM_Pulse_Old = 0;


uint32_t SystemCoreClock = 168000000;


/*

* 函数功能: 定时器4配置为硬件PWM模式(不开启TIM2的定时及DMA传输中断)

* TIM2_PWM_FQ:     TIM2_CH1_PWM 频率    1Hz至1000000Hz

* TIM2_PWM_Pulse:  TIM2_CH1_PWM 占空比  0-100%

*/

void StdPeriph_TIM2_PWM_Config(void)

{

    GPIO_InitTypeDef GPIO_InitStructure;

    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

    TIM_OCInitTypeDef  TIM_OCInitStructure;


    uint32_t temp32;

    uint32_t uhTimerfrequency;

    uint16_t uhTimerPeriod;

    uint16_t uhTimerPulse;


    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);  

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

    // GPIOB Configuration

    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;

    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;

    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;

    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN;

    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;

    GPIO_Init(GPIOA, &GPIO_InitStruct);


    GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_TIM2);


    uhTimerfrequency = 200000; /* 初始化 200KHz */

    temp32 = ((SystemCoreClock / 2) / uhTimerfrequency);

    if (temp32 > 65535) temp32 = 65535;

    uhTimerPeriod = (uint16_t) temp32;

    uhTimerPulse  = uhTimerPeriod * 50 / 100; /* 占空比50% */


    // Time base configuration

    TIM_TimeBaseStructure.TIM_Period = uhTimerPeriod - 1; /* 0x0000 and 0xFFFF */

    TIM_TimeBaseStructure.TIM_Prescaler = 0; /* 0x0000 and 0xFFFF */

    TIM_TimeBaseStructure.TIM_ClockDivision = 0;

    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);


    // PWM1 Mode configuration: Channel1

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;

    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

    TIM_OCInitStructure.TIM_Pulse = uhTimerPulse;

    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;


    TIM_OC1Init(TIM2, &TIM_OCInitStructure);

    TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable);

    TIM_ARRPreloadConfig(TIM2, ENABLE);

    TIM_GenerateEvent(TIM2, TIM_EventSource_Update);


    TIM_Cmd(TIM2, ENABLE);

}


/*

* 函数功能: 刷新TIM2_CH1_PWM输出的频率和占空比

* 修改TIM2_PWM_FQ的值,调节PWM频率(1Hz至1MHz)

* 修改TIM2_PWM_Pulse的值,调节PWM的占空比(0-100)

*/


void StdPeriph_TIM2_PWM_Update(void)

{

    uint32_t temp32;

    uint32_t uhTimerfrequency;

    uint16_t uhTimerPeriod;

    uint16_t uhTimerPrescaler;

    uint16_t uhTimerPulse;


    if ((TIM2_PWM_FQ_Old != TIM2_PWM_FQ) || (TIM2_PWM_Pulse_Old != TIM2_PWM_Pulse)) {

        TIM2_PWM_FQ_Old = TIM2_PWM_FQ;

        TIM2_PWM_Pulse_Old = TIM2_PWM_Pulse;

        if (TIM2_PWM_FQ >= 4000) {

            uhTimerfrequency = TIM2_PWM_FQ;  /* 定时器计时频率和PWM频率相等 */

            uhTimerPrescaler = 1;    /* 实际频率TIM2_PWM_FQ较大时,TIM2设置分频为1(不分频)   */

        } else {

            uhTimerfrequency = 4000; /* 实际频率TIM2_PWM_FQ较小时,和4000Hz的频率比较,看相差几倍 */

            uhTimerPrescaler = 4000 / TIM2_PWM_FQ;  /* 实际频率和4000相差的倍数作为TIM2的分频设置值 */

            uhTimerfrequency = uhTimerPrescaler * TIM2_PWM_FQ; /* TIM2分频后,计时周期变长,需要将uhTimerfrequency倍频  */

        }


        /* TIM2的周期要通过倍频uhTimerfrequency来计算,uhTimerPeriod = 84MHz / uhTimerfrequency */

        temp32 = ((SystemCoreClock / 2) / uhTimerfrequency);

        if (temp32 > 65535) temp32 = 65535;

        uhTimerPeriod = (uint16_t) temp32;


        if (TIM2_PWM_Pulse > 100) TIM2_PWM_Pulse = 100;

        uhTimerPulse = uhTimerPeriod * TIM2_PWM_Pulse / 100;


        TIM2->ARR  = uhTimerPeriod - 1;

        TIM2->PSC  = uhTimerPrescaler - 1;

        TIM2->CCR1 = uhTimerPulse;

        TIM2->EGR  = TIM_PSCReloadMode_Update;

    }

}



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
单片机中高阻态的实质及意义