STM32F0使用LL库实现PWM输出

在本次项目中,限于空间要求我们选用了STM32F030F4作为控制芯片。这款MCU不但封装紧凑,而且自带的Flash空间也非常有限,所以我们选择了LL库实现。本文我们将说明如何通过LL库实现PWM信号的输出。

1、概述

我们知道STM32的TIM计时器可以输出PWM信号,这测我们也采用STM32F030F4中的TIM3通用计时器来实现我们想要的功能。TIM3通用计时器由一个16位的自动重新加载计数器组成,由一个可编程的预定标器驱动。其结构如下图所示:

它可以用于各种目的,包括测量输入信号的脉冲长度(输入捕获)或生成输出波形(输出比较和PWM)。使用定时器预标量和RCC时钟控制器预标量,输出的PWM脉冲长度和波形周期可以调整从几微秒到几毫秒。我们这里实现一个占空比0%到100%可调,频率为200Hz的PWM波形。

2、TIM配置

我们在使用TIM3输出PWM波,我们必须对其进行相应的配置。关于TIM3的配置我们需要关注:TIM3控制寄存器1 (TIM3_CR1)、TIM3预置寄存器(TIM3_PSC)、TIM3自动重载寄存器(TIM3_ARR)以及对应通道的捕获比较寄存器。

首先来看一看TIM3控制寄存器1 (TIM3_CR1),这个寄存器用于配置TIM计时器。其结构如下:

对于TIM3控制寄存器1 (TIM3_CR1)我们主要需要说一下计数器使能(CEN)位。而其它的位通过初始化函数设置就可以了。

TIM3预置寄存器(TIM3_PSC)用以配置TIM计数器的工作频率,这个工作频率的计算是:psc的工作频率/(psc的值+1)。其结构如下:

TIM3自动重载寄存器(TIM3_ARR)用以配置输出PWM波的频率或者说周期。因为这个值就是计数器的计数周期。其结构如下:

我们设置了技术器的时钟频率,计数的周期,要想得到PWM波,我们还需要告诉TIM一个占空比。关于占空比实际上是在捕获比较寄存器中设置的。

3、PWM实现

我们已经如何通过配置TIM得到PWM波形输出,我们接下来就是通过软件来实现我们的想法。其配置代码如下:

/* TIM3 初始化配置 */
static void TIM3_Init_Configuration(void)
{
  LL_TIM_InitTypeDef TIM_InitStruct = {0};
  LL_TIM_OC_InitTypeDef TIM_OC_InitStruct = {0};

  LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* TIM3时钟使能 */
  LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM3);

  /* TIM3初始化配置 */
  TIM_InitStruct.Prescaler = 47;
  TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
  TIM_InitStruct.Autoreload = TIMPERIOD;
  TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
  LL_TIM_Init(TIM3, &TIM_InitStruct);
  LL_TIM_DisableARRPreload(TIM3);
  LL_TIM_OC_EnablePreload(TIM3, LL_TIM_CHANNEL_CH4);
  TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_PWM1;
  TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_DISABLE;
  TIM_OC_InitStruct.OCNState = LL_TIM_OCSTATE_DISABLE;
  TIM_OC_InitStruct.CompareValue = 0;
  TIM_OC_InitStruct.OCPolarity = LL_TIM_OCPOLARITY_HIGH;
  LL_TIM_OC_Init(TIM3, LL_TIM_CHANNEL_CH4, &TIM_OC_InitStruct);
  LL_TIM_OC_DisableFast(TIM3, LL_TIM_CHANNEL_CH4);
  LL_TIM_SetTriggerOutput(TIM3, LL_TIM_TRGO_RESET);
  LL_TIM_DisableMasterSlaveMode(TIM3);

  /* TIM使用GPIO时钟使能 */
  LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOB);
  
  /* TIM3 GPIO配置:PB1   ------> TIM3_CH4 */
  GPIO_InitStruct.Pin = LL_GPIO_PIN_1;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
  GPIO_InitStruct.Alternate = LL_GPIO_AF_1;
  LL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  LL_TIM_CC_EnableChannel(TIM3,LL_TIM_CHANNEL_CH4);
  LL_TIM_EnableCounter(TIM3);
}

