4、主控芯片选型:STM32F4系列与ESP32的对比、GPIO分配策略、ADC采样电路设计、看门狗与低功耗设计

好,咱们进入第四章。这一章我打算聊聊主控芯片选型。说实话,这是整个硬件设计的灵魂。芯片选错了,后面再怎么折腾也白搭。

我这些年经手的项目,从楼宇自控到小型商用空调,主控芯片基本就两个阵营:STM32F4系列和ESP32。很多人问我选哪个好。我的回答是——看场景。别盲目跟风,也别一味追求便宜。

4.1 STM32F4 vs ESP32:核心差异在哪?

先说说STM32F4。这芯片我用了快十年了。稳定、可靠、生态成熟。你想想看,一个空调系统要跑十年八年不出问题,STM32F4是经过验证的。它的Cortex-M4内核带FPU,做PID运算、FFT分析,那叫一个丝滑。

ESP32呢?Wi-Fi和蓝牙是它的杀手锏。我去年做一个智能温控器项目,客户要求手机APP远程控制。用ESP32,一片芯片搞定所有,省了外挂Wi-Fi模块的钱和空间。

但ESP32有个坑——它的ADC线性度不太好。我在项目中遇到过,采集温度传感器数据,低端和高端偏差能达到2%以上。做高精度控制,你得额外校准。

对比项 STM32F4 ESP32
核心架构 Cortex-M4F,单核 Xtensa LX6,双核
主频 最高180MHz 最高240MHz
ADC精度 12位,线性度好 12位,线性度一般
无线能力 无(需外挂) Wi-Fi + BLE 内置
功耗 低功耗模式丰富 Wi-Fi开启时功耗较高
工作温度 -40~105°C -40~85°C
价格(批量) 约15-30元 约10-18元

我的建议:做有线控制的中央空调、精密空调,选STM32F4。做家用智能温控器、需要联网的末端设备,选ESP32。别混着用,除非你团队够大、时间够多。

4.2 GPIO分配策略:别等画板子时才发现不够用

GPIO分配这事,看着简单,其实最容易翻车。我见过太多人,原理图画完了,一数引脚,发现不够用。或者够用,但布局走线绕了一大圈。

我个人习惯,先列一个GPIO需求清单。把所有外设列出来:几个温度传感器、几个继电器、几个按键、几个LED、通信接口用哪组。然后按功能分组分配。

举个例子,一个典型的暖通空调控制板:

// GPIO分配示例(STM32F407VGT6)
// 功能组A:传感器接口
PA0 - 室内温度传感器 (ADC1_IN0)
PA1 - 室外温度传感器 (ADC1_IN1)
PA2 - 盘管温度传感器 (ADC1_IN2)
PA3 - 湿度传感器 (ADC1_IN3)

// 功能组B:执行器控制
PB0 - 压缩机继电器 (推挽输出)
PB1 - 四通阀继电器 (推挽输出)
PB2 - 室内风机PWM (定时器输出)
PB3 - 室外风机PWM (定时器输出)

// 功能组C:人机交互
PC0 - 模式按键 (上拉输入)
PC1 - 温度+按键 (上拉输入)
PC2 - 温度-按键 (上拉输入)
PC13 - 运行指示灯 (推挽输出)

// 功能组D:通信接口
PA9 - USART1_TX
PA10 - USART1_RX
PB6 - I2C1_SCL
PB7 - I2C1_SDA

避坑指南:我曾经在一个项目里,把PWM输出和I2C引脚混在同一组。结果PWM干扰导致I2C通信时不时出错。后来花了三天排查,才发现是引脚间距太近、串扰了。所以,高频信号和模拟信号一定要分开,最好隔一个地引脚。

还有一点,留出至少4个备用GPIO。相信我,你一定会用到的。调试阶段加个功能、改个逻辑,有备用引脚就不用重新画板子。

4.3 ADC采样电路设计:精度从电路开始

ADC采样,说白了就是把模拟世界的温度、压力、湿度,变成芯片能理解的数字。但很多人只关注芯片内部的ADC精度,忽略了前端电路。

我常用的NTC温度传感器采样电路,长这样:

// 典型NTC分压电路
// Vref (3.3V) --- R1 (10kΩ 1%) ---+--- NTC (10kΩ@25°C) --- GND
//                                  |
//                                  +--- 到ADC引脚
//                                  |
//                                  C1 (100nF 到GND)

// 计算公式:
// Vout = Vref * Rntc / (R1 + Rntc)
// 温度值通过查表或Steinhart-Hart方程计算

