发新帖本帖赏金 30.00元(功能说明)我要提问
12下一页
返回列表
打印
[STM32F4]

使用stm32f4 用一个定时器输出多个不同频率占空比PWM波

[复制链接]
1085|29
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
poison0|  楼主 | 2023-4-6 15:24 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 poison0 于 2023-4-6 15:26 编辑

#申请原创#
使用STM32F4的定时器和GPIO模块来生成多个不同频率和占空比的PWM波。下面是一个基本的步骤:

配置定时器
首先,需要配置STM32F4的定时器,以便能够生成PWM波。我们可以选择使用其中一个通道(Channel)来控制一个GPIO引脚上的PWM波,同时可以使用另一个通道来控制另一个GPIO引脚上的PWM波。

设置计数器和频率
接下来,需要设置计数器和频率。计数器的值越大,PWM波的周期就越长。而频率则决定了PWM波的频率。可以使用定时器的预分频器(Prescalr)和计数器的重载值(Auto Reload Register)来控制这些值。

配置占空比
然后,需要设置PWM波的占空比。可以通过在每个周期的不同阶段改变输出的高电平时间来实现。可以使用定时器的通道寄存器来控制输出引脚的占空比。

启动定时器
最后,需要启动定时器,以便开始生成PWM波。可以通过设置定时器的控制寄存器来启动和停止定时器。

下面是一个示例代码,可以生成两个不同频率和占空比的PWM波:
c
Copy code
#include "stm32f4xx.h"

void timer_pwm_init(void)
{
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  TIM_OCInitTypeDef TIM_OCInitStructure;

  // 使能时钟
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

  // 配置GPIO引脚
  GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_Init(GPIOB, &GPIO_InitStructure);

  GPIO_PinAFConfig(GPIOB, GPIO_PinSource0, GPIO_AF_TIM3);
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource1, GPIO_AF_TIM3);

  // 配置定时器
  TIM_TimeBaseStructure.TIM_Period = 1000 - 1; // 1kHz PWM
  TIM_TimeBaseStructure.TIM_Prescaler = 84 - 1; // 84MHz / 84 = 1MHz
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

  // 配置PWM通道
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = 500; // 50% 占空比
  TIM_OCInitStructure.TIM_O

大部分情况下,使用定时器生成PWM波总结为以下步骤
使用STM32F4的定时器生成PWM波可以分为以下步骤:

时钟使能
在使用定时器之前,需要先使能相应的外设时钟。例如,如果我们要使用定时器3TIM3),则需要使能TIM3的时钟和与之相关的GPIO口的时钟。具体操作可以参考芯片手册或者使用STM32CubeMX生成代码。

配置GPIO引脚
使用定时器生成PWM波需要将定时器的输出连接到GPIO引脚上。因此,需要先配置相应的GPIO引脚为复用模式,并选择定时器的输出映射到这些引脚上。具体操作可以参考芯片手册或者使用STM32CubeMX生成代码。

配置定时器基本参数
在使用定时器生成PWM波之前,需要配置定时器的基本参数,例如时钟分频器、自动重载计数器和计数模式等。这些参数的配置可以通过TIM_TimeBaseInitStruct结构体完成,具体参数的配置可以参考芯片手册或者使用STM32CubeMX生成代码。

配置PWM波的占空比
通过改变PWM波在周期中的高电平时间和低电平时间的比例,可以实现不同的占空比。在STM32F4中,可以使用定时器的比较寄存器(TIMx_CCRx)来控制占空比。具体来说,需要将比较寄存器的值设置为自动重载计数器值的一定比例,即可实现相应的占空比。

启动定时器
配置好定时器的参数之后,需要启动定时器,使其开始工作并输出PWM波。启动定时器可以通过设置TIMx_CR1寄存器中的CEN位来实现,其中CEN表示计数器使能。

下面是一个简单的代码示例,演示如何使用STM32F4的定时器生成PWM波:
c
Copy code
#include "stm32f4xx.h"

void TIM_Config(void)
{
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  TIM_OCInitTypeDef TIM_OCInitStructure;

  // 使能时钟
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);

  // 配置GPIO引脚
  GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_Init(GPIOC, &GPIO_InitStructure);

  GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_TIM3);

  // 配置定时器
  TIM_TimeBaseStructure.TIM_Period = 999; // PWM频率 = 84MHz / (1 + 999) ≈ 84kHz
  TIM_TimeBaseStructure.TIM_Prescaler = 0

修改频率与占空比

要修改PWM波的频率和占空比,需要修改定时器的相关参数,包括定时器的时钟分频、自动重载计数器值、比较寄存器值等。下面是一个简单的示例,演示如何修改PWM波的频率和占空比:
c
Copy code
#include "stm32f4xx.h"

void TIM_Config(void)
{
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  TIM_OCInitTypeDef TIM_OCInitStructure;

  // 使能时钟
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);

  // 配置GPIO引脚
  GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_Init(GPIOC, &GPIO_InitStructure);

  GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_TIM3);

  // 配置定时器
  TIM_TimeBaseStructure.TIM_Period = 999; // PWM频率 = 84MHz / (1 + 999) ≈ 84kHz
  TIM_TimeBaseStructure.TIM_Prescaler = 0;
  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

  // 配置PWM波的占空比
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
  TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
  TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;

  TIM_OCInitStructure.TIM_Pulse = 499; // PWM占空比 = (499+1) / (999+1) ≈ 50%
  TIM_OC1Init(TIM3, &TIM_OCInitStructure);

  // 启动定时器
  TIM_Cmd(TIM3, ENABLE);
}

