|
|
#include <pwm.h>
|
|
|
#include <stm32f4xx_tim.h>
|
|
|
#include <stm32f4xx_gpio.h>
|
|
|
#include <stm32f4xx_rcc.h>
|
|
|
#include <stm32f4xx_tim.h>
|
|
|
#include <core.h>
|
|
|
#include <gpio.h>
|
|
|
#include <timer.h>
|
|
|
|
|
|
const TIM_TypeDef* _timer_dev_table[14]={TIM1,TIM2,TIM3,TIM4,TIM5,TIM6,TIM7,
|
|
|
TIM8,TIM9,TIM10,TIM11,TIM12,TIM13,TIM14};
|
|
|
|
|
|
|
|
|
#define PWMGETTIMNUMBER(PWM) (((uint32_t)(PWM) & (uint32_t)0x0000FF00)>>(uint32_t)8)
|
|
|
|
|
|
int pwmopen(int PWM,uint32_t pin)
|
|
|
{
|
|
|
#define GPIOGETPORT(gpio) ((GPIO_TypeDef*)(((((uint32_t)gpio) & (uint32_t)0x0000FF00)*(uint32_t)4) + (uint32_t)GPIOA))
|
|
|
#define GPIOPORTNUM(gpio) (((uint32_t)(gpio) & (uint32_t)0x0000FF00)>>(uint32_t)8)
|
|
|
int timer = PWMGETTIMNUMBER(PWM);
|
|
|
gpio_t PWMOUT;
|
|
|
PWMOUT = gpioopen(pin);
|
|
|
gpiosetconfig(PWMOUT, gpioaf, gpiohighspeed, gpiopushpulltype, gpionopulltype);
|
|
|
uint8_t GPIO_AF = -1;
|
|
|
if(timer==timer1 || timer==timer2)GPIO_AF=1;
|
|
|
if(timer==timer3 || timer==timer4 || timer==timer5)GPIO_AF=2;
|
|
|
if(timer==timer8 || timer==timer9 || timer==timer10 || timer==timer11)GPIO_AF=3;
|
|
|
if(timer==timer12 || timer==timer13 || timer==timer14)GPIO_AF=9;
|
|
|
|
|
|
if(timer>=timer2 && timer <= timer7)RCC_APB1PeriphClockCmd((1<<(timer-1)), ENABLE);
|
|
|
if(timer>=timer12 && timer <= timer14)RCC_APB1PeriphClockCmd((1<<(timer-5)), ENABLE);
|
|
|
if(timer==timer1)RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
|
|
|
if(timer==timer8)RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE);
|
|
|
if(timer==timer9)RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM9, ENABLE);
|
|
|
if(timer==timer10)RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM10, ENABLE);
|
|
|
if(timer==timer11)RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM11, ENABLE);
|
|
|
|
|
|
if(GPIO_AF!=-1)GPIO_PinAFConfig(GPIOGETPORT(PWMOUT), (uint8_t)(PWMOUT & 0xF), GPIO_AF);
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int pwmsetconfig(int PWM,uint32_t freq,float dutyCycle)
|
|
|
{
|
|
|
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
|
|
TIM_OCInitTypeDef TIM_OCInitStructure;
|
|
|
if(PWM==-1) return -1;
|
|
|
int timer = PWMGETTIMNUMBER(PWM);
|
|
|
TIM_TypeDef* tim = _timer_dev_table[timer];
|
|
|
uint32_t timfreq = getCpuFreq()/2;
|
|
|
uint32_t period = timfreq/freq - 1;
|
|
|
uint16_t PrescalerValue=0;
|
|
|
|
|
|
while (period>=0x0FFFF)
|
|
|
{
|
|
|
PrescalerValue++;
|
|
|
timfreq = getCpuFreq()/(2*(PrescalerValue+1));
|
|
|
period = (timfreq/freq) - 1;
|
|
|
}
|
|
|
|
|
|
TIM_TimeBaseStructure.TIM_Period = period;
|
|
|
TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
|
|
|
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
|
|
|
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
|
|
TIM_TimeBaseInit(tim, &TIM_TimeBaseStructure);
|
|
|
|
|
|
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
|
|
|
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
|
|
|
TIM_OCInitStructure.TIM_Pulse = (uint32_t)((period * dutyCycle)/100);
|
|
|
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
|
|
|
|
|
|
switch (PWM&0x0FF) {
|
|
|
case 0:
|
|
|
TIM_OC1Init(tim, &TIM_OCInitStructure);
|
|
|
TIM_OC1PreloadConfig(tim, TIM_OCPreload_Enable);
|
|
|
TIM_ARRPreloadConfig(tim, ENABLE);
|
|
|
TIM_Cmd(tim, ENABLE);
|
|
|
break;
|
|
|
case 1:
|
|
|
TIM_OC2Init(tim, &TIM_OCInitStructure);
|
|
|
TIM_OC2PreloadConfig(tim, TIM_OCPreload_Enable);
|
|
|
TIM_ARRPreloadConfig(tim, ENABLE);
|
|
|
TIM_Cmd(tim, ENABLE);
|
|
|
break;
|
|
|
case 2:
|
|
|
TIM_OC3Init(tim, &TIM_OCInitStructure);
|
|
|
TIM_OC3PreloadConfig(tim, TIM_OCPreload_Enable);
|
|
|
TIM_ARRPreloadConfig(tim, ENABLE);
|
|
|
TIM_Cmd(tim, ENABLE);
|
|
|
break;
|
|
|
case 3:
|
|
|
TIM_OC4Init(tim, &TIM_OCInitStructure);
|
|
|
TIM_OC4PreloadConfig(tim, TIM_OCPreload_Enable);
|
|
|
TIM_ARRPreloadConfig(tim, ENABLE);
|
|
|
TIM_Cmd(tim, ENABLE);
|
|
|
break;
|
|
|
default:
|
|
|
return -1;
|
|
|
break;
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int pwmsetdutycycle(int PWM,float dutyCycle)
|
|
|
{
|
|
|
if(PWM==-1) return -1;
|
|
|
int timer = PWMGETTIMNUMBER(PWM);
|
|
|
TIM_TypeDef* tim = _timer_dev_table[timer];
|
|
|
switch (PWM&0x0FF) {
|
|
|
case 0:
|
|
|
tim->CCR1 = (uint32_t)((tim->ARR * dutyCycle)/100);
|
|
|
break;
|
|
|
case 1:
|
|
|
tim->CCR2 = (uint32_t)((tim->ARR * dutyCycle)/100);
|
|
|
break;
|
|
|
case 2:
|
|
|
tim->CCR3 = (uint32_t)((tim->ARR * dutyCycle)/100);
|
|
|
break;
|
|
|
case 3:
|
|
|
tim->CCR4 = (uint32_t)((tim->ARR * dutyCycle)/100);
|
|
|
break;
|
|
|
default:
|
|
|
return -1;
|
|
|
break;
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
float pwmgetdutycycle(int PWM)
|
|
|
{
|
|
|
if(PWM==-1) return -1;
|
|
|
int timer = PWMGETTIMNUMBER(PWM);
|
|
|
TIM_TypeDef* tim = _timer_dev_table[timer];
|
|
|
switch (PWM&0x0FF) {
|
|
|
case 0:
|
|
|
return (float)((tim->CCR1*100)/tim->ARR);
|
|
|
break;
|
|
|
case 1:
|
|
|
return (float)((tim->CCR2*100)/tim->ARR);
|
|
|
break;
|
|
|
case 2:
|
|
|
return (float)((tim->CCR3*100)/tim->ARR);
|
|
|
break;
|
|
|
case 3:
|
|
|
return (float)((tim->CCR4*100)/tim->ARR);
|
|
|
break;
|
|
|
default:
|
|
|
return -1;
|
|
|
break;
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
|
|
|
int pwmsetfrequency(int PWM,uint32_t freq)
|
|
|
{
|
|
|
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
|
|
if(PWM==-1) return -1;
|
|
|
int timer = PWMGETTIMNUMBER(PWM);
|
|
|
TIM_TypeDef* tim = _timer_dev_table[timer];
|
|
|
uint32_t timfreq = getCpuFreq()/2;
|
|
|
uint32_t period = timfreq/freq - 1;
|
|
|
uint16_t PrescalerValue=0;
|
|
|
float dutyCycle = pwmgetdutycycle(PWM);
|
|
|
while (period>=0x0FFFF)
|
|
|
{
|
|
|
PrescalerValue++;
|
|
|
timfreq = getCpuFreq()/(2*(PrescalerValue+1));
|
|
|
period = (timfreq/freq) - 1;
|
|
|
}
|
|
|
|
|
|
TIM_TimeBaseStructure.TIM_Period = period;
|
|
|
TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
|
|
|
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
|
|
|
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
|
|
TIM_TimeBaseInit(tim, &TIM_TimeBaseStructure);
|
|
|
|
|
|
switch (PWM&0x0FF) {
|
|
|
case 0:
|
|
|
tim->CCR1 = (uint32_t)((tim->ARR * dutyCycle)/100);
|
|
|
TIM_ARRPreloadConfig(tim, ENABLE);
|
|
|
break;
|
|
|
case 1:
|
|
|
tim->CCR2 = (uint32_t)((tim->ARR * dutyCycle)/100);
|
|
|
TIM_ARRPreloadConfig(tim, ENABLE);
|
|
|
break;
|
|
|
case 2:
|
|
|
tim->CCR3 = (uint32_t)((tim->ARR * dutyCycle)/100);
|
|
|
TIM_ARRPreloadConfig(tim, ENABLE);
|
|
|
break;
|
|
|
case 3:
|
|
|
tim->CCR4 = (uint32_t)((tim->ARR * dutyCycle)/100);
|
|
|
TIM_ARRPreloadConfig(tim, ENABLE);
|
|
|
break;
|
|
|
default:
|
|
|
return -1;
|
|
|
break;
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|