用STM32和TB6612打造智能温控风扇从硬件搭建到闭环控制1. 项目构思与核心组件解析炎炎夏日一个能根据环境温度自动调节风速的智能风扇不仅实用还能让你深入理解嵌入式系统的闭环控制原理。这个项目将STM32微控制器的强大处理能力与TB6612电机驱动模块的高效控制相结合通过温湿度传感器实现环境感知最终构建出一个完整的智能温控系统。核心组件选型考量STM32F103C8T6作为主流ARM Cortex-M3内核微控制器72MHz主频和丰富的外设接口完全满足本项目需求TB6612FNG相比传统L298N这款驱动芯片效率更高最高达95%支持1.2A连续电流输出DHT11低成本数字温湿度传感器±2℃精度足以满足家用场景直流电机建议选择额定电压5-6V的微型电机转速在2000-3000RPM为宜提示采购元件时注意TB6612的版本市场上有些兼容模块引脚定义可能略有不同2. 硬件系统搭建与电路设计2.1 电机驱动电路连接TB6612作为双通道H桥驱动芯片其接线需要特别注意电源隔离和信号匹配。以下是关键连接点模块引脚连接目标注意事项VM6V电源正极需单独供电不与MCU共用VCC5V逻辑电源可来自STM32开发板PWMAPB0(TIM3_CH3)PWM信号输出引脚AIN1PB7GPIO控制方向AIN2PB3GPIO控制方向A01/A02电机两极极性决定转向可反接测试GND共地连接必须确保所有GND连通电源配置要点为电机准备独立的6V电源如4节AA电池STM32开发板通过USB或稳压电源供电所有GND必须相互连接形成统一参考地2.2 传感器模块集成DHT11温湿度传感器采用单总线协议接线简单但需注意时序// DHT11典型连接方式 VCC - 3.3V DATA - PA1 (需上拉4.7K电阻) GND - GND3. 软件架构与核心代码实现3.1 PWM调速基础配置利用STM32的定时器产生PWM信号控制电机转速void TIM3_PWM_Init(u16 arr, u16 psc) { GPIO_InitTypeDef GPIO_InitStruct; TIM_TimeBaseInitTypeDef TIM_BaseStruct; TIM_OCInitTypeDef TIM_OCStruct; // 使能时钟和GPIO RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); // 配置PB0为复用推挽输出 GPIO_InitStruct.GPIO_Pin GPIO_Pin_0; GPIO_InitStruct.GPIO_Mode GPIO_Mode_AF_PP; GPIO_InitStruct.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOB, GPIO_InitStruct); // 定时器基础配置 TIM_BaseStruct.TIM_Period arr; // 自动重装载值 TIM_BaseStruct.TIM_Prescaler psc; // 预分频系数 TIM_BaseStruct.TIM_ClockDivision 0; TIM_BaseStruct.TIM_CounterMode TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, TIM_BaseStruct); // PWM模式配置 TIM_OCStruct.TIM_OCMode TIM_OCMode_PWM2; TIM_OCStruct.TIM_OutputState TIM_OutputState_Enable; TIM_OCStruct.TIM_OCPolarity TIM_OCPolarity_High; TIM_OC3Init(TIM3, TIM_OCStruct); TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable); TIM_Cmd(TIM3, ENABLE); }3.2 温度采集与滤波处理DHT11数据读取需要严格遵循时序要求#define DHT11_GPIO_PORT GPIOA #define DHT11_GPIO_PIN GPIO_Pin_1 u8 DHT11_Read_Data(u8 *temp, u8 *humi) { u8 buf[5] {0}; u8 retry 0; // 主机启动信号 GPIO_ResetBits(DHT11_GPIO_PORT, DHT11_GPIO_PIN); Delay_ms(18); GPIO_SetBits(DHT11_GPIO_PORT, DHT11_GPIO_PIN); Delay_us(30); // 等待从机响应 while(GPIO_ReadInputDataBit(DHT11_GPIO_PORT, DHT11_GPIO_PIN) retry100) { retry; Delay_us(1); } if(retry100) return 1; // 数据接收 for(int i0; i5; i) { for(int j0; j8; j) { while(!GPIO_ReadInputDataBit(DHT11_GPIO_PORT, DHT11_GPIO_PIN)); Delay_us(40); buf[i] 1; if(GPIO_ReadInputDataBit(DHT11_GPIO_PORT, DHT11_GPIO_PIN)) { buf[i] | 1; while(GPIO_ReadInputDataBit(DHT11_GPIO_PORT, DHT11_GPIO_PIN)); } } } // 校验和数据验证 if(buf[0] buf[1] buf[2] buf[3] buf[4]) { *humi buf[0]; *temp buf[2]; return 0; } return 2; }3.3 闭环控制算法实现采用增量式PID算法实现温度闭环控制typedef struct { float Kp, Ki, Kd; float error, lastError; float integral, maxIntegral; float output, maxOutput; } PID_Controller; void PID_Init(PID_Controller *pid, float kp, float ki, float kd, float maxI, float maxOut) { pid-Kp kp; pid-Ki ki; pid-Kd kd; pid-maxIntegral maxI; pid-maxOutput maxOut; pid-error pid-lastError pid-integral pid-output 0; } float PID_Calculate(PID_Controller *pid, float setpoint, float measurement) { pid-lastError pid-error; pid-error setpoint - measurement; pid-integral pid-error; if(pid-integral pid-maxIntegral) pid-integral pid-maxIntegral; else if(pid-integral -pid-maxIntegral) pid-integral -pid-maxIntegral; float derivative pid-error - pid-lastError; pid-output pid-Kp * pid-error pid-Ki * pid-integral pid-Kd * derivative; if(pid-output pid-maxOutput) pid-output pid-maxOutput; else if(pid-output 0) pid-output 0; return pid-output; }4. 系统集成与优化技巧4.1 主控制逻辑实现将各模块功能整合到主循环中int main(void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); Delay_init(); USART1_Init(115200); TIM3_PWM_Init(999, 71); // PWM频率72MHz/(9991)/(711)1kHz Motor_GPIO_Init(); DHT11_Init(); PID_Controller tempPID; PID_Init(tempPID, 10.0, 0.1, 2.0, 100.0, 1000.0); float targetTemp 28.0; // 默认目标温度28℃ while(1) { u8 temperature, humidity; if(DHT11_Read_Data(temperature, humidity) 0) { printf(Temp: %d℃, Humi: %d%%\r\n, temperature, humidity); float pwmValue PID_Calculate(tempPID, targetTemp, temperature); TIM_SetCompare3(TIM3, (u16)pwmValue); if(temperature targetTemp) { Motor_Forward(); // 温度高于设定值正转 } else { Motor_Stop(); // 温度低于设定值停止 } } Delay_ms(2000); // 每2秒采样一次 } }4.2 性能优化与调试技巧常见问题排查指南电机不转检查STBY引脚是否接高电平确认VM和VCC供电正常用万用表测量PWM信号是否输出转速不稳定增加电源滤波电容100μF电解电容并联0.1μF陶瓷电容检查代码中PWM频率设置建议1kHz-5kHz确保所有GND连接可靠温度读数异常检查DATA线上拉电阻4.7KΩ确保时序严格符合DHT11规格要求避免在读取过程中被中断打断PID参数整定经验值比例系数Kp5-15响应速度积分系数Ki0.05-0.2消除静差微分系数Kd1-5抑制振荡5. 功能扩展与进阶方向5.1 蓝牙无线控制集成通过HC-05模块增加手机控制功能// 蓝牙指令处理示例 void USART1_IRQHandler(void) { if(USART_GetITStatus(USART1, USART_IT_RXNE) ! RESET) { u8 cmd USART_ReceiveData(USART1); switch(cmd) { case 1: targetTemp 1.0; break; // 温度 case 2: targetTemp - 1.0; break; // 温度- case 3: Motor_Forward(); break; // 手动开启 case 4: Motor_Stop(); break; // 手动关闭 } } }5.2 多模式控制策略实现不同场景下的控制策略切换enum FanMode { AUTO, MANUAL, SCHEDULE, ECO }; enum FanMode currentMode AUTO; void Mode_Switch(void) { static u8 modeCount 0; modeCount (modeCount 1) % 4; currentMode (enum FanMode)modeCount; switch(currentMode) { case AUTO: // 自动温控模式 break; case MANUAL: // 手动调速模式 break; case SCHEDULE: // 定时运行模式 break; case ECO: // 节能模式降低最大转速 break; } }5.3 能耗监测与优化通过电流传感器实现能耗统计float currentSense, powerConsumption; void ADC1_Init(void) { ADC_InitTypeDef ADC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); ADC_InitStructure.ADC_Mode ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode DISABLE; ADC_InitStructure.ADC_ContinuousConvMode ENABLE; ADC_InitStructure.ADC_ExternalTrigConv ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel 1; ADC_Init(ADC1, ADC_InitStructure); ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5); ADC_Cmd(ADC1, ENABLE); ADC_ResetCalibration(ADC1); while(ADC_GetResetCalibrationStatus(ADC1)); ADC_StartCalibration(ADC1); while(ADC_GetCalibrationStatus(ADC1)); ADC_SoftwareStartConvCmd(ADC1, ENABLE); } void Calculate_Power(void) { u16 adcValue ADC_GetConversionValue(ADC1); currentSense (float)adcValue * 3.3 / 4096 * 10; // 假设10倍放大 powerConsumption currentSense * 6.0; // 6V供电电压 }在实际项目中我发现电机的启动电流往往比稳态运行高3-5倍因此软启动策略对延长电池寿命特别重要。一个简单的实现方法是让PWM占空比从0开始在500ms内线性增加到目标值这样可以有效降低启动冲击。