基于STM32的智能绿色风扇设计与实现详解
2026/9/22 6:38:01 网站建设 项目流程

这次我们来看一个基于 STM32 的智能绿色风扇设计与实现项目,项目编号 mcu-1173,定位是单片机毕业设计。所谓“智能绿色”,核心不是单纯做一个能转的风扇,而是让风扇根据环境温度、人员存在、用户设定三个维度自动工作:有人时按温度自动调速,没人时定时关闭,温度未达到阈值时保持低转速,整体上减少无效运行和电量浪费。主控使用 STM32,外围涉及温度采集、人体感应、PWM 电机调速、OLED 显示和按键交互,覆盖了 GPIO、定时器、ADC、单总线通信、I2C 显示等 STM32 开发中的高频知识点。这种方案放在毕业设计里,既能展示嵌入式系统设计能力,也容易迁移到智能家居控制类题目上。本文会从需求设计、硬件选型、驱动接线、软件框架、功能验证到常见排错完整拆一遍,帮你确认为什么要做、怎么做、做到什么程度可以验收。内容面向准备做 STM32 单片机毕业设计、课程设计和智能小项目的读者,如果你正在选型或已经画好板子开始写代码,这篇可以直接收藏备用。

下面先把整个项目的核心能力整理出来,随后分别展开硬件、代码和测试方法。为避免瞎编参数,所有涉及型号、接口和引脚的内容都按常见的 STM32 毕业设计方案来组织,具体型号和 PCB 接线需要以你手头的开发板或原理图为准。这里的价值在于给你一套完整可执行的实现框架,而不是照抄某个固定图纸。

1. 项目核心能力概览

从功能和工程约束的角度,这个智能绿色风扇项目可以先用一张表格快速看清楚:

项目项说明
项目名称基于 STM32 的智能绿色风扇设计与实现
项目类型单片机毕业设计 / 嵌入式系统应用设计
主控方案以 STM32F103 系列为典型,如 STM32F103C8T6
开发方式寄存器 / 标准外设库 / STM32 HAL 库均可,推荐 HAL 或标准库工程
主要功能温度检测、人体感应、自动调速、手动调速、OLED 显示、阈值设定
核心执行器5V/12V 直流风扇模块,用 PWM 调压或电机驱动板控制
输入模块DS18B20 温度传感器、HC-SR501 人体红外感应、独立按键
显示模块0.96 寸 I2C OLED(SSD1306)
节能控制无人强制延时关闭,温度区间映射 PWM 占空比
工作模式手动模式、自动模式、节能模式
供电方式建议使用 USB 5V 或低压直流电源,如需控制市电风扇须按强电规范设计
适用场景教室、宿舍、办公工位、家用桌面风扇智能化改装、智能家居课程设计
平台兼容Keil MDK、STM32CubeMX、IAR,也可以配合 VSCode + EIDE

这里需要明确一点:如果毕业设计只要求“能转、能调速、能测温度”,这个题目并不算难。真正能拉分的点是“绿色节能”有没有落到控制策略上,有没有数据或逻辑支撑。比如同样 35 度环境,普通风扇一直全速转,而智能风扇在有人且温度刚超过阈值时只给中低占空比,人离开后延时 30 秒停止,这种细节就是答辩时可以展开讲的亮点。所以整篇文章不只是给接线图,还会给一套可解释的控制决策表。

2. 系统功能设计与绿色节能策略

2.1 功能需求

先按毕业设计常用写法把需求拆成功能模块:

温度采集模块负责感知环境温度。DS18B20 是单总线数字温度传感器,测温范围常见为 -55℃ 到 +125℃,在 10 位精度下分辨率可以到 0.25℃ 左右,12 位时更高一些。对风扇控制来说,不需要小数点后几位也够用。它的优点是只占用一根 IO 口线,接线简单,代码上需要处理单总线时序。

人体存在检测模块负责判断风扇前方是否有人。HC-SR501 是热释电红外传感器模块,输出数字电平,检测到人体活动时输出高电平,没人时保持低电平。它的缺点是只对“移动的人体”敏感,如果人长时间静止,模块输出可能会恢复低电平。所以实际控制逻辑里不能把“无人”判断做成瞬时值,一般要加“连续无人超过 N 秒才关风扇”的延时策略,这个后面代码部分会体现。

