0
\$\begingroup\$

I'm trying to just get timer based PWM output working on the F103 Nucleo board and I can't get the MCU to output anything. I spent a decent amount of time looking through the examples in the related questions relating to the F4 and F0 MCUs, but couldn't find an answer there. My code originally came from the CubeMX tool, but I changed the name of the PWM_MspInit function to match the function that HAL_TIM_PWM_INIT() calls.

My timer initialization and PWM inialization fuctions look like this:

/* TIM3 init function */
static void MX_TIM3_Init(void) {
 TIM_ClockConfigTypeDef sClockSourceConfig;
 TIM_MasterConfigTypeDef sMasterConfig;
 TIM_OC_InitTypeDef sConfigOC;
 htim3.Instance = TIM3;
 htim3.Init.Prescaler = 6400-1;
 htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
 htim3.Init.Period = 10000-1;
 htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
 HAL_TIM_PWM_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 = 1000-1;
 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_PWM_Start(&htim3,TIM_CHANNEL_ALL);
}
void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim) {
 GPIO_InitTypeDef GPIO_InitStruct;
 if (htim->Instance == TIM3) {
 __HAL_RCC_GPIOA_CLK_ENABLE();
 __HAL_RCC_GPIOB_CLK_ENABLE();
 //Configure GPIO pins : PA6 PA7
 GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 //Configure GPIO pins : PB0 PB1
 GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 }
}

Then my main() looks like this:

int main(void) {
 // Reset of all peripherals, Initializes the Flash interface and the Systick. */
 HAL_Init();
 // Configure the system clock
 SystemClock_Config();
 // Initialize all configured peripherals
 MX_TIM3_Init();
 // Infinite loop
 while (1) {
 }
}

The only part of my main.c not shown is the unmodified SystemClock_Config() function that CubeMX produced. To my understanding because of the 64MHz system clock this should produce a 1Hz PWM signal with a 10% duty cycle. When I probe PA6 or PA7 I get nothing.

asked Mar 20, 2018 at 2:37
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Did you forget to configure the peripheral bus clocks themselves? Did you forget to enable clock to the timer before configuring it? \$\endgroup\$ Commented Mar 20, 2018 at 2:48
  • 1
    \$\begingroup\$ Why did you change de MSP init name? The HAL calls the function as it was originally declared. Indeed you see nothing because your PA6 and 7 pins are not initialized at all. \$\endgroup\$ Commented Mar 20, 2018 at 6:50

1 Answer 1

1
\$\begingroup\$

There are two obvious problems that I could see with your code!

  1. You have not clearly mentioned how you have changed the name of HAL_TIM_PWM_MspInit() to HAL_TIM_PWM_Init() but I am assuming you have directly changed the function name in the stm32f1xx_hal_msp.c file. That could be the main mistake! Because both of them are different functions and does different initializations.

HAL_TIM_PWM_MspInit() initializes the Timer clock and HAL_TIM_PWM_Init() initializes the TIM PWM Time base according to the configurations given.

  1. You are skipping two important things in the timer configuration. One is HAL_TIM_MspPostInit() function which initializes the TIMER GPIO pins and the other is "AutoReloadPreload" has to be enabled!

    htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; HAL_TIM_MspPostInit(&htim3)

answered Mar 20, 2018 at 7:54
\$\endgroup\$
2
  • \$\begingroup\$ I went back to cubeMX and enabled AUTORELOAD. Thanks to you I understand that there should be 3 init() functions so I didn't modify the generated functions. I would post my new MX_TIM3_Init() but it's too long for a comment. The only thing I changed from the CubeMX output is to add HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1); right before the while(1) loop. I checked and PA6 is initialized in HAL_TIM_MspPostInit(). __HAL_RCC_TIM3_CLK_ENABLE() is called as well as __HAL_RCC_GPIOA_CLK_ENABLE() and __HAL_RCC_GPIOB_CLK_ENABLE(). I still have nothing on the output. What did I miss. \$\endgroup\$ Commented Mar 20, 2018 at 22:09
  • \$\begingroup\$ Success! I just needed to add HAL_TIM_Base_Start(&htim3); before the while(1). \$\endgroup\$ Commented Mar 20, 2018 at 22:39

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.