Using the Blue pill STM32F103 and libopencm3, I am using timer 1 to output a PWM signal onto PA8 and toggle the on board LED PC13. However this does not work. What have I done wrong in my code?
I can confirm that the timer is running at the correct frequency (scaled down to 24Hz) by toggling the LED in the interrupt. It is also counting to the correct value.
#include <stdlib.h>
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/usb/usbd.h>
#include <libopencm3/usb/cdc.h>
#include <libopencm3/stm32/timer.h>
#include <libopencm3/cm3/nvic.h>
void tim1_cc_isr(){
timer_clear_flag(TIM1, TIM_SR_CC1IF);
gpio_toggle(GPIOC, GPIO13);
}
int main(void)
{
unsigned int i;
// Initialize the master clock
rcc_clock_setup_in_hse_8mhz_out_72mhz();
rcc_periph_clock_enable(RCC_GPIOA);
rcc_periph_clock_enable(RCC_GPIOC);
gpio_set(GPIOC, GPIO13);
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO13);
// Timer clocks
rcc_periph_clock_enable(RCC_AFIO);
rcc_periph_clock_enable(RCC_TIM1);
timer_set_mode(TIM1, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_CENTER_1,
TIM_CR1_DIR_UP);
timer_enable_oc_output(TIM1, TIM_OC1);
timer_set_oc_mode(TIM1, TIM_OC1, TIM_OCM_PWM1);
timer_set_oc_polarity_low(TIM1, TIM_OC1);
gpio_set_mode(GPIO_BANK_TIM1_CH1,
GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_TIM1_CH1);
// Set Period
timer_set_prescaler(TIM1, 1000);
// Count to 750 for 24Hz
timer_set_period(TIM1, 750);
timer_clear_flag(TIM1, TIM_SR_CC1IF);
timer_set_oc_value(TIM1, TIM_OC1, 350);
timer_enable_counter(TIM1);
nvic_enable_irq(NVIC_TIM1_CC_IRQ);
timer_enable_irq(TIM1, TIM_DIER_CC1IE);
while(1){}
}
If timer supports the break functionality (and TIM1
does), then OC/OCN outputs are disabled after the reset. To enable them, set the MOE
bit in the TIMx_BDTR
register. In the libopencm3
this is done by timer_enable_break_main_output
function.