pwm.c
208 lines
| 6.2 KiB
| text/x-c
|
CLexer
kaveh
|
r90 | #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> | ||||
Jeandet Alexis
|
r100 | #include <timer.h> | ||
kaveh
|
r90 | 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); | ||||
PWMOUT |= gpiohighspeed | gpioaf | gpiopushpulltype | gpionopulltype; | ||||
gpiosetconfig(&PWMOUT); | ||||
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; | ||||
} | ||||