STM32智能风扇实战:PWM调速与OLED显示嵌入式开发指南
2026/7/17 19:56:30 网站建设 项目流程

这次我们来做一个基于STM32的智能定时风扇项目。这个设计结合了STM32微控制器、OLED显示屏和PWM调速技术,能够实现风扇的智能定时控制和无级调速功能。对于想要学习嵌入式系统开发、PWM控制原理以及实际项目应用的开发者来说,这是一个很好的实战案例。

智能定时风扇的核心功能包括:通过STM32的定时器生成PWM信号控制风扇转速,使用OLED显示屏实时显示当前状态和设置参数,支持多档定时设置和手动调速模式。整个系统硬件成本低,代码结构清晰,适合作为STM32入门到进阶的练习项目。

1. 核心能力速览

能力项说明
主控芯片STM32F103C8T6(兼容其他STM32F1系列)
显示模块0.96寸OLED显示屏(I2C接口)
调速方式PWM无级调速(支持4线风扇)
定时功能多档可调定时(1-120分钟)
控制方式按键输入+旋转编码器
开发环境Keil MDK-ARM + STM32CubeMX
供电要求5V/2A电源适配器
适合场景学习PWM控制、嵌入式UI设计、定时器应用

2. 适用场景与使用边界

这个智能定时风扇项目主要适合以下场景:

学习应用场景

  • STM32入门开发者学习GPIO、定时器、PWM、I2C等外设使用
  • 嵌入式UI设计实践,掌握OLED菜单显示和用户交互
  • PWM控制原理的实际应用,理解占空比与转速关系
  • 定时器中断编程,实现精准的时间控制

实际使用场景

  • 桌面小风扇的智能控制
  • 需要定时关闭的通风设备
  • 实验室环境的风速可调装置
  • 物联网设备的原型验证

使用边界提醒

  • 本项目驱动的是小型直流风扇(通常5-12V),不能直接控制大功率电机
  • OLED显示在强光下可视性较差,适合室内使用
  • 定时精度受STM32内部时钟精度影响,需要高精度定时时应使用外部晶振
  • PWM频率需要匹配风扇电机特性,过高或过低都可能影响控制效果

3. 环境准备与前置条件

3.1 硬件准备清单

核心控制器

  • STM32F103C8T6最小系统板(蓝色药丸板)
  • ST-Link V2调试下载器

显示模块

  • 0.96寸OLED显示屏(SSD1306驱动,I2C接口)
  • 4针I2C接口线(VCC、GND、SCL、SDA)

执行部件

  • 5V或12V直流风扇(建议使用4线PWM风扇)
  • MOSFET驱动模块(如IRF520模块)
  • 散热片(根据风扇功率选配)

输入设备

  • 旋转编码器(带按键功能)
  • 轻触按键(备用方案)

电源系统

  • 5V/2A电源适配器
  • DC电源接口
  • 杜邦线若干

3.2 软件环境准备

开发工具

  • Keil MDK-ARM(建议V5.25以上版本)
  • STM32CubeMX(最新版本)
  • ST-Link Utility(用于固件下载)

驱动安装

  • ST-Link V2驱动程序
  • CH340串口驱动(如需串口调试)

库文件准备

  • STM32F1xx HAL库
  • SSD1306 OLED驱动库
  • 旋转编码器处理库

4. 硬件连接与电路设计

4.1 核心控制器引脚分配

// STM32F103C8T6引脚定义 #define OLED_SDA_PIN GPIO_PIN_7 // PB7 - I2C1 SDA #define OLED_SCL_PIN GPIO_PIN_6 // PB6 - I2C1 SCL #define FAN_PWM_PIN GPIO_PIN_0 // PA0 - TIM2_CH1 #define ENCODER_A_PIN GPIO_PIN_1 // PA1 - 编码器A相 #define ENCODER_B_PIN GPIO_PIN_2 // PA2 - 编码器B相 #define ENCODER_BTN_PIN GPIO_PIN_3 // PA3 - 编码器按键

4.2 电路连接示意图

电源部分

5V电源 → STM32 VCC (5V) → 风扇正极 → OLED VCC GND → STM32 GND → 风扇负极 → OLED GND → MOSFET源极

信号连接

STM32 PA0 (PWM) → MOSFET栅极 STM32 PB6 (SCL) → OLED SCL STM32 PB7 (SDA) → OLED SDA STM32 PA1,PA2,PA3 → 编码器A,B,按键 MOSFET漏极 → 风扇PWM控制线

4.3 重要注意事项

  1. 电平匹配:STM32是3.3V系统,直接驱动5V OLED需要确认模块支持3.3V
  2. 电流要求:风扇电机启动电流较大,确保电源能提供足够电流
  3. PWM频率:风扇PWM频率通常在25kHz左右,需要设置合适的定时器分频
  4. 滤波电路:在PWM输出端可加入RC滤波,提高信号质量