int main(void)
{
  TIM_Config();

  // 修改PWM波的频率和占空比
  TIM_SetAutoreload(TIM3, 3999); // PWM频率 = 84MHz / (1 + 3999) ≈ 21kHz
  TIM_SetCompare1(TIM3, 1999);   // PWM占空比 = (1999+1) / (3999+1) ≈ 50%

  while (1)
  {
  }
}
在这个示例中,我们首先配置定时器3TIM3)和相应的GPIO引脚,然后使用TIM_TimeBaseInitStruct结构体配置定时器的基本参数和PWM波的占空比。

在启动定时器后,我们使用TIM_SetAutoreload()函数修改定时器的自动重载计数器值、比较寄存器值等。


以上是我在使用stm32f4 用一个定时器输出多个不同频率占空比PWM波的部分步骤和经验,欢迎大家参考,指正。


使用特权

评论回复

打赏榜单

21小跑堂 打赏了 30.00 元 2023-08-25
理由:恭喜通过原创审核!期待您更多的原创作品~

评论
21小跑堂 2023-8-25 18:00 回复TA
以STM32F4为例,详细介绍了定时器输出PWM的配置,每一步的讲解较为详细,若是可以分享调试结果和源码会更好 
沙发
香水城| | 2023-4-7 16:54 | 只看该作者
本帖最后由 香水城 于 2023-4-9 21:54 编辑

一个定时器实现4个不同频率及占空比,是可以。

不过,没看懂你如何实现不同频率的。

基于中断方式固然可以,但有点辛苦,实用性不强。可以考虑DMA加TIMER toggle模式。
一个定时器输出4路不同频率波形的应用示例

使用特权

评论回复
板凳
Pretext| | 2023-4-10 11:46 | 只看该作者
你这是一个引脚输出四个不同频率的占空比?

使用特权

评论回复
地板
朝生| | 2023-4-10 11:46 | 只看该作者
一个定时器,让四个引脚输出不同占空比的PWM吗?

使用特权

评论回复
5
芯路例程| | 2023-4-10 11:47 | 只看该作者
这么做的意义是什么?节省定时器吗?

使用特权

评论回复
6
Bowclad| | 2023-4-10 22:27 | 只看该作者
一个引脚不同的频率

使用特权

评论回复
7
Undshing| | 2023-4-11 21:44 | 只看该作者
同时输出吗?

使用特权

评论回复
8
poison0|  楼主 | 2023-4-18 12:21 | 只看该作者
香水城 发表于 2023-4-7 16:54
一个定时器实现4个不同频率及占空比,是可以。

不过,没看懂你如何实现不同频率的。

香水城版主推荐的文章非常棒,比我写的更有逻辑,确实有点繁琐,不太解释的清楚。我还需要多加学习。感谢!我去学习学习大佬。

使用特权

评论回复
9
poison0|  楼主 | 2023-4-18 12:54 | 只看该作者
Pretext 发表于 2023-4-10 11:46
你这是一个引脚输出四个不同频率的占空比?

一个定时器

使用特权

评论回复
10
poison0|  楼主 | 2023-4-18 12:55 | 只看该作者
芯路例程 发表于 2023-4-10 11:47
这么做的意义是什么?节省定时器吗?

不是为了节省,就是意思它有这个功能。至于最终是因为节省使用,还是因为多路使用那就看使用者了。

使用特权

评论回复
11
51xlf| | 2023-5-5 13:01 | 只看该作者
如果不是通过定时器中断计数,怎么实现的不同频率呢?

使用特权

评论回复
12
mollylawrence| | 2023-5-5 19:00 | 只看该作者
这个是需要多个定时器的吗              

使用特权

评论回复
13
wengh2016| | 2023-5-5 21:59 | 只看该作者
只能输出4中不同占空比吧。              

使用特权

评论回复
14
hilahope| | 2023-5-5 23:20 | 只看该作者
这个比较高端了。              

使用特权

评论回复
15
yeates333| | 2023-5-7 15:11 | 只看该作者
多个不同频率是怎么实现呢              

使用特权

评论回复
16
gygp| | 2023-5-7 17:48 | 只看该作者
不同频率是什么意思              

使用特权

评论回复
17
yorkbarney| | 2023-5-7 18:22 | 只看该作者
可以通过定时器中断实现。              

使用特权

评论回复
18
earlmax| | 2023-5-7 20:05 | 只看该作者
这个同一个定时器怎么实现的              

使用特权

评论回复
19
tpgf| | 2023-5-12 08:18 | 只看该作者
这种情况是不是得考虑使用io口进行模拟了啊

使用特权

评论回复
20
keaibukelian| | 2023-5-12 12:08 | 只看该作者
是一个定时器在同一时间输出不同频率的pwm波?

使用特权

评论回复
发新帖 本帖赏金 30.00元(功能说明)我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

70

主题

615

帖子

2

粉丝