)
STM32智能台灯DIY全攻略从硬件选型到手机APP控制附完整代码深夜的书桌前一盏能自动调节亮度、感知人体存在的智能台灯或许正是每个熬夜工作学习者的理想伴侣。本文将带你从零开始用STM32打造一款具备环境光自适应、人体感应和手机远程控制功能的智能台灯系统。1. 硬件选型与电路设计1.1 核心控制器选择STM32F103C8T6俗称蓝莓派是性价比极高的选择72MHz主频的Cortex-M3内核64KB Flash 20KB SRAM丰富的GPIO和外设接口淘宝价格约15-25元// STM32最小系统电路示例 #include stm32f10x.h void SystemInit(void) { // 时钟配置 RCC-CR | RCC_CR_HSEON; // 开启外部晶振 while(!(RCC-CR RCC_CR_HSERDY)); // 等待晶振稳定 RCC-CFGR | RCC_CFGR_PLLMULL9; // 9倍频 RCC-CFGR | RCC_CFGR_PLLSRC; // HSE作为PLL输入 RCC-CR | RCC_CR_PLLON; // 开启PLL while(!(RCC-CR RCC_CR_PLLRDY)); // 等待PLL锁定 RCC-CFGR | RCC_CFGR_SW_PLL; // PLL作为系统时钟 while((RCC-CFGR RCC_CFGR_SWS) ! RCC_CFGR_SWS_PLL); // 切换完成 }1.2 传感器模块选型传感器类型推荐型号接口方式单价特点人体感应HC-SR501GPIO输入¥8探测距离7米可调延时光敏电阻GL5516ADC采集¥2光谱特性接近人眼环境光BH1750I2C¥150-65535 lux量程提示BH1750比传统光敏电阻精度更高且自带数字输出减少ADC配置复杂度1.3 LED驱动方案PWM调光是最经济高效的方案使用STM32的TIM1/2/3/4产生PWMMOSFET驱动电路如IRLZ44N恒流驱动确保LED寿命# PWM占空比与亮度关系实验数据 pwm_duty [0, 25, 50, 75, 100] lux_value [0, 150, 320, 490, 650] # 实测照度值2. 系统软件架构设计2.1 开发环境搭建推荐工具链组合STM32CubeMX初始化代码生成Keil MDK-ARM编译调试ST-Link V2下载调试器关键库安装# STM32CubeF1库 git clone https://github.com/STMicroelectronics/STM32CubeF1 # HAL库文档位于Drivers/STM32F1xx_HAL_Driver/Inc2.2 多任务调度设计采用前后台系统架构前台中断服务程序定时器中断1ms外部中断人体感应后台主循环光线采集与处理PWM输出控制蓝牙通信处理// 主循环示例 while(1) { static uint32_t tick 0; if(HAL_GetTick() - tick 100) { // 100ms周期 tick HAL_GetTick(); LightSensor_Update(); AutoBrightness_Adjust(); Bluetooth_Process(); } LED_Refresh(); // PWM实时更新 }3. 核心功能实现3.1 自适应调光算法采用PID控制实现平滑亮度过渡// PID参数 #define KP 0.8 #define KI 0.1 #define KD 0.05 float PID_Control(float target, float current) { static float integral 0, last_err 0; float err target - current; integral err; float derivative err - last_err; last_err err; return KP*err KI*integral KD*derivative; }光照度分级策略环境光照(lux)推荐亮度(%)适用场景50100黑暗环境50-20070夜间阅读200-50050台灯补光50030白天辅助3.2 蓝牙APP控制实现使用HC-05模块的AT指令配置ATNAMESmartLamp // 设置设备名称 ATPSWD1234 // 设置配对密码 ATUART9600,0,0 // 设置串口参数Android端关键代码// Bluetooth连接处理 private class ConnectThread extends Thread { private final BluetoothSocket mmSocket; public void run() { mmSocket.connect(); manageConnectedSocket(mmSocket); } void sendBrightness(int value) { String cmd BRIGHT: value \n; mmSocket.getOutputStream().write(cmd.getBytes()); } }4. 系统优化与调试技巧4.1 PWM频率选择LED调光的黄金法则频率100Hz避免闪烁但过高频率会导致MOSFET发热推荐1-3kHz范围// TIM3 PWM初始化示例 TIM_HandleTypeDef htim3; htim3.Instance TIM3; htim3.Init.Prescaler 72-1; // 1MHz htim3.Init.CounterMode TIM_COUNTERMODE_UP; htim3.Init.Period 1000-1; // 1kHz htim3.Init.ClockDivision TIM_CLOCKDIVISION_DIV1; HAL_TIM_PWM_Init(htim3);4.2 抗干扰设计常见问题解决方案人体感应误触发增加软件消抖连续3次检测调整传感器灵敏度电位器蓝牙连接不稳定保持模块与天线距离5cm添加10μF去耦电容LED闪烁检查电源功率是否足够增加PWM滤波电容100nF注意调试时建议先用USB供电稳定后再切换至外部电源5. 进阶功能扩展5.1 坐姿检测方案通过超声波模块HC-SR04实现float Get_Distance(void) { HAL_GPIO_Write(TRIG_PIN, GPIO_PIN_SET); delay_us(10); HAL_GPIO_Write(TRIG_PIN, GPIO_PIN_RESET); while(!HAL_GPIO_Read(ECHO_PIN)); uint32_t start HAL_GetTick(); while(HAL_GPIO_Read(ECHO_PIN)); uint32_t duration HAL_GetTick() - start; return duration * 0.034 / 2; // cm }5.2 能耗统计功能基于STM32内部ADC监测电流I (ADC_Value * 3.3 / 4096) / R_sense 能耗 Σ(I * V * Δt)5.3 OTA无线升级通过蓝牙实现固件更新将hex文件转为bin格式APP分段发送数据Bootloader写入Flash// Bootloader跳转代码 void JumpToApp(void) { typedef void (*pFunction)(void); pFunction Jump_To_Application; uint32_t JumpAddress *(__IO uint32_t*)(APP_ADDRESS 4); Jump_To_Application (pFunction)JumpAddress; __set_MSP(*(__IO uint32_t*)APP_ADDRESS); Jump_To_Application(); }完整项目代码结构/SmartLamp ├── /Drivers # HAL库文件 ├── /Inc │ ├── main.h │ ├── bluetooth.h │ └── sensors.h ├── /Src │ ├── main.c # 主程序 │ ├── pwm.c # 调光控制 │ └── ble_comm.c # 蓝牙处理 ├── /App │ ├── android # APP源码 │ └── ios # APP源码 └── /Hardware ├── schematic.pdf # 原理图 └── pcb_layout # PCB设计文件在项目开发过程中建议先分模块测试如单独测试PWM调光功能再逐步集成。当蓝牙连接出现问题时可以用串口助手监控通信数据这是我调试时发现最有效的排错方法。