STM32定时器PWM概述

在嵌入式系统开发中,控制LED的亮度或电机的速度等模拟控制任务常常需要使用PWM(脉冲宽度调制)技术。STM32微控制器提供了强大的定时器功能,可以方便地生成PWM信号。本文将详细介绍如何在STM32上配置定时器的PWM输出。

定时器与引脚映射

STM32的定时器具有多个通道,每个通道都可以输出PWM信号。但是,并非所有的GPIO引脚都可以用于所有定时器的通道。每个定时器通道通常只能映射到一组特定的引脚上,这些引脚被称为复用功能(Alternate Function,AF)引脚。

如何确定引脚与定时器通道的映射关系?

  1. 查看数据手册:STM32的数据手册会详细列出每个定时器通道可以映射到哪些引脚。通常,这些信息会在引脚定义和复用功能章节中给出。

  2. 使用STM32CubeMX工具:STM32CubeMX是一个图形化配置工具,可以用来配置STM32的外设。通过这个工具,你可以直观地选择定时器和对应的通道,

配置TIM通道的PWM输出

假设我们使用STM32F103RCT6微控制器,并希望配置TIM3的通道2输出PWM信号,因为我的LED是这个TIM通道,按自己的来更改。以下是配置过程的详细步骤:

1. 使能时钟

首先,需要使能定时器和GPIO端口的时钟。

1
2
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); // 使能TIM3时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // 使能GPIOB时钟

2. GPIO配置

接下来,配置GPIO端口的引脚为复用推挽输出模式。在这个例子中,我们使用TIM3的通道2,对应的GPIO引脚是PB5。

1
2
3
4
5
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; // PB5
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // IO口速度为50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); // 初始化GPIOB.5

3. 定时器基本配置

在配置PWM之前,需要对定时器进行基本的配置,包括预分频器、计数模式、自动重装载值等。

1
2
3
4
5
6
7
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Prescaler = 71; // 预分频器值
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // 向上计数模式
TIM_TimeBaseStructure.TIM_Period = 499; // 自动重装载值
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; // 时钟分频
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

4. PWM模式配置

现在,我们可以配置定时器的PWM模式。这包括设置PWM模式、输出状态、占空比、输出极性等。

1
2
3
4
5
6
7
8
9
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; // PWM模式1
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // 使能输出
TIM_OCInitStructure.TIM_Pulse = 0; // 初始占空比
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; // 输出极性高
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; // 空闲状态
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; // 互补空闲状态
TIM_OC2Init(TIM3, &TIM_OCInitStructure); // 配置TIM3通道2为PWM模式
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); // 使能TIM3通道2的预装载寄存器

5. 启动PWM

最后,启动定时器,PWM信号就会出现在配置好的引脚上。

1
TIM_Cmd(TIM3, ENABLE); // 使能TIM3

注意:需要写对对应的TIM和对应的通道,不然可能无效,如果不行,可以使用STM32CubeMX工具来找。

完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include "stm32f10x.h"
#include "stm32f10x_tim.h"
#include "delay.h"

void PWM_Init(void)
{
/*开启时钟*/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //开启TIM3的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //开启GPIOB的时钟

/*GPIO初始化*/
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; // PB5对应TIM3的通道2
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure); //将PB5引脚初始化为复用推挽输出

// 定时器初始化
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Prescaler = 71; // 预分频器
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // 向上计数模式
TIM_TimeBaseStructure.TIM_Period = 499; // 自动重装载值
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; // 时钟分频
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

// 使能定时器3
TIM_Cmd(TIM3, ENABLE);

// PWM模式配置
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; // PWM模式1
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // 使能输出
TIM_OCInitStructure.TIM_Pulse = 0; // 初始占空比
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; // 互补空闲状态

// 配置TIM3通道2
TIM_OC2Init(TIM3, &TIM_OCInitStructure);

// 使能TIM3通道2的预装载寄存器
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
}



void PWM_SetCompare(uint16_t Compare)
{
TIM_SetCompare2(TIM3, Compare); //设置CCR3的值
}

int main(void) {
PWM_Init();
uint16_t value = 0;
while(1) {
while(value < 500) {
value++;
PWM_SetCompare(value);
delay_ms(2);
}

while(value) {
value--;
PWM_SetCompare(value);
delay_ms(2);
}
delay_ms(200);
}
}

通过以上步骤,您已经成功配置了STM32的定时器TIM3的通道2,使其输出PWM信号到PB5引脚。通过调整TIM_OCInitStructure.TIM_Pulse的值,您可以改变PWM的占空比,从而控制连接到该引脚的LED的亮度。


本站由 Natuie 使用 Stellar 1.26.8 主题创建。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。

本站总访问量次 | 本站总访客数人次
载入天数...载入时分秒...