用STM32F103和L9110S做个桌面小风扇吧(OLED显示档位+流水灯效果)
用STM32F103和L9110S打造智能桌面小风扇OLED显示炫彩灯效在炎热的夏季一个能带来清凉的小风扇总能让人心情愉悦。但如果你是一名电子爱好者为什么不自己动手制作一个独一无二的智能桌面风扇呢今天我们就来用STM32F103微控制器和L9110S电机驱动模块打造一个集实用与趣味于一体的DIY小风扇项目。这个项目不仅能让你的桌面多一份清凉还能通过OLED屏幕实时显示风扇档位配合炫彩的LED流水灯效果让这个小制作既实用又充满科技感。相比市面上普通的USB小风扇我们的DIY版本可以完全自定义功能比如调节风速、改变灯效模式甚至未来可以扩展加入温度感应自动调速等智能功能。1. 项目准备与硬件选型1.1 核心硬件组件要完成这个项目我们需要准备以下主要硬件组件STM32F103C8T6开发板或兼容的Blue Pill板作为项目的大脑负责控制所有外设L9110S电机驱动模块用于驱动小型直流风扇电机0.96寸OLED显示屏I2C接口显示风扇状态和档位信息5V小型直流风扇建议选择电流在0.5A以下的型号LED灯带或4个独立LED用于实现流水灯效果4个轻触开关用于控制风扇档位和功能切换面包板和杜邦线用于原型搭建1.2 硬件连接指南正确的硬件连接是项目成功的关键。以下是主要模块的连接方式模块STM32引脚连接说明L9110S IAPA8电机控制PWM信号AL911S IBPA9电机控制PWM信号BOLED SCLPB6I2C1时钟线OLED SDAPB7I2C1数据线按键1PA0低速档控制外部中断按键2PA1中速档控制外部中断按键3PA2高速档控制外部中断按键4PA3复位/关闭外部中断LED1PC13流水灯效果LED1LED2PC14流水灯效果LED2LED3PC15流水灯效果LED3LED4PB8流水灯效果LED4提示在实际连接时建议使用不同颜色的杜邦线区分电源、地和信号线这将大大减少接线错误的风险。2. 开发环境配置2.1 软件工具准备开始编码前我们需要安装和配置以下开发工具STM32CubeMX用于生成初始化代码和配置外设Keil MDK-ARM或PlatformIO作为主要的开发IDEST-Link Utility用于程序烧录和调试串口调试工具如Putty或Tera Term用于调试输出2.2 STM32CubeMX工程配置使用STM32CubeMX可以快速完成硬件外设的初始化配置创建新工程选择对应的STM32F103C8T6型号配置时钟树将系统时钟设置为72MHz启用I2C1接口OLED显示屏配置TIM1的通道1和2为PWM输出电机控制设置PA0-PA3为外部中断输入按键控制配置PC13-PC15和PB8为GPIO输出LED控制生成MDK-ARM工程代码// CubeMX生成的部分关键配置代码 static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct {0}; /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); /*Configure GPIO pins : PA0-PA3 */ GPIO_InitStruct.Pin GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3; GPIO_InitStruct.Mode GPIO_MODE_IT_RISING; GPIO_InitStruct.Pull GPIO_PULLDOWN; HAL_GPIO_Init(GPIOA, GPIO_InitStruct); /*Configure GPIO pins : PC13-PC15|PB8 */ GPIO_InitStruct.Pin GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15; GPIO_InitStruct.Mode GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull GPIO_NOPULL; GPIO_InitStruct.Speed GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOC, GPIO_InitStruct); GPIO_InitStruct.Pin GPIO_PIN_8; HAL_GPIO_Init(GPIOB, GPIO_InitStruct); }3. 核心功能实现3.1 电机PWM控制L9110S电机驱动模块需要两路PWM信号来控制电机的转速和方向。在我们的项目中我们只需要单向转动因此可以将IB引脚接地通过IA引脚的PWM信号来控制转速。// 初始化PWM HAL_TIM_PWM_Start(htim1, TIM_CHANNEL_1); // 启动TIM1通道1 PWM // 设置风扇转速函数 void set_fan_speed(uint8_t speed) { // speed范围0-100对应占空比0%-100% __HAL_TIM_SET_COMPARE(htim1, TIM_CHANNEL_1, speed); current_speed speed; update_display(); // 更新OLED显示 }3.2 OLED显示实现OLED显示屏可以直观地展示风扇的当前状态。我们需要实现以下显示功能当前风速档位低速/中速/高速当前PWM占空比百分比自定义欢迎界面和关机界面// OLED显示更新函数 void update_display(void) { OLED_Clear(); OLED_ShowString(0, 0, Smart Fan v1.0); switch(current_speed) { case 0: OLED_ShowString(0, 2, Status: OFF); break; case 30: OLED_ShowString(0, 2, Status: LOW); OLED_ShowString(0, 3, Duty: 30%); break; case 60: OLED_ShowString(0, 2, Status: MEDIUM); OLED_ShowString(0, 3, Duty: 60%); break; case 90: OLED_ShowString(0, 2, Status: HIGH); OLED_ShowString(0, 3, Duty: 90%); break; default: OLED_ShowString(0, 2, Status: CUSTOM); char buf[16]; sprintf(buf, Duty: %d%%, current_speed); OLED_ShowString(0, 3, buf); } }3.3 按键中断处理四个按键分别对应不同的功能按键1低速档30%占空比按键2中速档60%占空比按键3高速档90%占空比按键4关闭风扇// 外部中断回调函数 void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if(GPIO_Pin GPIO_PIN_0) { // 按键1 set_fan_speed(30); set_led_mode(1); } else if(GPIO_Pin GPIO_PIN_1) { // 按键2 set_fan_speed(60); set_led_mode(2); } else if(GPIO_Pin GPIO_PIN_2) { // 按键3 set_fan_speed(90); set_led_mode(3); } else if(GPIO_Pin GPIO_PIN_3) { // 按键4 set_fan_speed(0); set_led_mode(0); } }4. 炫彩LED效果实现4.1 流水灯模式设计为了让这个小风扇更具观赏性我们设计了四种LED流水灯模式模式0所有LED关闭风扇关闭状态模式1双LED交替闪烁低速档模式2三LED波浪效果中速档模式3四LED跑马灯效果高速档// LED模式设置函数 void set_led_mode(uint8_t mode) { current_led_mode mode; // 重置所有LED状态 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET); } // 在主循环中处理LED效果 void handle_led_effects(void) { static uint32_t last_tick 0; if(HAL_GetTick() - last_tick 200) return; // 200ms间隔 last_tick HAL_GetTick(); static uint8_t led_state 0; switch(current_led_mode) { case 1: // 双LED交替 if(led_state % 2 0) { HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13); HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_14); } else { HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13|GPIO_PIN_14); } led_state; break; case 2: // 三LED波浪 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15, GPIO_PIN_SET); switch(led_state % 3) { case 0: HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET); break; case 1: HAL_GPIO_WritePin(GPIOC, GPIO_PIN_14, GPIO_PIN_RESET); break; case 2: HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_RESET); break; } led_state; break; case 3: // 四LED跑马灯 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET); switch(led_state % 4) { case 0: HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET); break; case 1: HAL_GPIO_WritePin(GPIOC, GPIO_PIN_14, GPIO_PIN_RESET); break; case 2: HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_RESET); break; case 3: HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET); break; } led_state; break; default: // 所有LED关闭 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET); } }4.2 主程序逻辑将所有功能模块整合到主程序中int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_I2C1_Init(); MX_TIM1_Init(); OLED_Init(); OLED_Clear(); OLED_ShowString(0, 0, Smart Fan); OLED_ShowString(0, 2, Initializing...); HAL_Delay(1000); set_fan_speed(0); // 初始状态关闭 while (1) { handle_led_effects(); // 其他后台任务可以放在这里 } }5. 项目优化与扩展5.1 电源管理优化为了提升项目的实用性我们可以考虑以下电源优化措施添加锂电池供电电路实现便携功能设计低功耗模式当风扇不使用时自动进入睡眠增加充电管理电路和充电状态显示5.2 功能扩展建议这个基础项目可以进一步扩展更多有趣的功能温度感应自动调速添加DS18B20温度传感器根据环境温度自动调节风扇转速无线控制通过蓝牙或WiFi模块实现手机APP控制RGB LED效果将单色LED替换为WS2812 RGB灯带实现更丰富的灯光效果档位记忆功能使用STM32的Flash存储保存用户最后设置的档位// 温度感应自动调速示例代码 void check_temp_and_adjust(void) { float temp read_temperature(); // 假设有这个函数 if(temp 30.0) { set_fan_speed(90); } else if(temp 26.0) { set_fan_speed(60); } else if(temp 23.0) { set_fan_speed(30); } else { set_fan_speed(0); } }5.3 外壳设计与制作为了让项目更加完整可以考虑3D打印或手工制作一个精致的外壳设计合理的风道提高风扇效率为OLED屏幕和LED灯预留展示窗口合理安排按键位置便于操作考虑散热设计防止长时间工作过热在实际制作过程中我发现将电子元件合理布局在外壳内是一个不小的挑战。特别是要确保风扇电机不会干扰其他电子元件的工作同时还要保证整体美观。经过几次尝试最终采用了分层设计底部是控制电路中间是电池顶部是风扇和显示部分。