基于STM32的酒精检测仪设计

一、系统概述与设计目标

1. 核心功能

  • 酒精浓度检测:实时检测环境中的酒精浓度(支持mg/L、ppm、%BAC单位)
  • 结果显示:LCD/OLED显示浓度值、状态图标及报警阈值
  • 声光报警:浓度超标时触发蜂鸣器+LED闪烁报警
  • 数据存储:记录历史检测数据(时间、浓度)
  • 校准功能:支持零点校准和量程校准(应对传感器漂移)
  • 低功耗设计:便携式场景下电池供电(续航≥8小时)

2. 技术指标

参数 指标 说明
检测范围 0.01~5.00 mg/L 覆盖酒驾(0.2mg/L)至醉酒(2.0mg/L)
分辨率 0.01 mg/L 12位ADC采集,精度±5%FS
响应时间 ≤30秒(90%响应) MQ-3传感器典型响应时间
预热时间 ≤120秒 传感器加热至稳定工作状态
报警阈值 0.2 mg/L(可自定义) 对应酒驾标准(GB 19522-2010)
工作电压 3.3~5V DC 锂电池供电(3.7V/2000mAh)
整机功耗 ≤50mA(工作)/≤10μA(待机) 低功耗模式延长续航

二、硬件设计方案

1. 核心元器件选型

模块 型号 关键参数 接口方式
主控MCU STM32F103C8T6 72MHz Cortex-M3,12位ADC,64KB Flash 核心控制器
酒精传感器 MQ-3 检测范围0.1~5mg/L,加热电压5V 模拟输出(0~5V)
温度传感器 DS18B20 ±0.5℃精度,单总线接口 单总线(GPIO)
显示模块 OLED 12864(I2C) 0.96寸,128×64像素,低功耗 I2C(PB6/PB7)
报警模块 有源蜂鸣器+LED 5V驱动,声压≥85dB GPIO(PA0/PA1)
存储模块 AT24C02 2KB EEPROM,I2C接口 I2C(PB6/PB7复用)
按键模块 轻触按键×3 校准、开关机、阈值设置 GPIO(PA2/PA3/PA4)
电源模块 TP4056+AMS1117 锂电池充电(1A)+3.3V稳压输出 充电/供电一体化

2. 硬件电路设计

2.1 主控最小系统
  • 时钟电路:8MHz外部晶振+32.768kHz RTC晶振(低功耗计时)
  • 复位电路:10kΩ上拉电阻+0.1μF电容(手动复位+上电复位)
  • 调试接口:SWD(PA13/SWIO,PA14/SWCLK),支持ST-Link下载
2.2 酒精传感器(MQ-3)接口电路

MQ-3为半导体气敏传感器,需加热至300℃左右才能工作,电路设计要点:

c 复制代码
// MQ-3接口电路
VCC(5V) → [加热丝] → MOS管(Q1) → GND  
         │  
         ├─[负载电阻RL=10kΩ]─┬─[ADC输入]→ STM32 PA5(ADC1_IN5)  
         │                   │  
         └─[滤波电容C1=10μF]─┘  

// 加热控制:STM32 PB5输出PWM(占空比50%)驱动MOS管,控制加热功率

注意:MQ-3预热期间(约120秒)输出不稳定,需忽略初期数据。

2.3 信号调理电路(ADC采集)

MQ-3输出模拟电压范围0~5V,STM32 ADC参考电压3.3V,需分压处理:

c 复制代码
// 分压电路(5V→3.3V)
ADC输入 = MQ-3输出 × (R2/(R1+R2))  
取R1=10kΩ,R2=20kΩ → 分压比=2/3,5V→3.33V(接近3.3V上限)
2.4 电源电路
  • 锂电池充电:TP4056模块(Micro USB输入,支持过充保护)
  • 稳压输出:AMS1117-3.3V(给STM32、OLED供电)+ 5V升压模块(给MQ-3加热丝供电)
  • 低功耗设计:STM32进入STOP模式时,关闭OLED、传感器加热(仅保留RTC和按键唤醒)

