论持久战-STM32实现的PWM输出学习记录

                     本来打算假期把stm32吃透的怎奈家里的床就像吸铁石,手机里的王者就像农药蚕食我的计划(珍爱生命远离王者)。

                     那么我提一下目前的在搞的PWM输出吧。因为正在搞四轴飞行器,所以需要四路可调占空比的PWM信号来控制四个无刷电机。所以我需要利用stm32中的TIM4定时器来产生四路PWM。首先说下配置的思路及过程:

                                        1) 开启TIM4GPIO时钟,配置PB8|PB9|PB10|PB11选择复用功能AF输出

                                        2) 初始化TIM4,设置TIM4ARR(自动重装载值)PSC(预分频值等参数
                                        3) 设置TIM4_CH1/2/3/4PWM模式, 使能TIM4CH1/2/3/4输出

                                        4) 使能TIM4
                                        5) 修改TIM4_CCR1/2/3/4来控制占空比

                     好的那么咱们先写PWM初始化程序PWM.c



void PWM(u32 arr,u32 psc,u32 crr1,u32 crr2,u32 crr3,u32 crr4)
   { #include "PWM.h"
    GPIO_InitTypeDef  GPIO_InitStructure;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//使能gpioB时钟
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11;//初始化引脚PB8/9/10/11
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//设置为复用模式
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//设置为上拉
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化gpio
    GPIO_PinAFConfig(GPIOF, GPIO_PinSource6, GPIO_AF_TIM4);
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_TIM4);
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_TIM4);
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_TIM4);//映射复用的GPIO口PB8/9/10/11至定时器4
   TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;  
  TIM_OCInitTypeDef  TIM_OCInitStructure; 
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4 , ENABLE);//使能TIM4
  TIM_TimeBaseStructure.TIM_Prescaler = psc; //定时器分频 
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //向上计数模式
  TIM_TimeBaseStructure.TIM_Period = arr;    //自动重装载值
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;  
  TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;  //重复寄存器,用于自动更新pwm占空比     
  TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;    // 设置互补端输出极性
  TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;  //使能互补端输出
  TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;   // 死区后输出为高
  TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;  //死区后互补端输出为低
  
  TIM_OCInitStructure.TIM_Pulse =crr1;    // 
  TIM_OC1Init(TIM4, &TIM_OCInitStructure);
  TIM_OCInitStructure.TIM_Pulse =crr2;    //
  TIM_OC2Init(TIM4, &TIM_OCInitStructure);
  TIM_OCInitStructure.TIM_Pulse =crr3;    //
  TIM_OC3Init(TIM4, &TIM_OCInitStructure);
  TIM_OCInitStructure.TIM_Pulse =crr4;    //设置四个pwm通道占空比
  TIM_OC4Init(TIM4, &TIM_OCInitStructure);
  TIM_Cmd(TIM4, ENABLE); 
  /* TIM1 Main Output Enable */  
  TIM_CtrlPWMOutputs(TIM4, ENABLE);//使能PWM输出

}
      
  
  


然后是我们的头文件PWM.h

#include "sys.h"
#ifndef  PWM_
#def PWM_
 PWM(500-1,84-1,20,20,20,20)////定时器时钟为 84M,分频系数为 84,所以计数频率
//84M/84=1Mhz,重装载值 500,所以 PWM 频率为 1M/500=2Khz其余的crr1/2/3/4均为20 
#enif


接下来在主函数中通过TIM_SetComparex(TIMx,crrx);可以调节占空比

也可以通过改变void PWM(u32 arr,u32 psc,u32 crr1,u32 crr2,u32 crr3,u32 crr4) 后四个参数来改变各通道占空比
函数TIM-SetCompare1(TIM4,30)是将TIM4的第一通道crr1设置为30来控制占空比。

占空比计算公式为(TIM4_CCR1/ TIM4_ARR)* 100%


没有更多推荐了,返回首页