一、前言
我这张STM32气敏传感器PCB使用五颗HHC1000封装气敏传感器,组成五路传感器阵列。
每一颗传感器都有两类接口:
加热接口:
HEAT_IN / HEAT_OUT
检测接口:
3.3V / RS_OUT
五颗传感器的检测部分相互独立,分别输出五路电压;五个加热丝则并联在一起,由PA6控制。
整条信号链可以概括为:
气敏传感器电阻Rs
↓
和100K负载电阻分压
↓
RS_OUT电压
↓
RC滤波
↓
AD8606电压跟随器
↓
STM32 ADC输入PA1~PA5
↓
ADC码值
↓
换算成电压、电阻和气体浓度
二、五路传感器阵列的整体连接
每一颗HHC1000的检测部分可以等效成一个随气体浓度变化的电阻Rs。
以第一路为例:
3.3V
|
Rs
|
RS_OUT ───── ADC前端
|
RL
|
GND
其中:
Rs:气敏传感器内部等效电阻;RL:PCB上的负载电阻;RS_OUT:分压输出电压;3.3V:检测电极的激励电压。
当气体浓度变化时,Rs发生变化,RS_OUT电压也跟着变化。
所以STM32测到的其实不是"气体浓度",而是:
气敏电阻Rs和100K负载电阻RL的分压电压
然后通过软件反推出Rs,再根据传感器特性曲线换算浓度。
三、五颗传感器具体怎么接
我的PCB中,五颗传感器的检测端、负载电阻、AD8606和ADC通道对应关系如下:
| 通道 | 传感器检测输出 | 负载电阻 | 运放 | STM32 ADC |
|---|---|---|---|---|
| CH1 | PAD16 | R22 100K | U9 AD8606 | PA1 / ADC1_IN1 |
| CH2 | PAD20 | R20 100K | U3 AD8606 | PA2 / ADC1_IN2 |
| CH3 | PAD4 | R15 100K | U2 AD8606 | PA3 / ADC1_IN3 |
| CH4 | PAD8 | R26 100K | U11 AD8606 | PA4 / ADC1_IN4 |
| CH5 | PAD12 | R24 100K | U10 AD8606 | PA5 / ADC1_IN5 |
每个通道旁边还有一组并联预留焊位:
R16、R21、R23、R25、R27
这些是和100K负载电阻并联的备用位置,实际只焊一个电阻即可。当前工程中主要焊的是:
R15、R20、R22、R24、R26
也就是:
每一路 RL = 100KΩ
四、检测电压的计算原理
每一路都是电阻分压电路:
3.3V ── Rs ── RS_OUT ── RL ── GND
根据分压公式:
V_RS_OUT = 3.3V × RL / (Rs + RL)
因为:
RL = 100KΩ
所以:
V_RS_OUT = 3.3V × 100K / (Rs + 100K)
由此可以反推出传感器电阻:
Rs = RL × (3.3V - V_RS_OUT) / V_RS_OUT
例如:
- Rs变大,RS_OUT电压降低;
- Rs变小,RS_OUT电压升高;
- 如果Rs接近0Ω,RS_OUT接近3.3V;
- 如果Rs接近无穷大,RS_OUT接近0V。
实际气敏传感器的Rs通常在几十kΩ到几MΩ之间,所以RS_OUT一般处在几百mV到几V之间。
五、为什么每路都要加AD8606跟随器
传感器分压点RS_OUT的内阻大约等于:
Rs // RL
这个内阻可能比较高,不能直接接到STM32的ADC。
原因是STM32的ADC采样时会有一个采样保持电容,瞬间从输入节点抽取电荷。如果信号源内阻太高,ADC测量会偏小、跳变或者不稳定。
所以每一路都加了一颗AD8606,接成电压跟随器:
AD8606:
3脚 = +IN
2脚 = -IN
1脚 = OUT
连接方式:
1脚和2脚短接
也就是:
RS_OUT → AD8606的+IN
AD8606的OUT → AD8606的-IN
AD8606的OUT → STM32 ADC
电压跟随器的作用是:
- 输入阻抗很高,几乎不从RS_OUT取电流;
- 输出阻抗很低,可以轻松驱动STM32 ADC;
- 输出电压约等于输入电压;
- 隔离传感器节点和ADC采样电路;
- 提高五路电压测量的稳定性和一致性。
AD8606使用:
V+ = 3.3V
V- = GND
属于单电源、轨到轨输入输出运放,适合STM32的0~3.3V ADC范围。
六、每一路的完整信号链
以CH1为例:
3.3V
|
Rs1
|
PAD16 → RS_OUT1
|
R22 100K
|
GND
RS_OUT1
|
C23/C24对地滤波
|
U9 AD8606 +IN
|
U9 AD8606 OUT
|
PA1 / ADC1_IN1
其他四路完全相同:
CH2:PAD20 → R20 100K → U3 AD8606 → PA2
CH3:PAD4 → R15 100K → U2 AD8606 → PA3
CH4:PAD8 → R26 100K → U11 AD8606 → PA4
CH5:PAD12 → R24 100K → U10 AD8606 → PA5
因此,STM32采集到的是五路RS_OUT电压经过跟随器后的电压:
Vadc1 ≈ V_RS_OUT1
Vadc2 ≈ V_RS_OUT2
Vadc3 ≈ V_RS_OUT3
Vadc4 ≈ V_RS_OUT4
Vadc5 ≈ V_RS_OUT5
七、RS_OUT处的RC滤波
每一路RS_OUT到GND都预留了电容位置:
C19~C28
它们和:
Rs // RL
一起构成一个低通滤波器,用来滤除高频噪声和加热PWM干扰。
等效关系:
RS_OUT对地电阻 ≈ Rs // 100K
截止频率大约为:
fc = 1 / (2πRC)
如果:
R = 100KΩ
C = 10nF
则:
fc ≈ 1 / (2π × 100K × 10nF)
≈ 159Hz
如果:
C = 100nF
则:
fc ≈ 15.9Hz
所以电容不能随便选:
- 电容越大,噪声越小,但响应越慢;
- 电容越小,响应越快,但抗干扰能力弱;
- 气敏传感器本身响应较慢,因此通常可以选10nF~100nF;
- 最终值要结合传感器响应速度、加热PWM干扰和ADC稳定性来选择。
注意:滤波电容应该接在RS_OUT和GND之间,不能接在运放输入和输出之间。接在输入输出之间会形成正反馈,容易导致运放自激振荡。
八、五路ADC与代码的对应关系
STM32F103C8T6的ADC是12位:
ADC码值 = V入 / VDDA × 4095
如果VDDA约为3.3V:
V入 = ADC码值 / 4095 × 3.3V
五路ADC通道对应:
PA1 = ADC1_IN1
PA2 = ADC1_IN2
PA3 = ADC1_IN3
PA4 = ADC1_IN4
PA5 = ADC1_IN5
所以代码中ADC通道数组应写成:
static const uint8_t ADC_CH[5] = {
ADC_Channel_1,
ADC_Channel_2,
ADC_Channel_3,
ADC_Channel_4,
ADC_Channel_5
};
不能写成:
PA0~PA4
因为PA0没有接传感器,接的是PA1~PA5。
九、从电压反推气敏电阻和浓度
1. 反推气敏电阻
Rs = RL × (Vc - V_RS_OUT) / V_RS_OUT
其中:
RL = 100KΩ
Vc = 3.3V
V_RS_OUT = 跟随器输出电压
例如测到:
V_RS_OUT = 1.0V
则:
Rs = 100K × (3.3 - 1.0) / 1.0
= 230KΩ
2. 换算浓度
MOX类气敏传感器通常使用Rs/R0曲线:
浓度 ppm ≈ a × (Rs / R0)^b
其中:
R0:洁净空气中的基准电阻;a、b:传感器厂家给出的曲线拟合系数;- 不同气体、不同传感器需要单独标定。
如果使用简单的线性标定,也可以写成:
ppm = (V - V0) × K
但这只适合小范围近似,不能代表整个传感器量程。
十、五个加热丝的关系
五颗传感器的加热丝不是独立的,而是:
五颗传感器HEAT_IN全部并在一起
五颗传感器HEAT_OUT全部并在一起
也就是:
HEAT_IN ──┬── 加热丝1 ──┬── HEAT_OUT
├── 加热丝2 ──┤
├── 加热丝3 ──┤
├── 加热丝4 ──┤
└── 加热丝5 ──┘
所以五个加热丝是并联关系。
这带来两个结果:
- 加热总电流是单颗加热丝的5倍左右;
- 如果其中一颗加热丝短路,会影响整个加热阵列。
加热阵列由PA6控制Q1,再控制公共的HEAT_IN:
PA6 → Q1栅极
Q1 → HEAT_IN
HEAT_OUT → 电流采样/地
检测部分和加热部分是相互独立的:
- 加热丝负责把传感器加热到工作温度;
- 3.3V/RS_OUT负责测量气敏电阻;
- 两者不能混在一起。
十一、电路优点
这套五路传感器阵列电路有几个明显优点:
- 五路检测完全独立;
- 每一路都有独立的100K负载电阻,不会相互串扰;
- 每一路都有AD8606跟随器,适合高内阻传感器;
- 检测电极使用3.3V供电,和STM32 ADC参考电压一致,具有一定比例抵消作用;
- 五路输出分别接到PA1~PA5,方便用ADC1依次采集;
- 传感器分压结构简单,容易计算Rs;
- 每路都预留了滤波电容位置,方便后期调整噪声和响应速度。
十二、需要注意和改进的地方
1. 负载电阻要根据传感器量程选
每路RL当前是100K。
如果传感器在目标气体中的Rs范围大约为:
10K ~ 1M
那么100K是一个比较居中、比较合理的选择。
但如果实际Rs经常低于10K,RS_OUT会接近3.3V,容易饱和;如果Rs经常高于1M,RS_OUT会接近0V,分辨率会下降。这时可以调整RL。
2. 未使用的运放通道不要悬空
AD8606是双运放,每颗只用了其中一个通道,另一个通道的5、6、7脚目前没有使用。
建议把未使用通道接成跟随器:
+IN → GND或3.3V/2
OUT → -IN
不要把未使用运放输入悬空,否则可能自激、振荡或引入噪声。
3. 滤波电容要实测选择
C19~C28要根据实际噪声和响应速度选择:
10nF ~ 100nF
如果加热PWM干扰明显,先用示波器观察RS_OUT,再决定电容值。
4. ADC采样要做平均和滤波
建议:
- 每路连续采样多次;
- 去掉最大值和最小值;
- 再做平均值;
- 使用VREFINT校准VDDA;
- 不要在加热PWM开关瞬间采样。
5. 浓度换算必须标定
STM32读到的是电压,不是ppm。
正确的流程是:
ADC码值
→ 计算RS_OUT电压
→ 计算Rs
→ 结合R0和传感器曲线
→ 计算ppm
不同传感器、不同气体、不同温湿度都需要重新标定。
十三、总结
这张PCB的五路气敏传感器阵列可以概括为:
五颗传感器
↓
每颗传感器检测电阻Rs
↓
Rs与100K负载电阻分压
↓
得到五路RS_OUT电压
↓
AD8606跟随器缓冲
↓
STM32 PA1~PA5 ADC采集
↓
计算Rs
↓
换算气体浓度
五路检测信号分别对应:
CH1 → PA1
CH2 → PA2
CH3 → PA3
CH4 → PA4
CH5 → PA5
核心公式是:
V_RS_OUT = 3.3V × 100K / (Rs + 100K)
Rs = 100K × (3.3V - V_RS_OUT) / V_RS_OUT
而五个加热丝则是并联在一起,由PA6通过MOSFET统一控制。
所以整个传感器阵列的本质就是:
五路独立的电阻分压测量 + 五路AD8606缓冲 + 五路STM32 ADC采集,加热部分则采用五路加热丝并联的公共加热结构。
15:36
