您当前的位置:首页 > 电子 > 单片机

基于STM32设计的酒精检测仪

时间:11-08来源:作者:点击数:

一、需求分析

随着社会的发展和生活水平的提高,人们对于行车安全、家庭安全的要求越来越高,而酒驾等问题也日渐突出,为此,开发一款基于STM32的酒精检测仪,通过检测酒精浓度,实时显示结果并进行报警,可以有效避免因酒后驾车带来的安全隐患。

image-20230618121603795

二、设计思路

2.1 硬件设计

1、主控芯片采用STM32F103RCT6,该芯片具有较高的性能和稳定性,能够满足本设计的各项需求。

2、酒精传感器采用MQ-3模块,该模块具有高精度、响应速度快等特点,能够准确检测酒精浓度。

3、OLED显示屏,用于实时显示酒精浓度等信息。

4、蜂鸣器,用于进行声音报警。

5、按键,用于设定报警阈值。

2.2 软件设计

1、IO口配置:将相应的IO口配置为输入输出,并使能对应的时钟。

2、ADC配置:将ADC采样通道、采样时间、采样频率等参数进行配置。

3、OLED配置:初始化OLED。

4、中断初始化:对按键进行中断初始化,并在中断服务函数中实现相应的操作。

5、主程序:定时读取酒精传感器的浓度值并将其转换为电压值,然后通过ADC进行采样,最后通过OLED显示屏进行实时显示。同时也需要根据设定的阈值进行判断,并触发相应的报警。

2.3 程序设计思路

main()
{
    初始化IO口
    初始化ADC
    初始化OLED
    配置中断
    while(1)
    {
        读取浓度值并转换为电压
        进行ADC采样
        计算实际浓度值
        显示实时浓度值
        判断是否超过设定阈值
        触发相应的报警
    }
}

void EXTIx_IRQHandler()
{
    检测按键状态
    根据按键状态进行相应的操作
}

三、代码设计

//头文件引用
#include "stm32f10x.h"
#include "OLED.h"
#include "ADC.h"
#include "MQ3.h"

//定义相关参数
#define THRESHOLD1 100
#define THRESHOLD2 200
#define THRESHOLD3 300

//定义中断服务函数
void EXTI0_IRQHandler(){
  if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0){
    threshold++;
    if(threshold == 4) threshold = 1;
    OLED_Clear();
    OLED_ShowString(0,0,"Threshold:");
    switch(threshold){
      case 1:{
        OLED_ShowString(70,0,"100");
        break;
      }
      case 2:{
        OLED_ShowString(70,0,"200");
        break;
      }
      case 3:{
        OLED_ShowString(70,0,"300");
        break;
      }
      default:{
        break;
      }
    }
  }
  EXTI_ClearITPendingBit(EXTI_Line0);
}

int main(void)
{
    //初始化IO口
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOA, ENABLE);   //使能端口时钟
    GPIO_InitTypeDef GPIO_InitStructure;                                           //定义GPIO结构体
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                               //输出模式
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                              //速度50MHz
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;                                     //LED所在引脚
    GPIO_Init(GPIOC, &GPIO_InitStructure);                                         //初始化GPIOC13
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;                          //浮空输入模式
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;                                      //按键所在引脚
    GPIO_Init(GPIOA, &GPIO_InitStructure);                                         //初始化GPIOA0

    //初始化ADC
    ADC_Configuration();

    //初始化OLED
    OLED_Init();
    OLED_Clear();

    //配置中断
    EXTI_InitTypeDef EXTI_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
    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);
    NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    //定义相关变量
    uint16_t adc_value = 0;
    float voltage = 0.0;
    float concentration = 0.0;
    uint8_t threshold = 1;

    while(1)
    {
        //读取酒精传感器的浓度值并转换为电压值
        adc_value = Get_ADC1_ConvertedValue(ADC_Channel_6);
        voltage = (adc_value * 3.3) / 4096;

        //计算实际浓度值
        concentration = Get_MQ3_Concentration(voltage);

        //显示实时浓度值
        OLED_ShowString(0, 0, "Concentration:");
        OLED_ShowNum(100, 0, concentration, 1, 2);

        //判断是否超过设定阈值
        if(concentration > THRESHOLD3){
            GPIO_SetBits(GPIOC, GPIO_Pin_13);      //LED灯亮
            BEEP_ON;                                //蜂鸣器报警
        }
        else if(concentration > THRESHOLD2){
            GPIO_ResetBits(GPIOC, GPIO_Pin_13);    //LED灯灭
            BEEP_OFF;                               //蜂鸣器关闭
        }
        else if(concentration > THRESHOLD1){
            GPIO_SetBits(GPIOC, GPIO_Pin_13);      //LED灯亮
            BEEP_ON;                                //蜂鸣器报警
        }
        else{
            GPIO_ResetBits(GPIOC, GPIO_Pin_13);    //LED灯灭
            BEEP_OFF;                               //蜂鸣器关闭
        }
    }
}
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门
本栏推荐