随着社会的发展和生活水平的提高,人们对于行车安全、家庭安全的要求越来越高,而酒驾等问题也日渐突出,为此,开发一款基于STM32的酒精检测仪,通过检测酒精浓度,实时显示结果并进行报警,可以有效避免因酒后驾车带来的安全隐患。
1、主控芯片采用STM32F103RCT6,该芯片具有较高的性能和稳定性,能够满足本设计的各项需求。
2、酒精传感器采用MQ-3模块,该模块具有高精度、响应速度快等特点,能够准确检测酒精浓度。
3、OLED显示屏,用于实时显示酒精浓度等信息。
4、蜂鸣器,用于进行声音报警。
5、按键,用于设定报警阈值。
1、IO口配置:将相应的IO口配置为输入输出,并使能对应的时钟。
2、ADC配置:将ADC采样通道、采样时间、采样频率等参数进行配置。
3、OLED配置:初始化OLED。
4、中断初始化:对按键进行中断初始化,并在中断服务函数中实现相应的操作。
5、主程序:定时读取酒精传感器的浓度值并将其转换为电压值,然后通过ADC进行采样,最后通过OLED显示屏进行实时显示。同时也需要根据设定的阈值进行判断,并触发相应的报警。
- 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; //蜂鸣器关闭
- }
- }
- }
-