2016-06-08 11:10 AM
Hello everyone,
I started with STM32F103 two days ago and I need to generate a PWM on GPIOB pin6 using TIM4. I need a PWM of period 20ms with a 1us precision (System Clock is set to 72 MHz) I have read several tutorial and examples, but I still cannot make it work (no signal, no PWM, nothing) Could anyone check what's wrong with my code ?////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//! Includes
////////////////////////////////////////////////////////////////////////////////
#include ''HIL_CLUTCH.h''
#include ''stm32f10x.h''
#include ''stm32f10x_spi.h''
#include ''stm32f10x_tim.h''
#include ''delay.h''
////////////////////////////////////////////////////////////////////////////////
//! Defines
////////////////////////////////////////////////////////////////////////////////
//typedef enum{eFullOnMode,eCruiseOnMode,eFullOffMode,eCuiseOffMode,eCustomMode} eClutchMode;
#define PORT_CLUTCH GPIOB //PB.6
#define PIN_CLUTCH GPIO_Pin_6
////////////////////////////////////////////////////////////////////////////////
//! Private prototypes
////////////////////////////////////////////////////////////////////////////////
void vHIL_CLUTCH_Init(void) ;
void ClutchTimerInit(uint16_t period) ;
void ClutchPWMInit(void) ;
void ClutchGPIOInit(void) ;
void RCC_Init() ;
////////////////////////////////////////////////////////////////////////////////
//! Private variables
////////////////////////////////////////////////////////////////////////////////
int UptimeMicroSec ;
////////////////////////////////////////////////////////////////////////////////
//! Private functions
////////////////////////////////////////////////////////////////////////////////
//Calls every function below
void vHIL_CLUTCH_Init(void)
{
RCC_Init() ;
ClutchGPIOInit() ;
ClutchTimerInit(999) ;
ClutchPWMInit() ;
}
void RCC_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
}
void ClutchTimerInit(uint16_t period)
TIM_TimeBaseInitTypeDef timerInitStructure;
timerInitStructure.TIM_Prescaler = 72 ;
timerInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
timerInitStructure.TIM_Period = period;
timerInitStructure.TIM_ClockDivision = 0;
timerInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM4, &timerInitStructure);
TIM_Cmd(TIM4, ENABLE);
}
void ClutchGPIOInit(void)
{
GPIO_InitTypeDef gpioStructure;
gpioStructure.GPIO_Pin = PIN_CLUTCH;
gpioStructure.GPIO_Mode = GPIO_Mode_AF_PP;
gpioStructure.GPIO_Speed = GPIO_Speed_50MHz ;
GPIO_Init(PORT_CLUTCH, &gpioStructure);
}
void ClutchPWMInit(void)
{
TIM_OCInitTypeDef outputChannelInit;
outputChannelInit.TIM_OCMode = TIM_OCMode_PWM1;
outputChannelInit.TIM_Pulse = 500;
outputChannelInit.TIM_OutputState = TIM_OutputState_Enable;
outputChannelInit.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM4, &outputChannelInit);
TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);
GPIO_PinRemapConfig(GPIO_Remap_TIM4,ENABLE);
}
#tim4 #pwm #stm32f103
2016-06-08 12:43 PM
Which STM32F103xx part specifically? Give me a fully qualified part#, not all support TIM4. Available on Medium and High density versions.
PB6 is the Default output for TIM4_CH1, not the Remapped one, so don't remap the pin/peripheral 1MHz from 72 MHz needs Prescaler = 72 - 1; // N steps, 0 .. N-1////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//! Includes
////////////////////////////////////////////////////////////////////////////////
#include ''HIL_CLUTCH.h''
#include ''stm32f10x.h''
#include ''stm32f10x_spi.h''
#include ''stm32f10x_tim.h''
#include ''delay.h''
////////////////////////////////////////////////////////////////////////////////
//! Defines
////////////////////////////////////////////////////////////////////////////////
//typedef enum{eFullOnMode,eCruiseOnMode,eFullOffMode,eCuiseOffMode,eCustomMode} eClutchMode;
#define PORT_CLUTCH GPIOB //PB.6
#define PIN_CLUTCH GPIO_Pin_6
////////////////////////////////////////////////////////////////////////////////
//! Private prototypes
////////////////////////////////////////////////////////////////////////////////
void vHIL_CLUTCH_Init(void) ;
void ClutchTimerInit(uint16_t period) ;
void ClutchPWMInit(void) ;
void ClutchGPIOInit(void) ;
void RCC_Init() ;
////////////////////////////////////////////////////////////////////////////////
//! Private variables
////////////////////////////////////////////////////////////////////////////////
int UptimeMicroSec ;
////////////////////////////////////////////////////////////////////////////////
//! Private functions
////////////////////////////////////////////////////////////////////////////////
//Calls every function below
void vHIL_CLUTCH_Init(void)
{
RCC_Init() ;
ClutchGPIOInit() ;
ClutchTimerInit(20000) ; // 20ms 20000us
ClutchPWMInit() ;
}
void RCC_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
}
void ClutchTimerInit(uint16_t period)
TIM_TimeBaseInitTypeDef timerInitStructure;
timerInitStructure.TIM_Prescaler = 72 - 1;
timerInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
timerInitStructure.TIM_Period = period - 1;
timerInitStructure.TIM_ClockDivision = 0;
timerInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM4, &timerInitStructure);
TIM_Cmd(TIM4, ENABLE);
}
void ClutchGPIOInit(void)
{
GPIO_InitTypeDef gpioStructure;
gpioStructure.GPIO_Pin = PIN_CLUTCH;
gpioStructure.GPIO_Mode = GPIO_Mode_AF_PP;
gpioStructure.GPIO_Speed = GPIO_Speed_50MHz ;
GPIO_Init(PORT_CLUTCH, &gpioStructure);
}
void ClutchPWMInit(void)
{
TIM_OCInitTypeDef outputChannelInit;
outputChannelInit.TIM_OCMode = TIM_OCMode_PWM1;
outputChannelInit.TIM_Pulse = 1500; // 1500us
outputChannelInit.TIM_OutputState = TIM_OutputState_Enable;
outputChannelInit.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM4, &outputChannelInit);
TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);
}
2016-06-10 07:45 AM
Thanks for your reply ! The MCU I'm using is STM32F103RB, which is medium density, I think.
Anyway, I tried your code and it works perfectly. Thank you very much ! For the story, I needed a PWM to control a servomotor for a dog clutch in the fuel-efficient vehicle TIM07. With your code, I can initialize the PWM. Then, I just change the duty cycle using TIM4->CCR1 = xxxx.2016-06-10 08:33 AM
The 20ms gives it away as a servo application, hence the choice of a value between 1 and 2ms for the pulse width, and using values that meet the requirement specified in the question.
I've covered servos here many times, you can control 4 independently from a single STM32 timer.