按键输入模块用来切换手动/自动模式、调整温度阈值。常见的毕业设计会安排 3 个或 4 个独立按键。这个项目我建议至少保留 3 个:模式键、温度阈值加、温度阈值减。如果还想增加“定时关闭”“风速循环”功能,可以再加键,但按键多了会占用 IO,逻辑复杂度也会上升,第一次做不建议超过 4 个。

执行机构是直流风扇。为了安全,毕业设计演示建议用 5V 或 12V 的直流风扇,通过三极管/MOS 管或 L9110S 驱动板接到 STM32 的 PWM 输出脚。使用时必须注意:不是所有直流风扇在 10% 占空比下都能启动,电机存在“启动死区”。如果占空比太低,风扇可能发出嗡嗡声但不转,反而显得不智能。一个常用办法是启动时先给高占空比,比如 80%,运行 300ms,然后回落到目标占空比,这个细节能做到程序里,答辩时解释起来也很加分。

显示模块用 OLED 显示当前模式、温度、设定阈值和 PWM 占空比。OLED 刷屏不能太频繁,否则主循环会被 I2C 通信占用大量时间,一般 200ms 到 500ms 刷新一次即可。

2.2 绿色节能控制决策

绿色节能的核心是控制决策表。这里以“温度阈值”和“人体存在”两个输入为例,给出一套典型的控制逻辑:

运行状态 / 条件风扇动作说明
无人在场,延时计时未到保持当前风速或按设定延时运行防止误关
无人在场,延时计时结束关闭风扇,进入待机避免无人空转
有人在且当前温度低于低温阈值风扇停止或最低档环境不热则不吹
有人在且温度处于低温阈值与高温阈值之间PWM 占空比按线性或分段映射中低速运行
有人在且温度高于高温阈值风扇全速或达到限定高速快速散热
手动模式用户按键选择档位,忽略温度满足个体需求
节能模式无人立即延时关闭,有人时限制最高转速最低能耗演示

这套表的价值在于:它可以让风扇避免“检测到人就开始转、没检测到人立刻停”的抖动问题,同时也能让“绿色”这两个字有具体的控制逻辑支撑。自动模式还应该加入迟滞区间。比如设定 28℃ 是打开阈值,那么风扇应该在温度升高到 28℃ 时启动,但关闭时不是马上低于 28℃ 就停,而是低于 26℃ 或无人延时一段时间才停。这样做的好处是防止传感器温度在阈值附近波动时风扇频繁启停,对电机寿命和体验都有帮助。

2.3 指示灯与提示功能

建议项目里增加一个简单状态指示灯或蜂鸣器,用于提示模式切换。OC 输出或普通推挽输出 LED 即可。OLED 已经能显示文字,但用户看风扇时不一定盯着屏幕,所以 RGB LED 三色灯可以更直观:红色表示手动高速、蓝色表示自动中速、绿色表示节能待机或风扇关闭。这个小设计会让整个装置看起来更完整,也能作为作品展示时的加分点。蜂鸣器如果不是必须,可以不接;如果接,声音要小,只做按键和阈值越限提示,不要做成持续报警。

3. 硬件选型与接线说明

3.1 典型器件清单

因为毕业设计要以稳定可靠为主,器件尽量选淘宝或实验室容易买到的模块,以下是一套典型配置:

器件型号/规格用途
主控板STM32F103C8T6 最小系统板控制和数据处理
下载器ST-Link V2 或 USB 转 TTL程序下载和串口打印
温度传感器DS18B20 防水探头或 TO-92 封装环境温度采集
人体感应模块HC-SR501 热释电红外模块人体存在检测
显示模块0.96 寸 OLED SSD1306 I2C参数显示
风扇5V/12V 直流风扇,尺寸按外壳选执行机构
驱动方式L9110S 驱动板或 NPN MOS 驱动电路风扇供电与 PWM
按键轻触按键 4 个模式切换和阈值设定
电源USB 5V / 充电宝 / 稳压模块系统供电
指示灯LED + 限流电阻模式指示