5. 软件架构与代码实现

5.1 工程结构设计

SmartFan/ ├── Core/ │ ├── Src/ │ │ ├── main.c │ │ ├── stm32f1xx_hal_msp.c │ │ └── stm32f1xx_it.c │ └── Inc/ │ ├── main.h │ └── stm32f1xx_it.h ├── Drivers/ │ └── STM32F1xx_HAL_Driver/ ├── OLED/ │ ├── oled.c │ └── oled.h ├── PWM/ │ ├── pwm.c │ └── pwm.h └── Encoder/ ├── encoder.c └── encoder.h

5.2 核心功能模块代码

PWM初始化配置

// pwm.c void PWM_Init(void) { TIM_HandleTypeDef htim2; TIM_OC_InitTypeDef sConfigOC; // 定时器基础配置 htim2.Instance = TIM2; htim2.Init.Prescaler = 71; // 72MHz/72 = 1MHz htim2.Init.CounterMode = TIM_COUNTERMODE_UP; htim2.Init.Period = 39999; // 1MHz/40000 = 25Hz htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; HAL_TIM_PWM_Init(&htim2); // PWM通道配置 sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = 20000; // 50%占空比 sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1); // 启动PWM HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1); }

OLED显示界面

// oled.c void OLED_ShowFanStatus(uint8_t speed, uint16_t remaining_time, uint8_t mode) { OLED_Clear(); OLED_ShowString(0, 0, "Smart Fan", 16); // 显示转速 OLED_ShowString(0, 2, "Speed:", 16); OLED_ShowNum(48, 2, speed, 3, 16); OLED_ShowString(72, 2, "%", 16); // 显示进度条 OLED_DrawProgressBar(0, 4, speed); // 显示剩余时间 OLED_ShowString(0, 6, "Time:", 16); if(remaining_time > 0) { OLED_ShowNum(40, 6, remaining_time/60, 2, 16); OLED_ShowString(56, 6, "m", 16); OLED_ShowNum(72, 6, remaining_time%60, 2, 16); OLED_ShowString(88, 6, "s", 16); } else { OLED_ShowString(40, 6, "OFF", 16); } }

旋转编码器处理

// encoder.c int8_t Encoder_Scan(void) { static uint8_t last_state = 0; uint8_t current_state = (HAL_GPIO_ReadPin(ENCODER_A_GPIO_Port, ENCODER_A_Pin) << 1) | HAL_GPIO_ReadPin(ENCODER_B_GPIO_Port, ENCODER_B_Pin); // 编码器状态机 if(last_state == 0x00) { if(current_state == 0x02) return 1; // 正转 if(current_state == 0x01) return -1; // 反转 } last_state = current_state; return 0; }

6. 功能测试与效果验证

6.1 PWM调速功能测试

测试目的:验证PWM信号能否正确控制风扇转速

测试步骤

  1. 编译下载程序到STM32
  2. 用示波器测量PA0引脚波形
  3. 观察PWM频率是否为25kHz
  4. 改变占空比,观察风扇转速变化
  5. 测试0%、25%、50%、75%、100%五个档位

预期结果

  • PWM频率稳定在25kHz±5%
  • 占空比从0%到100%线性变化
  • 风扇转速随占空比增加而提高
  • 0%占空比时风扇完全停止

常见问题

  • 频率不正确:检查定时器分频系数计算
  • 无输出:检查GPIO配置和定时器使能
  • 风扇不转:检查MOSFET连接和电源

6.2 定时功能测试

测试目的:验证定时关闭功能是否准确

测试步骤

  1. 设置1分钟定时
  2. 启动风扇,开始计时
  3. 观察OLED显示倒计时
  4. 时间到后检查风扇是否自动关闭
  5. 测试5分钟、30分钟等不同时长

预期结果

  • 定时精度误差小于±1秒/分钟
  • 时间到后风扇自动停止
  • OLED显示实时更新
  • 可中途取消定时

6.3 OLED显示测试

测试目的:验证用户界面显示正常

测试步骤

  1. 上电检查OLED是否正常初始化
  2. 旋转编码器,观察菜单切换
  3. 测试所有显示页面
  4. 检查字符显示是否清晰
  5. 测试长时间显示有无残影

预期结果

  • 上电后显示欢迎界面
  • 菜单切换流畅无闪烁
  • 所有字符显示清晰
  • 无显示残影问题

7. 系统优化与性能提升

7.1 功耗优化策略

动态频率调整

// 根据系统负载调整CPU频率 void SystemClock_Config_Optimized(void) { // 正常模式:72MHz // 低速模式:8MHz(待机时) // 睡眠模式:更低功耗 }

外设电源管理

  • 不使用时关闭OLED背光
  • 定时器在无PWM输出时进入低功耗模式
  • 使用STM32的停机模式降低待机功耗