这里有几个要点。第一,分压电阻R1要用1%精度的,别省这几毛钱。第二,ADC引脚对地加一个100nF电容,滤除高频噪声。第三,采样时间要够长。STM32F4的ADC采样时间可以配置,我一般设到15个周期以上。

注意:ESP32的ADC有个特性——它的参考电压不是精确的3.3V,而是随芯片内部变化。我做过测试,同一批ESP32,ADC读数能差3-5个LSB。解决办法:用外部基准电压源,或者做软件校准。我个人习惯用TL431做2.5V基准,精度好很多。

对于压力传感器(比如4-20mA输出的),需要加一个I/V转换电路。用运放把电流转成电压,再送ADC。运放选型要注意轨到轨输入输出,不然低压段会失真。

4.4 看门狗设计:别让系统死得不明不白

看门狗,英文叫Watchdog Timer。它的作用很简单——当程序跑飞了、死循环了,它帮你复位系统。暖通空调系统,一跑就是几个月甚至几年,没有看门狗,你敢放心吗?

STM32F4有独立看门狗(IWDG)和窗口看门狗(WWDG)。我一般用IWDG,因为它用独立的RC振荡器,即使主时钟挂了,它还能工作。

// STM32F4 IWDG配置示例
void IWDG_Config(void)
{
    // 使能写访问
    IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
    
    // 设置预分频器:4分频,约40kHz
    IWDG_SetPrescaler(IWDG_Prescaler_4);
    
    // 设置重装载值:约1秒超时
    // 40kHz / 4 = 10kHz, 10000 / 10000 = 1秒
    IWDG_SetReload(10000);
    
    // 重装载计数器
    IWDG_ReloadCounter();
    
    // 使能IWDG
    IWDG_Enable();
}

// 在主循环中喂狗
void main_loop(void)
{
    while(1)
    {
        // 处理传感器数据
        process_sensors();
        
        // 喂狗
        IWDG_ReloadCounter();
        
        // 处理通信
        process_communication();
        
        // 再次喂狗
        IWDG_ReloadCounter();
    }
}

我的经验:喂狗的位置很关键。别只在主循环开头喂一次。我习惯在关键函数执行完后都喂一次。比如传感器采集完、通信发送完、控制输出完。这样如果某个函数卡住了,看门狗能及时复位。我曾经遇到一个bug,通信模块偶尔死锁,就是因为只在主循环开头喂狗,结果死锁后看门狗没触发,系统一直卡着。

ESP32也有看门狗,但它的机制不太一样。ESP32有任务看门狗(Task WDT)和中断看门狗(Interrupt WDT)。用FreeRTOS的话,任务看门狗更实用——如果某个任务长时间不释放CPU,它会触发。

4.5 低功耗设计:省电就是省钱

低功耗设计,在暖通空调里越来越重要。尤其是那些用电池供电的无线温控器、传感器节点。省电就是省电池,省电池就是省钱。

STM32F4的低功耗模式分三种:睡眠、停止、待机。我常用的是停止模式。它保留了SRAM和寄存器内容,唤醒也快,适合间歇性工作的场景。

// STM32F4进入停止模式示例
void Enter_StopMode(void)
{
    // 关闭不用的外设时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, DISABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, DISABLE);
    
    // 配置唤醒引脚(PA0作为外部中断)
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
    EXTI_InitTypeDef EXTI_InitStructure;
    EXTI_InitStructure.EXTI_Line = EXTI_Line0;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);
    
    // 进入停止模式
    PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
    
    // 唤醒后重新配置系统时钟
    SystemInit();
}

ESP32的低功耗设计更灵活。它有深度睡眠模式,功耗可以低到10μA以下。但要注意,深度睡眠时Wi-Fi和蓝牙都断了。你需要用定时器或者外部中断唤醒。

低功耗设计要点:

  • 关闭不用的外设时钟——这是最容易被忽略的
  • GPIO不要悬空——设成上拉或下拉,避免漏电流
  • ADC在采样完立即关闭——它很耗电
  • 通信模块间歇工作——Wi-Fi不要一直开着,定时收发就行
  • 用外部RTC做定时唤醒——比内部定时器更准、更省电

嗯,这一章内容不少。芯片选型、GPIO分配、ADC电路、看门狗、低功耗,每一个都是实战中必须啃下来的硬骨头。下一章我们聊聊通信协议——Modbus和MQTT,怎么选、怎么用。到时候见。