在这段配置代码中,有几个值需要说一下。Prescaler 值我们设为47,所以在48MHz的系统时钟下,TIM计数器的工作频率就是1MHz。Autoreload 的值我们设为了5000,所以可以得到PWM的频率为200Hz。CompareValue值设为了0,所以我们只能得到占空比为0%的PWM。若我们想要得到占空比为50%的PWM,则CompareValue值应设为2500才行。配置完成后各寄存器的值如下图所示:

这要得到的只是固定占空比的PWM波,若想动态修改占空比则需要修改捕获比较寄存器的值。使用函数LL_TIM_OC_SetCompareCH4(TIM3,pulse)就可以了,其中pulse是处于0到Autoreload 的值的整数。

4、总结

我们通过上述操作,就实现了基于LL库的PWM波的输出。我们将代码下载到目标板,并修改占空比和监视器波形输出。

上图是占空比为50%的波形图。

上图是占空比为20%的波形图。

上图是占空比为80%的波形图。

欢迎关注:

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要在STM32F401上使用LL编写PWM控制舵机的话,你需要按照以下步骤进行操作: 1. 配置GPIO引脚作为PWM输出引脚。选择一个合适的引脚,通常使用定时器的通道来生成PWM信号。例如,你可以选择使用TIM4的CH1引脚(PA6)。 2. 初始化定时器。使用LL的函数来初始化定时器,选择合适的时钟源和预分频器,以及设置计数器的自动重载值。 3. 配置PWM模式。选择PWM模式,设置PWM信号的极性(正向或反向),以及设置占空比。 4. 配置输出比较模式。使用LL的函数来配置输出比较模式,以及设置比较值。 5. 启动定时器。使用LL的函数来启动定时器,开始产生PWM信号。 下面是一个示例代码,说明如何使用LLSTM32F401上控制舵机的PWM信号: ```c #include "stm32f4xx_ll_bus.h" #include "stm32f4xx_ll_gpio.h" #include "stm32f4xx_ll_tim.h" void PWM_Init(void) { // 使能GPIOA时钟 LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA); // 配置PA6引脚为复用功能 LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_6, LL_GPIO_MODE_ALTERNATE); LL_GPIO_SetPinOutputType(GPIOA, LL_GPIO_PIN_6, LL_GPIO_OUTPUT_PUSHPULL); LL_GPIO_SetPinSpeed(GPIOA, LL_GPIO_PIN_6, LL_GPIO_SPEED_FREQ_HIGH); LL_GPIO_SetAFPin_0_7(GPIOA, LL_GPIO_PIN_6, LL_GPIO_AF_2); // 使能TIM4时钟 LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM4); // 配置定时器预分频器 LL_TIM_SetPrescaler(TIM4, 83); // 84MHz / (83+1) = 1MHz // 配置自动重载值 LL_TIM_SetAutoReload(TIM4, 1999); // 1MHz / (1999+1) = 500Hz // 配置PWM模式 LL_TIM_OC_SetMode(TIM4, LL_TIM_CHANNEL_CH1, LL_TIM_OCMODE_PWM1); LL_TIM_OC_SetPolarity(TIM4, LL_TIM_CHANNEL_CH1, LL_TIM_OCPOLARITY_HIGH); // 配置输出比较模式和比较值 LL_TIM_OC_ConfigOutput(TIM4, LL_TIM_CHANNEL_CH1, LL_TIM_OCPOLARITY_HIGH | LL_TIM_OCPOLARITY_LOW); LL_TIM_OC_SetCompareCH1(TIM4, 1500); // 设置初始占空比为1500 // 启动定时器 LL_TIM_EnableCounter(TIM4); // 启动输出比较通道 LL_TIM_CC_EnableChannel(TIM4, LL_TIM_CHANNEL_CH1); } ``` 上面的代码初始化了TIM4定时器和PA6引脚用于PWM输出。然后,你可以使用LL_TIM_OC_SetCompareCH1函数来改变舵机的占空比,从而控制舵机的位置。 请根据你的具体需求进行适当的修改和调整。希望对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值