cancel
Showing results for 
Search instead for 
Did you mean: 

TIM4 CH3, CH2, CH1 now working

svarog995
Associate II
Posted on July 29, 2013 at 15:49

help again, I work with a four-timer but it does not work the channels one, two and three. I initialize them but they do not give a PWM.

CH4 working very good!

My code:

void init_pwm( void)

{

    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure2;

    TIM_OCInitTypeDef       TIM_OCInitStructure;

    GPIO_InitTypeDef   GPIO_InitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);

    GPIO_InitStructure. GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15;

    GPIO_InitStructure. GPIO_Mode = GPIO_Mode_AF ;

    GPIO_InitStructure. GPIO_Speed = GPIO_Speed_50MHz ;

    GPIO_InitStructure. GPIO_OType = GPIO_OType_PP ;

    GPIO_InitStructure. GPIO_PuPd = GPIO_PuPd_UP ;

    GPIO_Init(GPIOD, &GPIO_InitStructure);

    GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_2);

    GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_2);

    GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_2);

    GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_2);

    TIM_TimeBaseStructure2. TIM_Period = 19999;

    TIM_TimeBaseStructure2. TIM_Prescaler = 72-1;

    TIM_TimeBaseStructure2. TIM_ClockDivision = 0;

    TIM_TimeBaseStructure2. TIM_CounterMode = TIM_CounterMode_Up;

    TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure2);

    TIM_OCInitStructure. TIM_OCMode = TIM_OCMode_PWM1;

    TIM_OCInitStructure. TIM_OutputState = TIM_OutputState_Enable;

    TIM_OCInitStructure. TIM_Pulse = START;

    TIM_OCInitStructure. TIM_OCPolarity = TIM_OCPolarity_High;

    TIM_OC1Init(TIM4, &TIM_OCInitStructure);

    TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Disable);

    TIM_OCInitStructure. TIM_OutputState = TIM_OutputState_Enable;

    TIM_OCInitStructure. TIM_Pulse = START;

    TIM_OC2Init(TIM4, &TIM_OCInitStructure);

    TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Disable);

    TIM_OCInitStructure. TIM_OutputState = TIM_OutputState_Enable;

    TIM_OCInitStructure. TIM_Pulse = START;

    TIM_OC3Init(TIM4, &TIM_OCInitStructure);

    TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Disable);

    TIM_OCInitStructure. TIM_OutputState = TIM_OutputState_Enable;

    TIM_OCInitStructure. TIM_Pulse = START;

    TIM_OC4Init(TIM4, &TIM_OCInitStructure);

    TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Disable);

    TIM_Cmd(TIM4, ENABLE);

}

#understand-your-tools
8 REPLIES 8
Posted on July 29, 2013 at 17:44

May be you have other issues.

This works on all 4 channels for me

// STM32 4-channel Servo Demo for 72 MHz STM32F3 Discovery - sourcer32@gmail.com
#include ''stm32f3_discovery.h''
/**************************************************************************************/
// Integers, or scaled integers (*10) will be more efficient here
volatile float servo_angle[4] = { 0.0, 0.0, 0.0, 0.0 }; // +/- 0 degrees
void TIM4_IRQHandler(void)
{
if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
// minimum high of 600 us for -90 degrees, with +90 degrees at 2400 us, 10 us per degree
// timer timebase set to us units to simplify the configuration/math
TIM_SetCompare1(TIM4, 1500 + (int)(servo_angle[0] * 0f) ); // PD.12
TIM_SetCompare2(TIM4, 1500 + (int)(servo_angle[1] * 0f) ); // PD.13
TIM_SetCompare3(TIM4, 1500 + (int)(servo_angle[2] * 0f) ); // PD.14
TIM_SetCompare4(TIM4, 1500 + (int)(servo_angle[3] * 0f) ); // PD.15
}
}
/**************************************************************************************/
void RCC_Configuration(void)
{
/* --------------------------- System Clocks Configuration -----------------*/
/* TIM4 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
/* GPIOD clock enable */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);
}
/**************************************************************************************/
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable the TIM4 gloabal Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/**************************************************************************************/
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/*-------------------------- GPIO Configuration ----------------------------*/
/* GPIOD Configuration: Pins 12, 13, 14 and 15 in output push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
/* Connect TIM4 pins to AF2 */
GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_2);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_2);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_2);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_2);
}
/**************************************************************************************/
void TIM4_Configuration(void)
{
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
/* Time base configuration - SystemCoreClock = 72000000 for 72 MHz board */
TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t) ((SystemCoreClock / 1000000) - 1); // Shooting for 1 MHz, (1us)
TIM_TimeBaseStructure.TIM_Period = 20000 - 1; // 1 MHz / 20000 = 50 Hz (20ms)
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
/* Enable TIM4 Preload register on ARR */
TIM_ARRPreloadConfig(TIM4, ENABLE);
/* TIM PWM1 Mode configuration: Channel */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 1500; // Servo Top-Center
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
/* Output Compare PWM1 Mode configuration: Channel1 PD.12 */
TIM_OC1Init(TIM4, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);
/* Output Compare PWM1 Mode configuration: Channel2 PD.13 */
TIM_OC2Init(TIM4, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable);
/* Output Compare PWM1 Mode configuration: Channel3 PD.14 */
TIM_OC3Init(TIM4, &TIM_OCInitStructure);
TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);
/* Output Compare PWM1 Mode configuration: Channel4 PD.15 */
TIM_OC4Init(TIM4, &TIM_OCInitStructure);
TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable);
/* TIM Interrupts enable */
TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
/* TIM4 enable counter */
TIM_Cmd(TIM4, ENABLE);
}
/**************************************************************************************/
int main(void)
{
RCC_Configuration();
GPIO_Configuration();
NVIC_Configuration();
TIM4_Configuration();
while(1)
{
// Add code to stroke servos here
}
}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on October 04, 2013 at 21:42

