1
\$\begingroup\$

I use a STM32F103C8T6 with libopencm3 and I'm trying to get timer 1 on channel 3 (PA10) working. The datasheet (pg. 31) lists as alternate function for PA10 (pin #31): USART1_RX / TIM1_CH3.

Based on this and on some code snippets I created this minimal example (placed inside the main):

    rcc_clock_setup_in_hse_8mhz_out_72mhz();

    /* Enable TIM1 clock. */
    rcc_periph_clock_enable(RCC_TIM1);

    /* Enable GPIOC, Alternate Function clocks. */
    rcc_periph_clock_enable(RCC_GPIOA);
    rcc_periph_clock_enable(RCC_GPIOB);
    rcc_periph_clock_enable(RCC_AFIO);
    
    /* Enable outputs */
    gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_TIM1_CH3);
    gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_TIM1_CH1);

    /* Configure ... */
    timer_set_mode(TIM1, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
    timer_set_prescaler(TIM1, 2);
    timer_set_period(TIM1, 48000);
    timer_disable_preload(TIM1);
    timer_continuous_mode(TIM1);
    timer_set_oc_mode(TIM1, TIM_OC3, TIM_OCM_PWM1);
    timer_set_oc_value(TIM1, TIM_OC3, 24000);
    timer_enable_oc_output(TIM1, TIM_OC3);
    timer_enable_counter(TIM1);

But nothing happens on PA10. I tried also TIM1_CH2 (PA9 / TIM_OC2) & TIM1_CH1 (PA8 / TIM_OC1) without anything.

But when I change in the exact code shown TIM1 --> TIM3 (literally this string) and enable AF output on GPIO_TIM3_CH3 (PB0) a PWM square wave is produced as expected.

So the code should be correct or timer 1 is special - but I could not find anything in the datasheet.

Unfortunately I can't change the pin, I have PA10 dedicated to the PWM functionality already. Any ideas how to resolve this?

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

I've not used libopencm3 but when using the advanced timers there is some extra initialisation required for the break and dead-time functionality. Specifically, you have to enable the outputs by setting the MOE bit in the BDTR register.

Although I am not familiar with libopencm3, it looks from your code that this bit of initialisation is not being done.

The STM32 documentation does not make it plainly obvious that this initialisation is required, although it is there if you dig deep enough. Here is an example:

STM32 relevant documentation

If using the standard STM32 LL, the MOE bit can be set as follows:

LL_TIM_EnableAllOutputs(TIM1);  // Set MOE bit of BDTR (otherwise no output)

I have added a working project, using the standard STM32 LL library, on DevOps. You can take a look at it here. The project in this repo is called TIM_PWM_LL_BJH. It will build and run on a NUCLEO-G431RB and will output PWM on TIM1_CH3 using PA10. It could easily be adapted for another NUCLEO board, since it uses the abstract LL interfaces.

\$\endgroup\$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.