三、软件设计与核心代码

1. 系统主程序框架(HAL库)

c 复制代码
#include "stm32f1xx_hal.h"
#include "mq3_sensor.h"
#include "oled_display.h"
#include "buzzer.h"
#include "ds18b20.h"
#include "at24c02.h"

// 全局变量
float alcohol_concentration = 0.0;  // 酒精浓度(mg/L)
uint8_t alarm_flag = 0;             // 报警标志
uint32_t preheat_time = 0;           // 预热时间(ms)

int main(void) {
  HAL_Init();                     // 初始化HAL库
  SystemClock_Config();           // 配置系统时钟(72MHz)
  MX_GPIO_Init();                 // GPIO初始化
  MX_ADC1_Init();                  // ADC初始化(MQ-3采集)
  MX_I2C1_Init();                  // I2C初始化(OLED/AT24C02)
  MX_TIM2_Init();                  // 定时器初始化(PWM加热控制)
  
  OLED_Init();                    // OLED显示初始化
  DS18B20_Init();                  // 温度传感器初始化
  Buzzer_Init();                   // 蜂鸣器初始化
  AT24C02_Init();                  // EEPROM初始化
  
  Show_SplashScreen();             // 开机画面
  Preheat_Sensor();                // 传感器预热(120秒)
  
  while (1) {
    // 1. 采集传感器数据
    alcohol_concentration = MQ3_ReadConcentration();  // ADC采集+浓度转换
    float temp = DS18B20_ReadTemp();                   // 读取温度(补偿用)
    
    // 2. 温度补偿(MQ-3受温度影响±2%/℃)
    alcohol_concentration *= (1 + 0.02*(25 - temp));  // 25℃为基准温度
    
    // 3. 显示结果
    OLED_UpdateDisplay(alcohol_concentration, temp, alarm_flag);
    
    // 4. 报警判断(阈值0.2mg/L)
    if (alcohol_concentration > ALARM_THRESHOLD) {
      alarm_flag = 1;
      Buzzer_Alert(ON);           // 蜂鸣器报警
      LED_Alert(BLINK);           // LED闪烁
    } else {
      alarm_flag = 0;
      Buzzer_Alert(OFF);
      LED_Alert(OFF);
    }
    
    // 5. 数据存储(每小时存储1次)
    if (HAL_GetTick() - last_save_time > 3600000) {
      AT24C02_SaveData(alcohol_concentration, temp);
      last_save_time = HAL_GetTick();
    }
    
    // 6. 低功耗处理(无操作时进入STOP模式)
    if (no_operation_time > 300000) {  // 5分钟无操作
      Enter_LowPowerMode();
    }
    
    HAL_Delay(1000);  // 1秒刷新一次
  }
}

2. MQ-3传感器驱动(ADC采集与浓度转换)

2.1 ADC采集与校准
c 复制代码
// MQ-3传感器驱动头文件(mq3_sensor.h)
#define MQ3_ADC_CHANNEL ADC_CHANNEL_5  // PA5
#define RL_VALUE 10.0                  // 负载电阻(kΩ)
#define RO_VALUE 6.8                   // 传感器内阻(kΩ,校准得到)

// 标定气体浓度对应的ADC值(需实验测定)
const float CAL_POINTS[3][2] = {
  {0.1, 820},   // 0.1mg/L → ADC=820
  {1.0, 2048},  // 1.0mg/L → ADC=2048
  {5.0, 4095}   // 5.0mg/L → ADC=4095(满量程)
};

// 读取ADC原始值
uint16_t MQ3_ReadRawADC(void) {
  HAL_ADC_Start(&hadc1);
  HAL_ADC_PollForConversion(&hadc1, 10);
  return HAL_ADC_GetValue(&hadc1);
}

