硬汉嵌入式论坛

 找回密码
 立即注册
查看: 3101|回复: 1
收起左侧

[有问必答] void BspSetTIMOutPWM函数里的TIM_Pulse有什么用?

[复制链接]

9

主题

12

回帖

39

积分

新手上路

积分
39
发表于 2021-7-2 14:17:55 | 显示全部楼层 |阅读模式
void BspSetTIMOutPWM(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin_x,
                     TIM_TypeDef* TIMx,   uint8_t _ucChannel,
                     uint32_t _ulFreq,    uint32_t _ulDutyCycle)
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_OCInitTypeDef TIM_OCInitStructure;
    uint16_t usPeriod;
    uint16_t usPrescaler;
    uint32_t uiTIMxCLK;
   
    if(0 == _ulDutyCycle)/*如果占空比为0*/
    {
        TIM_Cmd(TIMx, DISABLE);
        BspConfigGpioOut(GPIOx, GPIO_Pin_x);
        GPIO_WriteBit(GPIOx, GPIO_Pin_x, Bit_RESET);/* PWM = 0 */
        
        return;
    }
    else if(10000 == _ulDutyCycle)/*如果占空比为1*/
    {
        TIM_Cmd(TIMx, DISABLE);
        
        BspConfigGpioOut(GPIOx, GPIO_Pin_x);
        GPIO_WriteBit(GPIOx, GPIO_Pin_x, Bit_SET);/* PWM = 1 */
        return;
    }
   
    BspConfigTIMGpio(GPIOx, GPIO_Pin_x, TIMx, _ucChannel);
   
    /*-----------------------------------------------------------------------
        system_stm32f4xx.c 文件中 void SetSysClock(void) 函数对时钟的配置如下:

        HCLK = SYSCLK / 1     (AHB1Periph)
        PCLK2 = HCLK / 2      (APB2Periph)
        PCLK1 = HCLK / 4      (APB1Periph)

        因为APB1 prescaler != 1, 所以 APB1上的TIMxCLK = PCLK1 x 2 = SystemCoreClock / 2;
        因为APB2 prescaler != 1, 所以 APB2上的TIMxCLK = PCLK2 x 2 = SystemCoreClock;

        APB1 定时器有 TIM2, TIM3 ,TIM4, TIM5, TIM6, TIM6, TIM12, TIM13,TIM14
        APB2 定时器有 TIM1, TIM8 ,TIM9, TIM10, TIM11

    ----------------------------------------------------------------------- */
   
    if((TIMx == TIM1)||(TIMx == TIM8)||(TIMx == TIM9)||(TIMx == TIM10)||(TIMx == TIM11))
    {
        /* APB2 定时器 */
        uiTIMxCLK = SystemCoreClock;
    }
    else
    {
        /* APB1 定时器 */
        uiTIMxCLK = SystemCoreClock / 2;
    }
   
    if(_ulFreq < 100)
    {
        usPrescaler = 10000 - 1;
        usPeriod = (uiTIMxCLK / 10000) / _ulFreq - 1; //TIM3 假如是50Hz: usPeriod = (90 000 000 / 10000) /50  - 1 = 179
    }
    else if(_ulFreq < 3000)
    {
        usPrescaler = 100 - 1;
        usPeriod = (uiTIMxCLK / 100) / _ulFreq - 1;
    }
    else
    {
        usPrescaler = 0;
        usPeriod = uiTIMxCLK / _ulFreq - 1;
    }
   
    TIM_TimeBaseStructure.TIM_Period = usPeriod;                //上面计算是180
    TIM_TimeBaseStructure.TIM_Prescaler = usPrescaler;          // 9999
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0x0000;   /* TIM1 和 TIM8 必须设置 */   
   
    TIM_TimeBaseInit(TIMx, &TIM_TimeBaseStructure);
   
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = (_ulDutyCycle * usPeriod) / 10000;  // 5000 * 179 / 10000 = 13.5
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
   
    TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;    /* only for TIM1 and TIM8. */   
    TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;         /* only for TIM1 and TIM8. */   
    TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;        /* only for TIM1 and TIM8. */   
    TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;      /* only for TIM1 and TIM8. */   
   
    if(1 == _ucChannel)
    {
        TIM_OC1Init(TIMx, &TIM_OCInitStructure);
        TIM_OC1PreloadConfig(TIMx, TIM_OCPreload_Enable);
    }
    else if(2 == _ucChannel)
    {
        TIM_OC2Init(TIMx, &TIM_OCInitStructure);
        TIM_OC2PreloadConfig(TIMx, TIM_OCPreload_Enable);
    }
    else if(3 == _ucChannel)
    {
        TIM_OC3Init(TIMx, &TIM_OCInitStructure);
        TIM_OC3PreloadConfig(TIMx, TIM_OCPreload_Enable);
    }
    else if(4 == _ucChannel)
    {
        TIM_OC4Init(TIMx, &TIM_OCInitStructure);
        TIM_OC4PreloadConfig(TIMx, TIM_OCPreload_Enable);
    }
   
    TIM_ARRPreloadConfig(TIMx, ENABLE);
   
    TIM_Cmd(TIMx, ENABLE);
   
    if((TIMx == TIM1)||(TIMx == TIM8))
    {
        TIM_CtrlPWMOutputs(TIMx, ENABLE);
    }
   
}
回复

使用道具 举报

9

主题

12

回帖

39

积分

新手上路

积分
39
 楼主| 发表于 2021-7-2 14:19:36 | 显示全部楼层
上面应该是84 000 000,算错了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-14 19:02 , Processed in 0.047273 second(s), 23 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表