#define TIMER4_PWM_GRP GPIOB
#define TIMER4_PWM_INDEX1 GPIO_Pin_7
#define TIMER4_PWM_INDEX2 GPIO_Pin_6
#define TIMER4_PWM_LOW(grp, index) GPIO_ResetBits(grp, index)
#define TIMER4_PWM_HIGH(grp, index) GPIO_SetBits(grp, index)
#define TIMER4_PWM_CONFIG(grp, index, mode) GPIOConfig(grp, index, mode)
#ifndef _BSP_PWM_H_
#define _BSP_PWM_H_
#include "stm32f10x_gpio.h"
#include "stm32f10x_tim.h"
#include "type.h"
void PwmTimerSet(GPIO_TypeDef* gpio, uint16_t pin, TIM_TypeDef* timer, uint8_t channel,
uint32_t freq, uint32_t duty);
#endif /* _BSP_PWM_H_ */
#include "pwm.h"
//#include "target.h"
void pwm_gpio_init(GPIO_TypeDef* gpio, uint16_t pin, GPIOMode_TypeDef mode)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
if(mode == GPIO_Mode_AF_PP)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
}
TIMER4_PWM_CONFIG(gpio, pin, mode);
}
// set freq(Hz) and duty(1/10000); if duty = 2000--- 2000/10000 = 20%
// PwmTimerSet(TIMER4_PWM_GRP, TIMER4_PWM_INDEX1, PWM_TIMER4, 1, 10000, 5000);
void PwmTimerSet(GPIO_TypeDef* gpio, uint16_t pin, TIM_TypeDef* timer, uint8_t channel,
uint32_t freq, uint32_t duty)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
uint16_t period, prescal;
uint32_t clk;
if(10000 == duty) // 100%
{
TimerDisable(timer);
pwm_gpio_init(gpio, pin, GPIO_Mode_Out_PP);
TIMER4_PWM_LOW(gpio, pin);
return;
}
pwm_gpio_init(gpio, pin, GPIO_Mode_AF_PP);
clk = SystemCoreClock; // 72 * 10^6;
if(freq < 100)
{
prescal = 100 - 1;
period = (clk / 10000) / freq - 1;
}
else if(freq < 3000)
{
prescal = 100 - 1;
period = (clk / 100) / freq - 1;
}
else
{
prescal = 0;
period = clk / freq - 1;
}
TIM_TimeBaseStructure.TIM_Period = period;
TIM_TimeBaseStructure.TIM_Prescaler = prescal;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(timer, &TIM_TimeBaseStructure);
TIM_OCStructInit(&TIM_OCInitStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = (duty * period) / 10000;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
if(1 == channel)
{
TIM_OC1Init(timer, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(timer, TIM_OCPreload_Enable);
}
else if(2 == channel)
{
TIM_OC2Init(timer, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(timer, TIM_OCPreload_Enable);
}
TIM_ARRPreloadConfig(timer, ENABLE);
/* TIMx enable counter */
TIM_Cmd(timer, ENABLE);
}