cancel
Showing results for 
Search instead for 
Did you mean: 

Not being able to enable PWM using the HAL TIM library on stm32f0

mt.haak9
Associate
Posted on April 13, 2016 at 11:21

The goal is to use the PWM feature of stm32 HAL TIM libraries to light up 4 leds on pins 0, 1, 4 and 5

I have generated the following code using CubeMX:


void
MX_TIM3_Init(
void
)

{

TIM_ClockConfigTypeDef sClockSourceConfig;

TIM_MasterConfigTypeDef sMasterConfig;

TIM_OC_InitTypeDef sConfigOC;


htim3.Instance = TIM3;

htim3.Init.Prescaler = 32;

htim3.Init.CounterMode = TIM_COUNTERMODE_UP;

htim3.Init.Period = 1000;

htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

HAL_TIM_Base_Init(&htim3);


sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;

HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig);


HAL_TIM_PWM_Init(&htim3);


sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;

sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig);


sConfigOC.OCMode = TIM_OCMODE_PWM1;

sConfigOC.Pulse = 500;

sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1);


HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2);


HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_3);


HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_4);


HAL_TIM_MspPostInit(&htim3);

}

This initiates the timer.


void
HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim)

{


GPIO_InitTypeDef GPIO_InitStruct;

if
(htim->Instance==TIM3)

{

/* USER CODE BEGIN TIM3_MspPostInit 0 */


/* USER CODE END TIM3_MspPostInit 0 */


/**TIM3 GPIO Configuration 

PB0 ------> TIM3_CH3

PB1 ------> TIM3_CH4

PB4 ------> TIM3_CH1

PB5 ------> TIM3_CH2 

*/

GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5;

GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

GPIO_InitStruct.Pull = GPIO_NOPULL;

GPIO_InitStruct.Speed = GPIO_SPEED_LOW;

GPIO_InitStruct.Alternate = GPIO_AF1_TIM3;

HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);


/* USER CODE BEGIN TIM3_MspPostInit 1 */


/* USER CODE END TIM3_MspPostInit 1 */

}

}

This initiates the GPIO pins for pwm.

Also the clock is enabled in theHAL_TIM_Base_MspInit callback function using__TIM3_CLK_ENABLE(). In the main.c file I have added the following code after all initializations, to start the base timer and pwm:

1.
HAL_TIM_Base_Start(&htim3); 
2.
HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_ALL);

Now after running this code on the stm32f070cb the leds do not light up at least slightly. I have tried changing the compare values CCRx. Also the GPIO pins work since I can use HAL_GPIO_WritePin to turn on the leds. Did someone have a similar problem or have some hints to go from here? #stm32f0-hal-cube-tim-pwm
5 REPLIES 5
Nesrine M_O
Lead II
Posted on April 13, 2016 at 12:34

Hi th.martin,

I recommend you to have a look to the TIM_PWMOutput example under the STM32F0 cube firmware package it may be helpful: 

STM32Cube_FW_F0_V1.5.0\Projects\STM32F0308Discovery\Examples\TIM\TIM_PWMOutput

-Syrine –
mt.haak9
Associate
Posted on April 13, 2016 at 14:07

Thank you very much Syrine that was a great suggestion!

Got the example working now. I was unaware of the existence of those examples for the stm32f0 series.. Now I can find out what is different from my own code.

Md Mubdiul Hasan
Associate III
Posted on October 14, 2016 at 06:27

Dear Sir,

I have same problem, let me know how to add this pwm in GPIO?

Katzenberger.Michael
Associate III
Posted on April 29, 2017 at 16:23

Stumbled over a similar issue.

The problem is that the definition of TIM_CHANNEL_ALL is not working with HAL_TIM_PWM_Start() (and maybe other functions)

 /* USER CODE BEGIN 2 */
 HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_ALL);
 /* USER CODE END 2 */�?�?�?�?�?�?

you need to enable each PWM channel explicitly:

 /* USER CODE BEGIN 2 */
 HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
 HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);
 HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3);
 HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_4);
 /* USER CODE END 2 */�?�?�?�?�?�?�?�?�?�?�?�?

The macro IS_TIM_CCX_INSTANCE() is not detecting the unsupported value TIM_CHANNEL_ALL ...

HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel)
{
 /* Check the parameters */
 assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));�?�?�?�?�?�?�?�?

jaessy77
Associate

Hi,

TIM_CHANNEL_ALL can't really work with the HAL.

Reason:

If you take TIM_CHANNEL_ALL, this is nothing other than

TIM_CHANNEL_ALL = TIM_CHANNEL_1 | TIM_CHANNEL_2 | TIM_CHANNEL_3 | TIM_CHANNEL_4

what results in

0x0018 = 0x0000 | 0x0004 | 0x008 | 0x000C

The function HAL_TIM_PWM_Start() calls TIM_CCxChannelCmd() and there the fatal error begins in the HAL ...

void TIM_CCxChannelCmd(TIM_TypeDef* TIMx, uint32_t Channel, uint32_t ChannelState)

{

...

tmp = TIM_CCER_CC1E << Channel;

...

}

If you apply either 0x0000 or 0x0004 or ox0008 or 0x000C the correct bit in CCER - Registers is set.

If you apply 0x0018 what is 24 in decimal, you try to set the 24th bit in the upper region of the 32 bit register which is not used (better reserved). CCER is only using the lower 16 bits ...

 0690X000006Bx4XQAS.png

Solution: 

If you use f.e. the TIM3, the following is fully working:

...

MX_TIM3_Init(); // If you use CubeMx

...

/* USER CODE BEGIN 2 */

HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);

HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);

HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_3);

HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_4);

...

Remark:

I also trapped in .. would be nice if the compiler could catch such failures .. or better: if the HAL itself would be able to catch this without having the assertion (assert_param) on.