如果非要做 220V 市电风扇的智能插座改造,那就需要继电器、隔离电源和强电安全设计,不建议在课程设计或毕业设计演示中直接触碰 220V,安全隐患很大。文章后面所有接线和控制方案默认都是低压直流风扇。

3.2 引脚分配示例

下面给出一个常见分配表,不代表唯一正确接法,因为不同开发板丝印和重映射不一样,实际调试时要看原理图。推荐先选好能避开 JTAG/SWD 冲突的引脚,再在 CubeMX 里重新映射。

模块STM32 引脚建议说明
DS18B20 数据PA0开漏输出或普通 GPIO,需 4.7k 上拉
HC-SR501 OUTPA1输入模式,建议内部上拉
OLED SCLPB6I2C1 时钟
OLED SDAPB7I2C1 数据
风扇 PWMPA8TIM1_CH1,或 PB0/TIM3_CH3
按键 K1PB0模式切换
按键 K2PB1阈值加
按键 K3PA4阈值减
按键 K4PA5手动风速档位循环
LED 状态PC13 或 PA6接限流电阻

作为通用提醒:STM32F103C8T6 的 PB3、PB4、PA13、PA14、PA15 默认和调试下载功能相关,如果要用这些引脚,必须在 Keil 或 CubeMX 里做重映射和关闭 SWD 复用,否则下载一次程序后可能无法再次连接。所以上面示例里尽量避开 PA13/PA14,优先使用普通 IO。

3.3 电路连接注意事项

DS18B20 的数据线要接一个 4.7kΩ 左右的上拉电阻到 3.3V 或 5V。很多成品模块已经集成上拉,直接用模块即可。HC-SR501 模块供电一般用 5V,输出高电平是 3.3V 还是 5V 取决于模块设计,如果输出 5V,接入 STM32 GPIO 时要注意电平兼容性,稳妥做法是加电阻分压或使用 3.3V 版本模块。OLED 模块 I2C 需要共地,SDA/SCL 不要接反。L9110S 驱动板有两路输入,只接一路时风扇方向固定,PWM 信号加到 IN1 或 IN2,另一路接低或接地。由于不同模块的输入端极性设计不完全一样,接好以后先在手动模式测试正转,再上代码。

4. 软件工程搭建与关键代码实现

4.1 开发环境准备

这套设计可以用 Keil MDK 或者 STM32CubeIDE。毕业设计答辩通常要求给出代码截图和工程结构,所以工程目录建议按模块拆开:

Project/ ├── Core/ │ ├── Inc/ │ └── Src/ ├── Drivers/ ├── Hardware/ │ ├── ds18b20.c/h │ ├── oled.c/h │ └── motor.c/h ├── App/ │ ├── fan_control.c/h │ └── key_scan.c/h └── Docs/

如果用 CubeMX,先选芯片型号,配置时钟树、GPIO、TIM PWM、I2C、USART 等外设,然后生成工程。DS18B20 的单总线时序建议不要依赖 HAL 的延时函数太多,因为不同优化等级下延时会变化;更可靠的做法是用 DWT 或 SysTick 微秒延时函数。对于刚起步的人来说,如果不想折腾时序,也可以把 DS18B20 换成 AHT20、DHT11 等更简单的传感器,或者用 STM32 内部 ADC 读 NTC 热敏电阻。但毕业设计里 DS18B20 更常见,代码资料也最多。

4.2 主循环状态框架

主循环不要全部堆在 main.c 里。这里给出一个功能性框架:

int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_TIMx_Init(); MX_I2C1_Init(); OLED_Init(); DS18B20_Init(); Motor_Init(); Key_Init(); uint32_t tick_display = 0; uint32_t tick_sensor = 0; uint32_t tick_scan = 0; while (1) { // 5ms 按键扫描 if (HAL_GetTick() - tick_scan >= 5) { tick_scan = HAL_GetTick(); Key_Scan(); } // 500ms 采样一次温度,避免频繁读单总线卡住主循环 if (HAL_GetTick() - tick_sensor >= 500) { tick_sensor = HAL_GetTick(); Temperature_Refresh(); } // 200ms 刷新一次 OLED if (HAL_GetTick() - tick_display >= 200) { tick_display = HAL_GetTick(); Display_Refresh(); } // 根据当前模式执行自动或手动控制 Fan_Task(); } }

注意:DS18B20 单总线温度转换最长时间在 750ms 左右,如果每 500ms 读一次,有可能上一次转换还没完成就开始下一次读取。实际代码要区分“发起转换”和“读取结果”两个阶段,建议采样周期设在 1s 以上。上面示例只是展示工程组织,不是可直接复制的完整驱动。

4.3 DS18B20 温度读取示例

这里给出一个常用的 DS18B20 驱动示例片段,里面用到的是“延时微秒”函数,需要你自己实现或移植:

uint8_t DS18B20_ReadTemp(float *temp) { uint8_t low = 0, high = 0; int16_t raw = 0; if (!DS18B20_Reset()) return 1; // 总线异常 DS18B20_WriteByte(0xCC); // 跳过 ROM DS18B20_WriteByte(0x44); // 启动温度转换 HAL_Delay(10); if (!DS18B20_Reset()) return 2; DS18B20_WriteByte(0xCC); DS18B20_WriteByte(0xBE); // 读取暂存器 low = DS18B20_ReadByte(); high = DS18B20_ReadByte(); raw = (high << 8) | low; *temp = raw * 0.0625f; return 0; }

这个代码把转换等待时间简化成了固定延时,实际 DS18B20 在 12 位分辨率下的最大转换时间是 750ms,因此更好的方式是:在第一次进入循环时发送启动转换命令,然后经过 750ms 后再读取,读取完成后再立刻启动下一次转换,用“流水线”方式避免主循环长时间阻塞。如果觉得解释起来麻烦,直接设置 9 位或 10 位分辨率可以缩短转换时间。这也是答辩时老师可能问的问题。

4.4 风扇 PWM 控制与占空比映射

风扇 PWM 控制最关键的是占空比映射。假设最高温度和用户设定的阈值相关,可以做成线性映射,也可以做分段映射。下面给出一段相对完整的风扇控制代码:

#define FAN_STOP 0 #define FAN_LOW 25 #define FAN_MID 55 #define FAN_HIGH 85 void Motor_SetDuty(uint16_t duty) { // duty 范围 0~100,对应 CCR 定时器重载值 __HAL_TIM_SET_COMPARE(&htimx, TIM_CHANNEL_1, duty); } void Fan_AutoControl(float temperature, uint8_t human) { static uint8_t last_duty = FAN_STOP; uint8_t target_duty = FAN_STOP; if (!human) { target_duty = FAN_STOP; } else if (temperature < auto_temp_low) { target_duty = FAN_STOP; } else if (temperature >= auto_temp_high) { target_duty = FAN_HIGH; } else { // 温度区间内线性映射 uint16_t step = (uint16_t)((FAN_HIGH - FAN_LOW) * 100 / 512); uint16_t dt = (uint16_t)((temperature - auto_temp_low) * 100); target_duty = FAN_LOW + (dt / 512) * step; if (target_duty > FAN_HIGH) target_duty = FAN_HIGH; if (target_duty < FAN_LOW) target_duty = FAN_LOW; } // 如果上一时刻是停止,而目标转速较高,先给一个启动占空比,防止启动死区 if (last_duty == FAN_STOP && target_duty > FAN_LOW) { __HAL_TIM_SET_COMPARE(&htimx, TIM_CHANNEL_1, 80); HAL_Delay(300); } Motor_SetDuty(target_duty); last_duty = target_duty; }

这段代码的价值在于说明 PWM 调速不是简单“设定占空比”就结束。要处理启动死区,要处理无人关停,还要处理温度区间映射。可以按照自己的芯片和驱动板调整占空比范围,但要注意:TIM 的 ARR 如果设置为 999,那么 1% 占空比就是 CCR=10,变量不要直接往 __HAL_TIM_SET_COMPARE 里传 0~100 范围内的值,除非你已经把 ARR 设置为 100 或做了换算。非常常见的错误是占空比传大了,导致波形周期完全不对。

4.5 按键扫描与模式切换

按键扫描建议用“非阻塞读取 GPIO + 消抖时间戳”的方式,而不是 HAL_Delay 消抖。因为 HAL_Delay 在等待时会卡住其他任务。可以写一个轻量消抖:

void Key_Scan(void) { if (HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == GPIO_PIN_RESET) { if (key1_press_tick == 0) key1_press_tick = HAL_GetTick(); else if (HAL_GetTick() - key1_press_tick > 20) { key1_flag = 1; key1_press_tick = 0; } } else { key1_press_tick = 0; } }

然后主循环里检测 key1_flag,根据当前 mode 切换工作模式。如果做得更精细,可以支持“短按”“长按”。但考虑到是单片机毕业设计,没必要把所有高级交互都做进来,把一个按键逻辑做对、做好,比堆一堆不稳定功能要好。这个原则也适用于 OLED 菜单设计。

4.6 OLED 显示

OLED 显示项目状态时,可以使用对应驱动库。需要显示的参数至少包括:

Mode: Auto Temp: 28.6 C Low: 26 C High: 32 C PWM: 55% Human: YES

OLED 刷新不要放在中断里,也不用每次调用都全屏清屏。比较好的方式是先清局部区域或使用 DMA 传输,但这属于优化,不一定在毕设阶段要求。要做的话可以开启 I2C DMA,初始化后显示区域数据放缓冲区,然后周期性刷新。这里提一句是因为很多人在毕业设计里会遇到“OLED 显示卡顿”“刷新占用大量时间”的问题,原因往往是频繁调用清屏函数。

5. 功能测试与效果验证

由于没有拿到实际运行日志和具体设备环境,下面给出一套通用的验证流程。你按这套流程操作,基本能从“能编译”推进到“能演示”。

5.1 上电前检查

先不要急着下载程序。上电前用万用表确认:

检查项标准说明
电源电压3.3V / 5V 正常用万用表测量主控和传感器电源脚
地线是否共地各模块 GND 与主控 GND 相连I2C、单总线、PWM 信号都需要共地
OLED I2C 地址0x3C 或 0x3D不确定时用 I2C 扫描代码确认
DS18B20 上拉电阻数据线对电源有 4.7k 上拉成品模块一般已包含
风扇供电使用独立 5V/12V 电源不能从 STM32 3.3V 引脚直接偷电

5.2 基础功能测试顺序

建议按“显示 -> 传感器 -> 手动模式 -> 自动模式 -> 节能逻辑”的顺序逐步验证。

第一步,烧录最简单的 LED 闪烁和 OLED 显示程序,确认芯片和下载链路正常。很多毕业设计一开始直接写完整综合程序,结果分不清是传感器坏了还是主控问题,这是低效做法。

第二步,测试 DS18B20。读取到的温度应接近室内温度。如果读出来是 85℃ 或 -55℃,通常是 4.7k 上拉缺失、数据引脚接错或延时时序不对。如果能够读到室内温度,再用手指捏住 DS18B20,观察温度是否能缓慢上升。

第三步,测试 HC-SR501。模块上电后会有一段稳定时间,刚上电时输出可能是高电平,等待 10 到 30 秒后再测试。人站在模块前方移动,观察输出引脚是否变高,人离开后模块经过延时自动恢复低。如果模块一直输出高,可能是灵敏度/延时旋钮调得太大,或者模块正对空调/热源。

第四步,测试手动模式。通过按键切换档位,风扇转速应从低到高变化。如果低档不转但高档转,就在程序里提高最低占空比,或者按前文思路加入“启动高占空比后回落”的过程。如果完全不能调速,先检查是 GPIO 没有输出 PWM,还是驱动板接线不对。用示波器或逻辑分析仪看 PWM 波形是最快的排查方式,没有示波器也可以在代码里用串口打印 CCR 值。

第五步,测试自动模式。设定低温阈值为 25℃,高温阈值为 32℃。将 DS18B20 放在空调出风口或者用电吹风加热,观察温度到阈值后风扇是否启动。判断成功的标准是:人不在时,即使温度很高,风扇也要关闭或进入待机;人出现后在 1~2 秒内风扇自动启动;人离开后,风扇不应立即停止,而应经过设定的延时再停止。

5.3 绿色节能效果验证

绿色节能不能只看“风扇能停”。要能证明节能效果,可以从几个维度记录:

项目记录方式结果判定
无人时耗电电流表串联供电端,人离开后观察电流电流应低于有人运行时的 30% 或更低
风扇运行时长程序统计电机累计启动时间自动模式应比一直全速运行时间短
温度波动响应用加热源靠近 DS18B20 再拿开风扇不会频繁启停
手动误操作切换模式和调节阈值OLED 显示与实际动作一致

如果条件允许,还可以加一个 ACS712 电流传感器,把电流值显示到 OLED 上,通过串口或蓝牙上传到上位机。这个扩展属于加分项,但会增加硬件成本和代码量。如果你的毕设要求偏“控制算法”,建议在论文里放多组实验数据:相同温度、相同风扇、普通恒速运行与智能自动控制运行下的累计耗电情况对比。

6. 数据采集、批量测试与上位机和扩展说明

这里要说明一件事:很多 AI 本地部署类项目会强调 API 接口和批量任务,但这个 STM32 风扇项目本身不是服务端项目,没有传统意义上的 HTTP API。不过从毕业设计展示和功能扩展角度,它可以扩展出几种与“批量/接口”相似的能力:

扩展方向实现方式说明
串口日志交互STM32 USART 发送字符串,上位机用串口助手接收数据上报、结果记录
PC 上位机控制Python PyQt / C# 上位机通过串口发送指令按键之外提供远程控制界面
ESP8266 Wi-Fi 模块AT 指令或 MQTT 协议接入局域网/云平台手机端查看温度和控制风扇
蓝牙模块HC-05 / HC-06 透传近距离手机控制
多台风扇节点每台风扇一个 STM32 节点,上位机统一管理可以作为“实验室/办公室风扇群控”扩展

如果你只需要一个自动开停风扇的单片机项目,前面的内容已经够用。但如果你想把完成度拉高,串口打印是低成本最好的办法。在代码里加一个串口重定向,每隔 1 秒打印一次温度、占空比、当前模式,调试和答辩展示都会方便很多。这里给出一个通用串口打印模板:

#include "stdio.h" #include "usart.h" int fputc(int ch, struct __FILE *fp) { HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 100); return ch; } // 然后在 main 中周期调用: printf("temp=%.2f, mode=%d, duty=%d\r\n", temperature, mode, pwm_duty);

注意:使用 printf 重定向后,如果需要查看打印内容,Keil 里要勾选“Use MicroLIB”,否则可能无法正确重定向到串口。这个坑很多新手都会遇到。如果不想用 MicroLIB,就写一个自己的 log 函数,逐字节发送字符串。下面给出一个更通用的发送函数:

void Debug_SendFloat(const char *name, float value) { char buf[64]; sprintf(buf, "%s: %.2f\r\n", name, value); HAL_UART_Transmit(&huart1, (uint8_t *)buf, strlen(buf), 100); }

7. 资源占用与性能观察

毕业设计虽然没有“显存占用”这种概念,但单片机的 Flash、RAM、CPU 占用和功耗仍然需要关注。这部分容易被忽略,却是最终的评分项。

STM32F103C8T6 的 Flash 是 64KB,RAM 是 20KB。如果 OLED 全屏使用字符串拼接,随手定义一个上百字节的临时数组,对一个内存只有 20KB 的单片机来说必须小心。打印日志、格式化浮点数、显示缓冲叠加在一起,很容易出现内存不足或栈溢出。建议:

  • OLED 显示缓冲如果使用全屏 1KB 或 8KB 缓冲区,要看芯片 RAM 够不够。
  • 不要在主函数里定义超大局部变量,放到 static 或全局数组。
  • 浮点运算在 STM32F103 没有硬件 FPU,F103 是软件浮点,虽不至于不能跑,但频繁 printf 和格式化浮点会占 CPU。
  • 测量线程任务执行周期:用 GPIO 翻转在示波器上观察主循环周期,确认传感器读取没有卡死主循环。这个测试方法在嵌入式里代替了看“显存占用”的功能,专业度很高。

功耗优化可以从几个方向做:

优化手段做法预期效果
降低主频72MHz 改为 64MHz 或 48MHz降低动态功耗
空闲时进入低功耗模式无任务时调用 __WFI() 或 STM32 STOP 模式系统功耗下降
关闭不用的外设时钟关闭 ADC、USART、I2C 时钟减少外设功耗
降低 OLED 刷新频率从 100ms 改为 500ms减少 I2C 总线活动
风扇用低占空比待机风扇完全停止而不是低转无风阻、无摩擦损耗

这些措施不一定要全部做,选一两个实现并在论文中分析即可。不过,如果论文标题里有“绿色节能”,却没有功耗对比数据,最后给老师的印象会弱很多。

8. 常见问题与排查方法

下面整理一份比较典型的排查表,涵盖 DIY 焊接、模块接线、代码下载和运行阶段:

问题现象可能原因排查方式解决方案
程序下载失败BOOT0 状态不对、驱动未安装、芯片锁死按住复位再点击下载;检查驱动短接 BOOT0 到 1 再下载;重装 ST-Link 驱动
板子可下载但 OLED 白屏或花屏I2C 地址错误、引脚接错、供电不足I2C 扫描;量 OLED 电源脚改设备地址;检查上拉和共地
DS18B20 读不出温度上拉缺失、GPIO 模式错误、时序不对示波器/逻辑分析仪抓波形;换传感器加 4.7k 上拉;延迟函数改用 DWT
风扇完全不动PWM 通道没初始化、驱动板供电不足测 IN1/IN2 电平,测风扇电源先高电平测试,再查定时器初始化
风扇能转但不受控,一直是最高速GPIO 复用配置错误,占空比传错打印 CCR 值;检查 ARR 设置换算占空比;检查 TIM Channel 配置
HC-SR501 无法触发模块稳定时间不够、正对热源、检测距离太近模块断电重启,等待 30 秒调整灵敏度旋钮,人移动再测试
HC-SR501 一直有效延时旋钮调太大、模块收到热气流检查输出电平与人的关系延时调到最小,远离空调/暖气
自动模式频繁启停缺少迟滞逻辑、温度采样周期太短查看串口温度曲线增加高温-低温迟滞区间,如 2℃
程序运行一段时间后重启电源电流不够、风扇启动瞬间压降过大万用表量电压跌落风扇单独供电,使用大电容
OLED 刷新卡顿/温度刷新慢使用了 HAL_Delay 阻塞检查打印时间戳改成非阻塞状态机和定时任务
按键偶尔没反应没有消抖、按一次触发多次串口打印按键标志增加 20ms 消抖
在人静止不动时风扇停了HC-SR501 对静止人体不敏感确认模块选型改用毫米波雷达人体存在传感器,如 LD2410

这里的 HC-SR501 问题要特别说明:热释电红外传感器本质上是“移动检测”,不是严格意义上的“人体存在检测”。人趴在桌子上写代码,风扇可能因为没检测到动作自动关闭。如果毕业设计的场景是“智能学习风扇”,建议使用 24GHz 毫米波传感器或雷达模块来做人体存在检测,虽然贵一些,但逻辑更贴合产品需求。如果成本有限,就在说明文档里明确传感器工作原理,把“无人延时关闭”时间设置成 2 到 5 分钟,减少误关困扰。

9. 毕业设计文档与工程管理建议

如果这个题目最终会写成毕业设计论文或课程设计报告,除了代码能跑,文档内容也需要覆盖几个点:

9.1 需求分析部分

写清楚“普通风扇有哪些浪费”“智能绿色风扇解决什么问题”,不要只写“实现温度检测和自动开关”。问题可以归纳成三方面:一是风扇常转不关造成无人空转;二是固定风速无法根据温度变化调节;三是手动频繁开关不仅麻烦,也可能影响风扇寿命。智能系统通过传感器感知环境和人员状态,再通过决策逻辑控制风扇运行,减少无效功耗,这是整套设计的立足点。

9.2 硬件设计部分

给出系统框图、主控最小系统、传感器接口电路、电机驱动电路。画原理图时注意标注器件型号和参数,不要只截图别人的模块。在论文里可以用方框图表示系统组成:STM32 作为主控,左边是输入设备,右边是输出设备,下面画电源。模块化框图在答辩 PPT 里非常直观。

[温度传感器 DS18B20] ---- 单总线 ---+ | [人体感应 HC-SR501] ---- GPIO ------+-> [STM32 主控] --> PWM --> [风扇驱动/风扇] | --> [按键输入] ---- GPIO ------+ I2C | --> [电源模块] ---- 供电 ------+ [OLED 显示]

注意,这里只是用文本示意系统结构,论文里最好画成规范框图。

9.3 软件设计部分

可以画出主程序流程图,但要注意:论文中插入大量源代码并不一定加分,核心代码和关键注释放一部分即可,重点写控制逻辑和决策表。答辩时老师会问的往往是“为什么这样设计”“如果出现某情况怎么办”,而不是每行代码什么意思。

答辩高频问题可以提前准备:

  • 为什么选 STM32F103,而不是 51 或 Arduino?
  • 为什么选 DS18B20,和热敏电阻方案有什么区别?
  • 热释电传感器存在什么局限?如何规避?
  • PWM 调速频率选多少?为什么听不到噪音?
  • 风扇电机和单片机如何隔离?
  • 系统的绿色节能体现在哪里?
  • 如果人坐在风扇前不动,系统会怎样?是否满足“存在检测”需求?

对于第 4 个问题,PWM 频率一般选择 20kHz 以上可以超过人耳听觉范围,但普通直流风扇电机对高频 PWM 响应可能变差;很多电动风扇驱动频率在 1kHz 到 25kHz 之间。实际调试时需要听噪音、看转速,选定一个合适频率。如果让老师试听时风扇有明显高频啸叫,会是很尴尬的演示效果。

10. 总结与下一步扩展

基于 STM32 的智能绿色风扇项目,硬件结构并不复杂,核心是控制逻辑和节能策略。做这个毕设时,不用一上来追求 321 个功能,先把底层驱动打通:DS18B20 能读到准确温度,OLED 能显示状态,按键能切换模式,PWM 能控制风扇,然后再叠加自动决策逻辑。整个系统的可行顺序是手动模式验证电机,自动模式验证温度阈值,节能模式验证无人关停。

最容易踩的坑集中在几个方面:一是风扇低压档不转,本质是启动死区,需要在高档启动后回落;二是 HC-SR501 对静止人体不敏感,导致无人判断频繁出现;三是 DS18B20 读温度时阻塞主循环,影响了按键响应和显示刷新;四是按键和高频中断逻辑没加消抖,显示状态跳变让人误以为代码有 bug。

如果你打算在这个项目上继续扩展,可以考虑两个方向。硬件方向是把普通直流风扇换成带霍尔测速的 4 线 PWM 风扇,通过 STM32 定时器输入捕获读取转速,形成闭环控制,让目标转速更准确。软件方向是接入 ESP8266 或蓝牙模块,把温度、模式、转速上传到手机小程序,实现远程控制和数据记录。这两个方向都是从“演示样机”走向“产品原型”的自然延伸。

最后提醒一句:如果在宿舍或实验室使用 220V 市电风扇做改装,务必注意用电安全,方案要增加保护隔离,论文和演示阶段建议优先使用低压直流风扇。合理控制、合法用电、规范接线,这个设计才算完整。

本文提到的所有代码、引脚分配和测试流程都是通用设计模板,实际调试时必须根据你选用的 STM32 型号、开发板原理图和传感器模块修改。建议你收藏这份思路,真正动手前先从点亮一块 OLED、读取一次温度开始,逐步把小模块拼成完整系统。这样即使中途出问题,也能很快定位到是哪一级没有打通。

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

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

立即咨询