STM32F103C8T6 · HAL库开发 · AO-03电化学探头 · 5V供电
HB-021氧气传感器模块由精密运放电路搭配奥松(Aosong)公司的AO-03电化学氧气传感器组合而成。
AO-03采用原电池(伽伐尼)式工作原理,无需外部电源即可工作。
传感器内部包含铅阳极和氧阴极,中间填充电解液。当环境中的氧气通过透气膜扩散进入传感器内部时,
在阴极发生还原反应 O₂ + 2H₂O + 4e⁻ → 4OH⁻,
在阳极发生氧化反应 2Pb + 4OH⁻ → 2PbO + 2H₂O + 4e⁻。
整个反应产生的电流与氧气浓度成正比,AO-03在空气中输出约0.1±0.03mA的微弱电流信号。
HB-021模块内部的精密运放电路将该微弱电流转换为0.1~0.6V的模拟电压信号,由OUT引脚输出至STM32的ADC采集。
OUT引脚输出0.1~0.6V模拟电压信号,由模块内部精密运放电路将AO-03传感器的微弱电流放大后输出。
通过标定系数53.59和偏差校准值,将采集到的电压值线性转换为氧气浓度百分比。
0.96寸OLED显示屏通过软件I2C驱动,实时居中显示当前氧气浓度数值。
程序中的偏差值为标定参数,可根据空气中20.9%的氧气浓度基准进行校准修正。
| 引脚 | 名称 | 功能 | STM32连接 |
|---|---|---|---|
| VCC | 电源正极 | 5V供电输入 | 5V |
| GND | 电源地 | 接地 | GND |
| OUT | 模拟输出 | 0.1~0.6V模拟电压,与O₂浓度成正比 | PA0 (ADC1_IN0) |
HB-021氧气传感器模块正面
HB-021氧气传感器模块背面(AO-03电化学探头)
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
// 使用外部高速晶振 HSE 8MHz
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; // 8MHz × 9 = 72MHz
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
Error_Handler();
// 系统时钟 = PLL = 72MHz
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; // HCLK = 72MHz
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; // APB1 = 36MHz
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; // APB2 = 72MHz
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
Error_Handler();
// ADC时钟 = APB2 / 8 = 9MHz
PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV8;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
}void MX_GPIO_Init(void)
{
// 使能GPIO时钟
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
}void MX_ADC1_Init(void)
{
ADC_ChannelConfTypeDef sConfig = {0};
hadc1.Instance = ADC1;
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE; // 非扫描模式
hadc1.Init.ContinuousConvMode = DISABLE; // 单次转换
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; // 软件触发
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; // 数据右对齐
hadc1.Init.NbrOfConversion = 1; // 1个转换通道
HAL_ADC_Init(&hadc1);
sConfig.Channel = ADC_CHANNEL_0; // 通道0 → PA0
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5; // 239.5周期采样
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(adcHandle->Instance == ADC1)
{
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
// PA0 → ADC1_IN0 模拟输入
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
}// 引脚定义
#define SCL_Port GPIOB
#define SCL_Pin GPIO_PIN_15
#define SDA_Port GPIOB
#define SDA_Pin GPIO_PIN_14
void OLED_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOB_CLK_ENABLE();
// SCL和SDA配置为开漏输出
GPIO_InitStruct.Pin = SCL_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
HAL_GPIO_Init(SCL_Port, &GPIO_InitStruct);
GPIO_InitStruct.Pin = SDA_Pin;
HAL_GPIO_Init(SDA_Port, &GPIO_InitStruct);
// 释放总线
OLED_W_SCL(1);
OLED_W_SDA(1);
}
void OLED_Init(void)
{
OLED_GPIO_Init(); // 引脚初始化
OLED_WriteCommand(0xAE); // 关闭显示
OLED_WriteCommand(0xD5); // 设置时钟分频
OLED_WriteCommand(0x80);
// ... 其他初始化命令省略 ...
OLED_WriteCommand(0xAF); // 开启显示
OLED_Clear();
OLED_Update();
}// 全局变量
uint32_t Time_Now; // 时间戳
float Voltage; // 电压值
float O2; // 氧气浓度
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_ADC1_Init();
OLED_Init();
while (1)
{
if(HAL_GetTick() - Time_Now >= 200) // 每200ms更新一次
{
// 单通道数据获取
HAL_ADC_Start(&hadc1);
if(HAL_ADC_PollForConversion(&hadc1, 999) == HAL_OK)
Voltage = (HAL_ADC_GetValue(&hadc1) / 4095.0) * 3.3;
HAL_ADC_Stop(&hadc1);
// 偏差值为标定校准,空气中氧气含量约20.9%,请修改此值校准
O2 = (53.59 * Voltage + 1.2);
OLED_Clear(); // 清屏
OLED_CenterPrintf(24, "氧气:%.1f", O2); // 居中显示
OLED_Update(); // 更新显示
Time_Now = HAL_GetTick(); // 更新时间戳
}
}
}STM32的ADC为12位分辨率,原始值范围0~4095。参考电压3.3V,将原始值线性映射到实际电压值。 HB-021模块OUT引脚输出范围为0.1~0.6V。
系数53.59为HB-021模块运放电路的标定灵敏度,偏差值通过校准确定(本程序为+1.2)。 AO-03传感器在空气中输出约0.1±0.03mA电流,经模块运放电路放大后对应约0.366V电压, 此时O₂读数约为20.9%。AO-03的线性测量范围为0~30%Vol,响应时间T90<15秒,预期使用寿命约2年。
| 环境状态 | 估算电压(V) | ADC原始值 | O₂浓度(%) |
|---|---|---|---|
| 低氧环境(~5%) | ~0.071 | ~88 | ~5.0 |
| 低氧环境(~10%) | ~0.164 | ~204 | ~10.0 |
| 正常空气 | ~0.366 | ~454 | ~20.9 |
| 富氧环境(~25%) | ~0.444 | ~551 | ~25.0 |