// ADC值转换为酒精浓度(mg/L)
float MQ3_RawToConcentration(uint16_t adc_value) {
  float rs_ro_ratio = (5.0 * RL_VALUE * 4095) / (adc_value * RO_VALUE * 3.3) - RL_VALUE/RO_VALUE;
  // 分段线性插值(简化计算)
  if (rs_ro_ratio > 10.0) return 0.1;       // 极低浓度
  else if (rs_ro_ratio > 2.5) return 0.1 + (10.0-rs_ro_ratio)*(0.9)/(7.5);  // 0.1~1.0mg/L
  else if (rs_ro_ratio > 0.5) return 1.0 + (2.5-rs_ro_ratio)*(4.0)/(2.0);    // 1.0~5.0mg/L
  else return 5.0;                           // 高浓度饱和
}

3. OLED显示驱动(I2C接口)

c 复制代码
// OLED显示浓度与状态
void OLED_UpdateDisplay(float conc, float temp, uint8_t alarm) {
  char buf[32];
  
  // 清屏
  OLED_Clear();
  
  // 显示标题
  OLED_ShowString(0, 0, "Alcohol Detector", 16);
  
  // 显示浓度(保留2位小数)
  sprintf(buf, "Conc: %.2f mg/L", conc);
  OLED_ShowString(0, 2, buf, 16);
  
  // 显示温度
  sprintf(buf, "Temp: %.1f C", temp);
  OLED_ShowString(0, 4, buf, 16);
  
  // 显示报警状态
  if (alarm) {
    OLED_ShowString(0, 6, "!!! ALARM !!!", 16);  // 红色字体(需OLED支持)
    OLED_DrawBitmap(100, 6, alert_icon);         // 报警图标
  } else {
    OLED_ShowString(0, 6, "Status: Normal", 16);
  }
  
  OLED_Refresh();  // 刷新屏幕
}

4. 低功耗模式设计

c 复制代码
// 进入STOP模式(保留RTC和按键唤醒)
void Enter_LowPowerMode(void) {
  OLED_Sleep(ON);               // OLED休眠
  HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_1);  // 关闭MQ-3加热PWM
  __HAL_RCC_ADC1_CLK_DISABLE();  // 关闭ADC时钟
  
  // 配置唤醒源(PA2按键中断)
  HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);  // PA0/WKUP引脚(需调整)
  
  HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
  
  // 唤醒后恢复
  SystemClock_Config();           // 重新配置时钟
  MX_ADC1_Init();                  // 重启ADC
  HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);  // 重启加热PWM
  OLED_Sleep(OFF);                // OLED唤醒
}

参考代码 基于STM32酒精检测仪设计 www.youwenfan.com/contentcsu/133725.html

四、校准方法与标定流程

1. 零点校准(洁净空气)

  1. 将传感器置于洁净空气中(酒精浓度≈0)
  2. 采集ADC原始值(记为ADC_zero)
  3. 计算传感器内阻RO:
    RO=RL×VCC−VADC_zeroVADC_zeroRO = RL \times \frac{V_{CC} - V_{ADC\zero}}{V{ADC\_zero}}RO=RL×VADC_zeroVCC−VADC_zero
    (V_CC=5V,V_ADC_zero为ADC_zero对应的电压值)

2. 量程校准(标准气体)

