Blackpill STM32F411CEU6-带有libopencm3的PWM不工作



我正在尝试让PWM与计时器3一起工作,我已经遵循了参考手册,相信我一切都是正确的,但我没有得到任何输出。

我的代码在下面,我一定遗漏了什么

rcc_periph_clock_enable(RCC_GPIOB);
gpio_mode_setup(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE,
GPIO0 | GPIO4 | GPIO5);
gpio_set_output_options(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,
GPIO0 | GPIO4 | GPIO5);
gpio_set_af(GPIOB, GPIO_AF2, GPIO0 | GPIO4 | GPIO5);
rcc_periph_clock_enable(RCC_TIM3);
timer_set_mode(TIM3, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
timer_set_prescaler(TIM3, 50000000 / 125000 - 1);
timer_enable_preload(TIM3);
timer_enable_oc_preload(TIM3, TIM_OC1);
timer_set_period(TIM3, 0xffff);
timer_enable_oc_output(TIM3, TIM_OC1);
timer_set_oc_mode(TIM3, TIM_OC1, TIM_OCM_PWM2);
// timer_set_oc_mode(TIM3, TIM_OC2, TIM_OCM_PWM2);
// timer_set_oc_mode(TIM3, TIM_OC3, TIM_OCM_PWM2);
timer_set_oc_value(TIM3, TIM_OC1, 0x7fff);
timer_enable_update_event(TIM3);
timer_generate_event(TIM3, TIM_EGR_UG);
timer_enable_counter(TIM3);

需要记住的几件事:

  • gpio_mode_setup((应使用gpio_mode_AF,而不是gpio_mode_OUTPUT
  • 有些计时器只使用16位计数器,有些是32位计数器。仔细检查计时器是否合适
  • 不同的引脚允许定时器、通道和备用功能编号的各种组合。检查数据表以确保使用正确的值

这里有一个例子,使用stm32f411re:上的TIM5将400Hz的频率、25%的占空比输出到PA0

#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/timer.h>
#include <libopencm3/cm3/nvic.h>
// PA0 TIM5_CH1. AF2

const uint32_t timer_peri = TIM5; // timer peripheral
const enum tim_oc_id oc_id = TIM_OC1; // output compare channel designator
int main(void)
{
// setup PA0 for PWM
rcc_periph_clock_enable(RCC_GPIOA);
rcc_periph_clock_enable(RCC_TIM5); // enable TIM clock
gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO0); // pin PA11 Alt Function
gpio_set_af(GPIOA, GPIO_AF2, GPIO0);
int freq = 400;
timer_set_prescaler(timer_peri, 16-1); // s/b 1MHz
int period = 1000000/freq; // assumes prescaled set to 1MHz
timer_enable_preload(timer_peri); // causes counter to be loaded from its ARR only at next update event
timer_set_period(timer_peri, period); // set the timer period in the (ARR) auto-reload register
timer_set_oc_value(timer_peri, oc_id, period * 1/4); // set duty cycle to 25%
timer_set_counter(timer_peri, 0); // TIM_CNT

timer_enable_oc_preload(timer_peri, oc_id);
timer_set_oc_mode(timer_peri, oc_id, TIM_OCM_PWM1); // output active when counter is lt compare register
timer_enable_oc_output(timer_peri, oc_id); // enable timer output compare
timer_continuous_mode(timer_peri); // enable the timer to run continuously
timer_generate_event(timer_peri, TIM_EGR_UG); // required!
timer_enable_counter(timer_peri);
//timer_enable_irq(timer_peri, TIM_DIER_COMIE);  //enable commutation interrupt
//nvic_enable_irq(NVIC_TIM1_CC_IRQ);
while (1);
}

根据您的需要进行调整。

最新更新