从零设计一款小风扇:用FS8A15S8 MCU搞定多档升压、边充边放与安全保护
从零设计一款智能小风扇:基于FS8A15S8的多档控制与安全保护实战指南
在创客社区和嵌入式开发领域,小型便携设备的DIY一直是最受欢迎的入门项目之一。其中,智能小风扇因其功能直观、硬件结构简单而成为许多开发者接触MCU控制、电源管理和PCB设计的理想起点。今天,我们将使用FS8A15S8这颗高性价比MCU,从电路设计到固件开发,完整实现一个支持三档风速调节、Type-C充电且具备完善保护机制的智能风扇原型。
这个项目特别适合那些已经掌握基础电子知识,但希望将理论转化为实际产品的开发者。您将学习到如何将一颗普通的MCU转变为功能完整的设备控制器,处理从用户输入到功率输出的完整链路。不同于简单的demo制作,我们会特别关注产品的实用性和安全性,包括边充边放功能的实现、电池保护逻辑以及符合实际应用需求的PWM控制策略。
1. 硬件系统设计与元器件选型
1.1 核心电路架构规划
一个完整的智能风扇系统包含以下几个关键子系统:
- 主控单元:FS8A15S8 MCU作为控制核心
- 电源管理:锂电池充电电路、升压转换电路
- 用户界面:单按键控制、LED状态指示
- 执行机构:直流电机驱动电路
- 保护电路:过充、过放、过流保护
关键元器件清单:
| 类别 | 型号/参数 | 数量 | 备注 |
|---|---|---|---|
| MCU | FS8A15S8 | 1 | 主控制器 |
| 锂电池 | 3.7V 1000mAh | 1 | 供电电源 |
| 充电IC | TP4056 | 1 | 锂电池充电管理 |
| 升压IC | MT3608 | 1 | 可调升压转换 |
| MOS管 | AO3400 | 1 | 电机驱动 |
| 按键 | 6×6mm轻触 | 1 | 用户输入 |
| LED | 0805封装 | 2 | 状态指示 |
1.2 FS8A15S8 MCU特性与引脚分配
FS8A15S8是一款8位低功耗MCU,特别适合小型便携设备应用。其主要特性包括:
- 工作电压:2.4V-5.0V
- 超低静态电流:6μA@5V
- 8个通用I/O口
- 内置振荡器,无需外部晶振
推荐引脚配置:
// 引脚定义 #define KEY_PIN P3_0 // 按键输入 #define LED_LOW_PIN P1_0 // 低档指示灯 #define LED_HIGH_PIN P1_1 // 高档指示灯 #define PWM_OUT_PIN P2_0 // PWM输出控制升压 #define CHG_STAT_PIN P3_1 // 充电状态检测1.3 升压电路设计与参数计算
风扇的不同档位通过调节电机供电电压实现。我们采用MT3608升压芯片,由MCU的PWM信号控制输出电压:
中档:5.5V (PWM占空比40%) 高档:6.8V (PWM占空比60%) 超强档:8V (PWM占空比80%)升压电路关键参数计算:
- 电感选择:4.7μH (饱和电流>2A)
- 反馈电阻:R1=100kΩ, R2=20kΩ (输出电压Vout=0.6*(1+R1/R2))
- 输入电容:10μF陶瓷电容
- 输出电容:22μF低ESR电容
2. 电源管理与充电电路实现
2.1 边充边放功能设计
实现边充边放(pass-through charging)功能需要考虑几个关键点:
- 充电优先级:当接入充电器时,充电电流应优先供给电池
- 系统供电无缝切换:在电池供电和充电器供电间平滑过渡
- 电流分配:确保总电流不超过充电器供给能力
推荐电路连接方式:
Type-C输入 → TP4056充电IC → 锂电池 ↘ 二极管(SS34) → 系统VCC注意:二极管用于防止电池电流倒灌到充电电路,应选择低压降肖特基二极管
2.2 电池保护电路
锂电池安全是便携设备设计的重中之重。除了TP4056自带的充电保护外,我们还需要:
- 过放保护:当电池电压<3.0V时自动关机
- 过流保护:电机电流>1.5A时切断输出
- 温度监测:NTC电阻检测电池温度
保护电路硬件实现:
// 电池电压检测电路 电池+ → 电阻分压(100k+100k) → MCU ADC输入 // 过流检测电路 电机电流 → 0.1Ω采样电阻 → LM358放大 → MCU ADC输入3. 固件开发与功能实现
3.1 系统状态机设计
智能风扇的工作模式可以抽象为以下几个状态:
- 关机状态:等待按键唤醒
- 中档运行:PWM=40%,LED低亮
- 高档运行:PWM=60%,LED高亮
- 超强档运行:PWM=80%,LED闪烁
- 充电状态:红灯常亮
- 充满状态:绿灯常亮
状态转换图:
[关机] ←短按→ [中档] ←短按→ [高档] ←短按→ [超强档] ←短按→ [关机] ↑充电插入 ↑充电插入 ↓充电完成 ↓充电完成 [充电中] -----------------------→ [充满]3.2 PWM控制与电机驱动
FS8A15S8虽然没有硬件PWM模块,但可以通过定时器中断实现软件PWM:
// PWM初始化 void PWM_Init() { TMOD |= 0x01; // 定时器0模式1 TH0 = 0xFF; // 设置重装值 TL0 = 0x00; ET0 = 1; // 使能定时器中断 EA = 1; // 全局中断使能 TR0 = 1; // 启动定时器 } // 定时器0中断服务程序 void Timer0_ISR() interrupt 1 { static uint8_t pwm_counter = 0; pwm_counter++; if(pwm_counter >= 100) pwm_counter = 0; if(pwm_counter < duty_cycle) { PWM_OUT_PIN = 1; // 输出高电平 } else { PWM_OUT_PIN = 0; // 输出低电平 } TH0 = 0xFF; // 重新装载定时值 TL0 = 0x00; }3.3 按键处理与档位切换
采用状态机方式处理按键输入,避免抖动和误触发:
// 按键状态检测 uint8_t Key_Scan() { static uint8_t key_state = 0; static uint16_t key_timer = 0; if(!KEY_PIN) { // 按键按下 if(key_state == 0) { key_state = 1; key_timer = 0; } else if(key_state == 1) { if(++key_timer > 20) { // 消抖20ms key_state = 2; return 1; // 返回有效按键 } } } else { // 按键释放 key_state = 0; } return 0; } // 主循环中的档位切换处理 if(Key_Scan()) { current_mode = (current_mode + 1) % 4; // 循环切换0-3 switch(current_mode) { case 0: // 关机 duty_cycle = 0; LED_Off(); break; case 1: // 中档 duty_cycle = 40; LED_Low(); break; case 2: // 高档 duty_cycle = 60; LED_High(); break; case 3: // 超强档 duty_cycle = 80; LED_Blink(); break; } }4. 安全保护机制实现
4.1 电池电压监测与保护
实时监测电池电压,当电压过低时自动关机:
// 电池电压检测(假设ADC为8位,参考电压3.0V) uint16_t Read_Battery_Voltage() { ADC_CONTR = 0x80 | ADC_CH; // 启动ADC转换 while(!(ADC_CONTR & 0x10)); // 等待转换完成 uint16_t adc_value = ADC_RES; return (adc_value * 3000UL * (R1+R2)/R2) / 255; // 计算实际电压(mV) } // 在主循环中添加保护检查 uint16_t bat_voltage = Read_Battery_Voltage(); if(bat_voltage < 3000 && current_mode != 0) { // 低于3.0V current_mode = 0; // 切换到关机模式 duty_cycle = 0; LED_Off(); }4.2 充电状态检测与指示
通过TP4056的STAT引脚检测充电状态:
// 充电状态检测 void Check_Charge_Status() { if(!CHG_STAT_PIN) { // STAT低电平表示充电中 LED_Red(); } else if(Read_Battery_Voltage() > 4100) { // 电池电压>4.1V LED_Green(); // 充满 } else if(current_mode == 0) { LED_Off(); // 未充电且关机 } // 运行中保持当前LED状态 }4.3 过流保护实现
通过采样电阻检测电机电流,超过阈值时切断输出:
// 电流检测(假设ADC为8位,50mV/A) uint16_t Read_Current() { ADC_CONTR = 0x80 | CURRENT_ADC_CH; while(!(ADC_CONTR & 0x10)); return (ADC_RES * 50000UL / 255) / 50; // 转换为mA } // 在主循环中添加过流保护 uint16_t current = Read_Current(); if(current > 1500) { // 超过1.5A current_mode = 0; duty_cycle = 0; PWM_OUT_PIN = 0; LED_Blink_Fast(); // 快速闪烁表示故障 while(1); // 进入保护状态,需重启 }5. PCB设计要点与调试技巧
5.1 布局与走线建议
电源分区布局:
- 将充电电路、升压电路、MCU电路分区布置
- 大电流路径(如电池到升压电路)走线尽量短而宽
地平面处理:
- 保持完整的地平面
- 模拟地(ADC采样)与数字地单点连接
关键信号线:
- PWM信号线远离模拟信号线
- 反馈电阻靠近升压IC放置
常见PCB设计错误与改进:
| 问题 | 现象 | 解决方案 |
|---|---|---|
| 地线过细 | 系统不稳定,ADC读数跳动 | 加粗地线,使用铺铜 |
| 反馈走线过长 | 输出电压不稳 | 缩短反馈走线,远离噪声源 |
| 未加去耦电容 | MCU复位或死机 | 每个电源引脚加0.1μF电容 |
5.2 系统调试步骤
上电前检查:
- 用万用表检查电源与地之间是否短路
- 确认所有极性元件方向正确
分模块调试:
- 先测试充电电路是否正常工作
- 然后测试MCU最小系统(编程、按键、LED)
- 最后测试升压电路和电机驱动
常见问题排查:
# 问题:升压电路无输出 检查步骤: 1. 测量输入电压是否正常 2. 检查EN引脚是否使能 3. 测量PWM信号是否到达升压IC 4. 检查电感和二极管是否正常 # 问题:边充边放时系统重启 可能原因: - 充电器电流不足(需至少1A) - 二极管压降过大导致系统电压低5.3 功耗优化技巧
- MCU睡眠模式:
- 在关机状态下让MCU进入低功耗模式
- 通过外部中断唤醒
// 进入睡眠模式 void Enter_Sleep_Mode() { PCON |= 0x01; // 进入空闲模式 // 通过外部中断唤醒 } // 初始化外部中断 void INT0_Init() { IT0 = 1; // 下降沿触发 EX0 = 1; // 使能INT0中断 EA = 1; }动态时钟调整:
- 运行时使用较高时钟频率
- 待机时降低时钟频率
外设电源管理:
- 不使用时关闭LED和传感器电源
- 使用MOS管控制外围电路电源
在实际项目中,我发现最耗时的往往是那些看似简单的细节 - 比如按键消抖参数的调整,或是PWM频率与电机特性的匹配。经过几次迭代后,确定将PWM频率设置在1kHz左右既能避免可闻噪声,又能保证电机响应速度。另一个实用技巧是在PCB上预留测试点,特别是电池电压和电流采样点,这大大简化了调试过程。
