#include "bsp_pwm.h"
#include "stdio.h"
static void PWM_GPIO_Init(void); //声明PWM时所用管脚的初始化函数
void PWM_Init()
{
PWM_GPIO_Init(); //调用PWM时所用管脚的初始化函数
}
static void PWM_GPIO_Init(void) //pwm时管脚的配置
{
GPIO_InitTypeDef pwm1GPIO, pwm2GPIO; //定义结构体变量
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); //使能GPIOB时钟,同时GPIOB也是
//被重映射到的I/O端口的时钟,同时使能AFIO功能的时钟
GPIO_PinRemapConfig(GPIO_FullRemap_TIM2, ENABLE); //开启TIM2_CH4引脚映射
pwm1GPIO.GPIO_Pin = GPIO_Pin_11;
pwm1GPIO.GPIO_Speed = GPIO_Speed_10MHz;
pwm1GPIO.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出功能
GPIO_Init(GPIOB, &pwm1GPIO);
pwm2GPIO.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_9;
pwm2GPIO.GPIO_Speed = GPIO_Speed_2MHz;
pwm2GPIO.GPIO_Mode = GPIO_Mode_AF_PP;//GPIO_Mode_Out_PP; //推挽输出功能
GPIO_Init(GPIOB, &pwm2GPIO);
}
uint8_t Config_PWM(TIM_TypeDef* TIMx, uint8_t channel, uint32_t freq, uint32_t duty) //PWM的配置
{
TIM_TimeBaseInitTypeDef timBaseInit; //定义与PWM相关定时器参数的结构体变量
TIM_OCInitTypeDef timOCInit; //定义与PWM输出相关寄存器参数的结构体变量
RCC_ClocksTypeDef clkInfo; //定义与PWM输出相关时钟参数的结构体变量
//if(freq > 72000) //输入频率参数>72000,参数非法,返回
//return 1;
//if(pulse > 100) //输入占空比>100,参数非法,返回
//return 2;
if((0 == freq) || (0 == duty)) //频率 or 占空比为0,停止PWM
{
TIM_Cmd(TIMx, DISABLE); //由外部输入
}
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //开启TIMx时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
RCC_GetClocksFreq(&clkInfo); //获取当前各时钟信息
//初始化TIMx
if(freq > 500)
{
timBaseInit.TIM_Prescaler = 60 - 1; //预分频位100
//频率大于500赫兹
timBaseInit.TIM_Period = clkInfo.PCLK1_Frequency / (timBaseInit.TIM_Prescaler + 1) / freq;
}
else
{
timBaseInit.TIM_Prescaler = 6000 - 1;
//频率小于500赫兹,用于警报,采用下面公式
timBaseInit.TIM_Period = clkInfo.PCLK1_Frequency*10 / (timBaseInit.TIM_Prescaler + 1) / freq;
}
//timBaseInit.TIM_Period = clkInfo.PCLK1_Frequency / (timBaseInit.TIM_Prescaler + 1) / freq; //????
timBaseInit.TIM_ClockDivision = TIM_CKD_DIV4; //设置时钟分割
timBaseInit.TIM_CounterMode = TIM_CounterMode_Down; //向下计数
TIM_TimeBaseInit(TIMx, &timBaseInit);
//初始化TIMx Channelx PWM模式
timOCInit.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
//timOCInit.TIM_Pulse = duty; //设置占空比,由外部输入 公式为(TIM_Pulse/TIM_Period)*100%
timOCInit.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
timOCInit.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
//是能不同通道的PWM
switch(channel) //选择通道,由外部输入
{
case 1:
TIM_OC1Init(TIMx, &timOCInit);
TIM_OC1PreloadConfig(TIMx, TIM_OCPreload_Enable);
break;
case 2:
TIM_OC2Init(TIMx, &timOCInit);
TIM_OC2PreloadConfig(TIMx, TIM_OCPreload_Enable);
//printf("timx = %d\n",channel);
break;
case 3:
TIM_OC3Init(TIMx, &timOCInit);
TIM_OC3PreloadConfig(TIMx, TIM_OCPreload_Enable);
break;
case 4:
TIM_OC4Init(TIMx, &timOCInit);
TIM_OC4PreloadConfig(TIMx, TIM_OCPreload_Enable);
//printf("timx = %d\n",channel);
break;
}
//使能TIMx
TIM_Cmd(TIMx, ENABLE);
//设置不同通道的占空比
switch(channel)
{
case 1:
TIM_SetCompare1(TIMx, timBaseInit.TIM_Period * (100 - duty) / 100);
break;
case 2:
TIM_SetCompare2(TIMx, timBaseInit.TIM_Period * (100 - duty) / 100);
break;
case 3:
TIM_SetCompare3(TIMx, timBaseInit.TIM_Period * (100 - duty) / 100);
break;
case 4:
TIM_SetCompare4(TIMx, timBaseInit.TIM_Period * (100 - duty) / 100);
break;
}
return 0;
}