13.5 通用定时器项目:旋转编码器控制LED亮度
# 13.5 通用定时器项目:旋转编码器控制LED亮度
本实验通过STM32的TIM2定时器(编码器模式)读取旋转编码器信号,结合TIM3的PWM输出,实现LED亮度调节与颜色切换功能。
核心功能:
- 编码器计数:旋转编码器调节PWM占空比(0~100),控制LED亮度。
- 按键切换:按下编码器按键切换红、绿、蓝三色LED通道。
- OLED显示:实时显示当前计数值(Encoder_cnt)。
# 13.5.1 硬件电路设计
# 旋转编码器连接
- 引脚分配:
- A相(TIM2_CH1) → PA15
- B相(TIM2_CH2) → PB3
- 按键(KEY) → PB4(内部上拉)
- 滤波电路:C20、C22、C27用于抑制信号抖动,R15、R19为上拉电阻。

# 13.5.2 STM32CubeMX配置
# 1. 工程基础配置
- 芯片型号:STM32F103C8T6
- 主频:72MHz
- 调试接口:SWD
# 2. TIM2编码器模式配置
- 模式选择:Encoder Mode TI1(仅在通道1边沿计数)。
- 参数设置:
- 预分频器(PSC):2-1 → 时钟频率36MHz
- 输入滤波(Filter):15(抑制噪声)
- 极性:
- 通道1(Rising Edge)
- 通道2(Falling Edge)

# 3. TIM3 PWM模式配置
- 通道:TIM3_CH2(PA7)、TIM3_CH3(PB0)、TIM3_CH4(PB1)。
- 参数:
- 预分频器(PSC):720-1 → PWM频率100Hz
- 自动重装载值(ARR):100-1 → 占空比范围0%~100%

# 13.5.3 软件设计
# 1. TIM2初始化(代码清单13‑6)
static void MX_TIM2_Init(void) {
htim2.Instance = TIM2;
htim2.Init.Prescaler = 2-1; // 预分频2,时钟36MHz
htim2.Init.Period = 65535; // 计数器最大值(16位)
TIM_Encoder_InitTypeDef sConfig = {
.EncoderMode = TIM_ENCODERMODE_TI1, // 编码器模式TI1
.IC1Polarity = TIM_ICPOLARITY_RISING,
.IC2Polarity = TIM_ICPOLARITY_FALLING, // 通道2极性反向
.IC1Filter = 15, // 输入滤波
.IC2Filter = 15
};
HAL_TIM_Encoder_Init(&htim2, &sConfig); // 初始化编码器
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 2. 主循环逻辑(代码清单13‑7)
int Encoder_cnt = 0; // 编码器计数值
int Channel_index = 0; // 当前PWM通道索引
uint32_t Channels[3] = {TIM_CHANNEL_2, TIM_CHANNEL_3, TIM_CHANNEL_4};
int main(void) {
// 初始化外设
HAL_Init();
MX_GPIO_Init();
MX_TIM2_Init();
MX_TIM3_Init();
MX_I2C1_Init();
OLED_Init();
HAL_TIM_Encoder_Start(&htim2, TIM_CHANNEL_ALL); // 启动编码器
HAL_TIM_PWM_Start(&htim3, Channels[Channel_index]); // 启动PWM
while (1) {
Encoder_cnt = __HAL_TIM_GET_COUNTER(&htim2); // 读取计数值
// 限制计数值范围0~100
if (Encoder_cnt > 100) {
Encoder_cnt = 100;
__HAL_TIM_SET_COUNTER(&htim2, 100);
}
// 按键检测:切换LED颜色
if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_4) == GPIO_PIN_RESET) {
HAL_Delay(10); // 消抖
if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_4) == GPIO_PIN_RESET) {
HAL_TIM_PWM_Stop(&htim3, Channels[Channel_index]);
Channel_index = (Channel_index + 1) % 3; // 切换通道
HAL_TIM_PWM_Start(&htim3, Channels[Channel_index]);
}
while (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_4) == GPIO_PIN_RESET);
}
// 更新PWM占空比
__HAL_TIM_SET_COMPARE(&htim3, Channels[Channel_index], Encoder_cnt);
// OLED显示计数值
sprintf(message, "Encoder_cnt:%d", Encoder_cnt);
OLED_NewFrame();
OLED_PrintString(1, 1, message, &font16x16, OLED_COLOR_NORMAL);
OLED_ShowFrame();
}
}
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
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
# 13.5.4 下载验证
# 现象与步骤
- 烧录程序:通过ST-LINK下载代码至开发板。
- 功能验证:
- 旋转编码器:顺时针旋转增加
Encoder_cnt
,逆时针减少(范围0~100)。 - LED亮度:计数值越大,当前通道LED越亮。
- 按键切换:按下按键切换红、绿、蓝三色LED通道。
- 旋转编码器:顺时针旋转增加
- OLED显示:实时显示当前计数值(如
Encoder_cnt:77
)。

关键说明:
- 编码器计数方向:通过设置通道2极性为
Falling Edge
,确保顺时针旋转时计数值递增。 - 占空比映射:
Encoder_cnt
直接映射为PWM的CCR值,范围0~100对应亮度0%~100%。 - 消抖逻辑:按键检测加入10ms延时,避免误触发。