使用已知浓度的酒精气体(如0.5mg/L、2.0mg/L)进行标定:

  1. 通入0.5mg/L气体,记录ADC值ADC_0.5,拟合曲线斜率k1
  2. 通入2.0mg/L气体,记录ADC值ADC_2.0,拟合曲线斜率k2
  3. 建立分段线性方程:
    浓度={k1×(ADC−ADC_zero)(ADC<ADC_mid)k2×(ADC−ADC_zero)+b(ADC≥ADC_mid)\text{浓度} = \begin{cases} k1 \times (ADC - ADC\_zero) & (ADC < ADC\_mid) \\ k2 \times (ADC - ADC\_zero) + b & (ADC \geq ADC\_mid) \end{cases}浓度={k1×(ADC−ADC_zero)k2×(ADC−ADC_zero)+b(ADC<ADC_mid)(ADC≥ADC_mid)

3. 温度补偿校准

在不同温度下(如15℃、25℃、35℃)重复上述标定,建立温度-浓度修正系数表,软件中实时查表补偿。

五、系统调试与优化

1. 调试步骤

阶段 操作 预期结果
硬件检查 测量VCC/GND电压(5V/3.3V)、传感器加热丝电压 电压稳定,无短路
ADC校准 采集洁净空气ADC值(应接近0V对应值) ADC值在100~300范围内(分压后)
传感器预热 上电后等待120秒,观察ADC值是否稳定 预热后ADC波动<±2%
报警测试 通入0.3mg/L酒精气体 触发声光报警,OLED显示超标

2. 常见问题解决

问题 原因 解决方案
浓度显示跳变大 环境气流不稳定/传感器接触不良 增加软件滤波(中值滤波+滑动平均)
预热后无输出 加热丝损坏/供电不足 测量加热丝电压(应≈5V),更换传感器
低浓度检测不灵敏 负载电阻RL过大/传感器老化 减小RL(如5kΩ),更换新传感器
温度补偿无效 温度传感器安装位置不当 将DS18B20贴近MQ-3传感器安装

六、扩展功能与进阶设计

1. 手机APP通信(蓝牙)

  • 模块:HC-05蓝牙模块(UART接口,PA9/PA10)
  • 功能:实时传输浓度数据,APP端显示趋势图、设置报警阈值
  • 协议 :自定义JSON格式(如{"conc":0.25,"temp":26.5,"alarm":1}

2. 数据上传云端(WiFi)

  • 模块:ESP8266-12F(UART接口,透传模式)
  • 平台:阿里云IoT/腾讯云(MQTT协议)
  • 功能:远程监控、历史数据查询、多设备组网

3. 微型化设计

  • PCB优化:4层板设计,缩小尺寸至5cm×3cm
  • 传感器集成:选用MEMS酒精传感器(如MP-802,尺寸3mm×3mm)
  • 电源管理:采用低功耗STM32L0系列(待机电流<1μA)

七、总结

本设计基于STM32F103C8T6和MQ-3传感器,实现了酒精浓度的实时检测、显示、报警及数据存储功能。通过硬件分压电路、软件滤波和温度补偿,确保了检测精度(±5%FS);低功耗设计(STOP模式+按需加热)满足了便携式需求。系统可广泛应用于酒驾检测、工业安全、家庭安防等场景,具有较高的实用价值和市场潜力。

相关推荐
点灯小铭19 小时前
基于单片机的锅炉压力与温度监测报警系统设计
数据库·单片机·嵌入式硬件·毕业设计·课程设计·期末大作业
环境倒逼我学习19 小时前
无人机地面站之第13章 Mission Planner 入门与界面总览
单片机·嵌入式硬件·无人机
大阳12319 小时前
ARM.8(ADC,SPI)
单片机·嵌入式硬件·adc·spi
hoiii18720 小时前
基于 STM32 的标准遥控器架构与源码
stm32·嵌入式硬件·架构
少年、潜行20 小时前
STM32 ISP 升级体验
stm32·嵌入式硬件·isp升级·系统编程区域
杨连江20 小时前
一种三模式可调气隙式双侧定子滑移可变磁通轴向永磁电机
单片机·嵌入式硬件
Aaron15881 天前
无人机反制中AOA+TDOA联合定位技术与雷达探测定位技术的应用对比分析
arm开发·嵌入式硬件·fpga开发·硬件工程·无人机·信息与通信·信号处理
foundbug9991 天前
STM32 睡眠模式测试程序
stm32·单片机·嵌入式硬件
wxmtwfx1 天前
littlefs 源码分析
单片机·littlefs·嵌入式文件系统
嵌入式小站1 天前
STM32 零基础可移植教程 18:I2C 入门,先用扫描器找一找总线上有没有设备
chrome·stm32·嵌入式硬件