Add code to demo motion

// STM32 4-channel Servo Demo for 72 MHz STM32F3 Discovery - sourcer32@gmail.com
#include ''stm32f3_discovery.h''
/**************************************************************************************/
// Integers, or scaled integers (*10) will be more efficient here
volatile float servo_angle[4] = { -0, -0, 0, 0 }; // +/- 0 degrees
#define SLEWRATE (1.0 / 0) // slew 1 degree per second, 50 Hz update
volatile float angle_delta[4] = { -SLEWRATE, -SLEWRATE, SLEWRATE, SLEWRATE };
void TIM4_IRQHandler(void)
{
if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)
{
int i;
TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
// minimum high of 600 us for -90 degrees, with +90 degrees at 2400 us, 10 us per degree
// timer timebase set to us units to simplify the configuration/math
TIM_SetCompare1(TIM4, 1500 + (int)(servo_angle[0] * 0f) ); // PD.12
TIM_SetCompare2(TIM4, 1500 + (int)(servo_angle[1] * 0f) ); // PD.13
TIM_SetCompare3(TIM4, 1500 + (int)(servo_angle[2] * 0f) ); // PD.14
TIM_SetCompare4(TIM4, 1500 + (int)(servo_angle[3] * 0f) ); // PD.15
// a quick hack to get the servo to stroke back and forth
for(i=0; i<
4
; i++)
{
servo_angle[i] += angle_delta[i];
if ((servo_angle[i] >= 0f) || (servo_angle[i] <= -0f))
{
angle_delta[i] = -angle_delta[i]; // reverse
servo_angle[i] += angle_delta[i];
}
}
}
}
/**************************************************************************************/
void RCC_Configuration(void)
{
/* --------------------------- System Clocks Configuration -----------------*/
/* TIM4 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
/* GPIOD clock enable */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);
}
/**************************************************************************************/
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable the TIM4 gloabal Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/**************************************************************************************/
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/*-------------------------- GPIO Configuration ----------------------------*/
/* GPIOD Configuration: Pins 12, 13, 14 and 15 in output push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
/* Connect TIM4 pins to AF2 */
GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_2);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_2);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_2);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_2);
}
/**************************************************************************************/
void TIM4_Configuration(void)
{
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_OCStructInit(&TIM_OCInitStructure);
/* Time base configuration - SystemCoreClock = 72000000 for 72 MHz board */
TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t) ((SystemCoreClock / 1000000) - 1); // Shooting for 1 MHz, (1us)
TIM_TimeBaseStructure.TIM_Period = 20000 - 1; // 1 MHz / 20000 = 50 Hz (20ms)
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
/* Enable TIM4 Preload register on ARR */
TIM_ARRPreloadConfig(TIM4, ENABLE);
/* TIM PWM1 Mode configuration: Channel */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 1500; // Servo Top-Center
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
/* Output Compare PWM1 Mode configuration: Channel1 PD.12 */
TIM_OC1Init(TIM4, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);
/* Output Compare PWM1 Mode configuration: Channel2 PD.13 */
TIM_OC2Init(TIM4, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable);
/* Output Compare PWM1 Mode configuration: Channel3 PD.14 */
TIM_OC3Init(TIM4, &TIM_OCInitStructure);
TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);
/* Output Compare PWM1 Mode configuration: Channel4 PD.15 */
TIM_OC4Init(TIM4, &TIM_OCInitStructure);
TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable);
/* TIM Interrupts enable */
TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
/* TIM4 enable counter */
TIM_Cmd(TIM4, DISABLE /*ENABLE*/);
}
/**************************************************************************************/
int main(void)
{
RCC_Configuration();
GPIO_Configuration();
NVIC_Configuration();
TIM4_Configuration();
while(1); // Infinite Loop, work done under interrupt
}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
mubinyousuf
Associate II
Posted on October 05, 2013 at 03:13

Thanks but i am getting this error

Error[Li005]: no definition for ''SystemCoreClock'' [referenced from C:\Users\Mubin\Downloads\fromScratch\IAR\Debug\Obj\main.o]

Posted on October 05, 2013 at 03:26

I'm not an IAR user, you will need to review the Template projects within the STM32F3-Discovery firmware library. Clone one of those and paste the example code into the ''main.c''component.

If you build a project from scratch you're going to have to specify the include paths for the libraries, the defines used for the board, and drop/add the library source files into the project.

SystemCoreClock should be exported from system_stm32f3xx.c
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
mubinyousuf
Associate II
Posted on October 05, 2013 at 03:31

i fixed the systemcoreclock problem, but i am still at a dead end, still cant run my motor, thats what have been happening with my previous programs, i thought there must be something wrong with my code but i think its the hardware problem.

Any suggestions tho?
Posted on October 05, 2013 at 03:59

I would start by evaluating the signal with a scope. Then using a common ground with the servo, and the control signal from the appropriate GPIO pin.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
mubinyousuf
Associate II
Posted on October 05, 2013 at 04:08

i am currently using the above program you wrote and using pin D14 i am driving the motor's pwm, the ground for the both motor and the board is common and the output at the programmed pins is a constant 2.94V.

I erased the program from the chip, took voltage readings and found that the pins used for the output are giving constant 2.94 V when programmed and a 1.5 V when there is no program in the memory.
Posted on October 05, 2013 at 04:25

I'd probably use the debugger, and confirm the code is actually running. Perhaps you could also toggle an LED, or otherwise indicate that initialization has completed.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..