一.MQ3酒精测量模块的使用
首先我们先讲解MQ3酒精测量模块的使用方法,下面是我使用的酒精测量模块的图片
这个模块的使用如下,D0可以悬空不接,A0接STM32的ADC通道口,这里我接的是PA0口也就是通道0口接好过后我们就可以开始测试代码了
二、stm32代码
首先是ADC电压采集的初始化和酒精浓度的测量公式的计算
adc.c
#include "adc.h"
//
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//STM32C8T6开发板
//ADC通道初始化
//闲鱼关注:强哥电子701;CSDN:Dandelion701:B站:Dandelion701
//修改日期:2024.1.17
//
u16 Value = 0;
void ADC_UserConfig(void){
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1|RCC_APB2Periph_AFIO,ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div6);//72/6=12
GPIO_InitStructure.GPIO_Pin = ADC1_Pin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//模拟输入
GPIO_Init(ADC_PROT,&GPIO_InitStructure);
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //独立模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE; //单通道
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //连续转换
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//软件触发方式
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//数据又对去
ADC_InitStructure.ADC_NbrOfChannel = 1;//单通道
ADC_Init(ADC1,&ADC_InitStructure);
ADC_ClearFlag(ADC1,ADC_FLAG_EOC);//清除中断标志位
ADC_ITConfig(ADC1,ADC_IT_EOC,ENABLE);//开启中断
ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_239Cycles5);//规则组239.5us
ADC_Cmd(ADC1,ENABLE);
ADC_ResetCalibration(ADC1);//ADC复位
while(ADC_GetResetCalibrationStatus(ADC1));//等待ADC复位结束
//为了让数据更加精确
ADC_StartCalibration(ADC1);//开始校验
while(ADC_GetSoftwareStartConvStatus(ADC1));//等待校验结束
ADC_SoftwareStartConvCmd(ADC1,ENABLE);//开启软件触发
NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn;//选择ADC1入口中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//子占优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能中断
NVIC_Init(&NVIC_InitStructure);
}
float ADCx_MQ_3(void){
float Temp = 0;
for(u8 i=0;i<10;i++){
Temp +=Value;
}
Temp/=10;//10次平均值
return Temp * 125/4095;
}
void ADC1_2_IRQHandler(void){
if(ADC_GetITStatus(ADC1,ADC_IT_EOC) !=RESET){
Value = ADC_GetConversionValue(ADC1);
ADC_ClearITPendingBit(ADC1,ADC_IT_EOC);//清空中断标志位
}
}
adc.h
#ifndef __ADC_H
#define __ADC_H
#include "sys.h"
#include "delay.h"
#include "stdio.h"
extern u16 Value;
#define ADC1_Pin GPIO_Pin_0
#define ADC_PROT GPIOA//MQ-3酒精
void ADC_UserConfig(void);
float ADCx_MQ_3(void);
#endif
下面是主函数的运行
main.c
#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"
#include "time.h"
#include "myiic.h"
#include "oled.h"
#include "beep.h"
#include "SR602.h"
#include "dht11.h"
#include "MOTOR.h"
#include "adc.h"
int i=0;
u8 string[30] = {0},string1[30] = {0};
void Use_MQ_3(void)
{
sprintf((char *)string,"MQ3:%f",ADCx_MQ_3());
OLED_ShowString(1,40,string,8,1);
}
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先
delay_init();//延时函数初始化
uart_init(115200);//串口2
LED_Init();
OLED_Init();//oled显示屏初始化
OLED_ColorTurn(0); //0正常显示,1 反色显示
OLED_DisplayTurn(0); //屏幕旋转180度调整
ADC_UserConfig();//ADC通道初始化
while(1)
{
OLED_Refresh();//oled刷新
Use_MQ_3();
}
}
请注意:本次使用的是ADC单通道的电压采集,如果大家需要多通道的ADC电压采集后面我会更新!
三.实验结果
没有沾酒精的正常状态如下:
用纸站上酒精,oled显示如下:
可以看到,在遇到酒精过后,发生了巨大的变化。
最后谢谢大家的观看!