7.2 控制算法优化

PID转速控制

// pid.c typedef struct { float Kp, Ki, Kd; float integral; float prev_error; } PID_Controller; float PID_Update(PID_Controller* pid, float setpoint, float actual) { float error = setpoint - actual; pid->integral += error; float derivative = error - pid->prev_error; float output = pid->Kp * error + pid->Ki * pid->integral + pid->Kd * derivative; pid->prev_error = error; return output; }

转速平滑过渡

  • 避免转速突变导致电流冲击
  • 实现软启动和软停止功能
  • 加入转速变化率限制

8. 常见问题与排查方法

8.1 硬件连接问题

问题现象可能原因排查方式解决方案
OLED不显示电源接反、I2C地址错误检查VCC/GND、测量I2C信号确认3.3V供电,调整I2C地址
风扇不转MOSFET损坏、PWM无输出测量栅极电压、检查PWM波形更换MOSFET,检查GPIO配置
编码器无反应引脚接触不良、上拉电阻检查接线、测量引脚电平添加上拉电阻,重新焊接
系统重启电源电流不足测量工作电流更换更大功率电源

8.2 软件调试问题

PWM输出异常

  • 现象:频率不正确或占空比不对
  • 排查:检查定时器分频系数和重载值计算
  • 解决:使用STM32CubeMX重新生成配置

I2C通信失败

  • 现象:OLED无法初始化
  • 排查:用逻辑分析仪抓取I2C波形
  • 解决:调整I2C时钟速度,检查从机地址

定时器中断冲突

  • 现象:系统卡死或运行异常
  • 排查:检查中断优先级配置
  • 解决:合理分配中断优先级,避免嵌套过深

8.3 性能优化问题

风扇转速波动

  • 原因:电源纹波大或PWM频率不合适
  • 解决:增加电源滤波电容,调整PWM频率

按键响应迟钝

  • 原因:消抖算法过于保守或主循环阻塞
  • 解决:优化消抖参数,使用中断处理编码器

显示刷新慢

  • 原因:OLED全屏刷新耗时过长
  • 解决:使用局部刷新,优化显示算法

9. 扩展功能与进阶应用

9.1 无线控制扩展

蓝牙模块接入

// 通过HC-05蓝牙模块接收手机控制指令 void Bluetooth_Control_Handler(uint8_t* data) { switch(data[0]) { case 'S': // 设置转速 SetFanSpeed(data[1]); break; case 'T': // 设置定时 SetTimer(data[1] * 60); break; case 'M': // 模式切换 SwitchMode(data[1]); break; } }

Wi-Fi远程控制

  • 使用ESP8266模块实现联网功能
  • 通过MQTT协议接入智能家居系统
  • 支持手机APP远程控制

9.2 环境感知扩展

温度传感器集成

// 使用DS18B20检测环境温度 void Temperature_Control(void) { float temp = DS18B20_ReadTemp(); if(temp > 30.0f) { SetFanSpeed(80); // 高温自动加速 } else if(temp < 25.0f) { SetFanSpeed(30); // 低温自动减速 } }

湿度检测功能

  • 添加DHT11/DHT22湿度传感器
  • 实现基于温湿度的智能控制策略
  • 支持除湿模式自动开启

9.3 数据记录与分析

运行数据存储

// 使用EEPROM记录运行统计 typedef struct { uint32_t total_runtime; uint16_t start_count; uint8_t max_speed; uint8_t avg_speed; } Fan_Statistics; void Save_Statistics(void) { // 定期保存到EEPROM EEPROM_Write(STATS_ADDR, &stats, sizeof(stats)); }

能耗统计功能

  • 基于转速估算功耗
  • 统计每日/每月用电量
  • 提供节能建议

10. 项目总结与进阶方向

这个基于STM32的智能定时风扇项目涵盖了嵌入式开发的多个重要知识点。通过实际动手实现,可以深入理解PWM控制原理、定时器应用、I2C通信协议以及用户界面设计。

最值得尝试的优化

  1. 首先验证PWM控制是否稳定,这是整个系统的基础
  2. 完善用户交互体验,让操作更加直观流畅
  3. 加入软启动功能,延长风扇电机寿命

最容易踩的坑

  • PWM频率设置不当导致风扇异响
  • I2C地址配置错误使OLED无法显示
  • 电源功率不足引起系统不稳定

后续扩展方向

  • 移植到其他STM32系列芯片,学习不同型号的特性差异
  • 加入FreeRTOS实现多任务管理,提升系统可靠性
  • 开发配套的手机APP,实践物联网应用开发
  • 优化控制算法,实现更精准的转速和温度控制

这个项目代码结构清晰,模块化程度高,非常适合作为STM32学习的实战案例。建议在基本功能实现后,根据自己的需求继续添加新功能,不断提升嵌入式开发能力。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询