10.[STM32]ADC中断方式-采集MQ-3酒精传感器检测的酒精浓度

文章目录

  • 1. ADC介绍
  • 1.1 时钟配置及设置模拟输入
  • 1.2 ADC初始化
  • 1.3 ADC状态寄存器
  • 1.4 ADC控制寄存器
  • 1.4.1 ADC控制寄存器 1(ADC_CR1)
  • 1.4.2 ADC控制寄存器 2(ADC_CR2)
  • 1.4.3 函数ADC_RegularChannelConfig
  • 2 MQ-3酒精传感器简介
  • 3.结语
  • 🍌
    🍌🍌
    作者简介:大家好啊,我叫DW,每天分享一些我新学到的知识,期待和大家一起进步
    🍋
    🍋🍋
    系列专栏:STM32
    🍎
    🍎🍎
    🍎🍎🍎
    🌞小实验目标:利用ADC功能获取MQ-3酒精传感器采集的数据🌞
    🍊如有写得不好的地方欢迎大家指正🍊
    🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎
    每天写点东西,记录下学习的过程,慢慢积累,每天都可以进步一点点
    🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎
    创作时间:🍊🍊🍊2022年4月27日🍊🍊🍊

    1. ADC介绍

    12位ADC是一种逐次逼近型模拟数字转换器。它有多达18个通道,可测量16个外部和2个内部信号源。各通道的A/D转换可以单次、连续、扫描或间断模式执行。ADC的结果可以左对齐或右对齐方式存储在16位数据寄存器中。

    🎵🎵小提示:
    ADC的输入时钟不得超过14MHz,它是由PCLK2经分频产生。

    本次实验用到的是ADC1的通道0,它对应着PA0引脚,ADC的引脚分布图如下:

    1.1 时钟配置及设置模拟输入

    ADC1挂载在APB2时钟总线上,RCC控制器为ADC时钟提供一个专用的可编程预分频器。STM32系统时钟为72Mhz,由于ADC的输入时钟不得超过14MHz,故我们需要利用函数RCC_ADCCLKConfig将72Mhz分频,我选择6分频。查看STM32固件库使用手册,里面包含分频器的具体参数介绍和使用例程:

    STM32F103 的 ADC 1的通道 0 在 PA0 上,所以,我们先要使能 PORTA 的时钟,然后设置 PA0为模拟输入。

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1|RCC_APB2Periph_AFIO,ENABLE);
    	
    RCC_ADCCLKConfig(RCC_PCLK2_Div6);//72/6=12Mhz
    
    GPIO_InitStructure.GPIO_Pin = ADC1_Pin;//宏定义PA0
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//模拟输入
    GPIO_Init(ADC_PROT,&GPIO_InitStructure);
    

    1.2 ADC初始化

    在库函数中是通过函数 ADC_Init 实现的,下面我们看看其定义:

    void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct);
    

    从函数定义可以看出,第一个参数是指定 ADC 号。这里我们来看看第二个参数是通过设置结构体成员变量的值来设定参数。
    这个结构体里定义了6个参数
    第一个ADC模式选择,包括独立模式和,注入同步模式等等。
    我选择独立模式( ADC_Mode_Independent)
    第二个是否开启扫描模式,我使用的是单通道单次转换,所以这里我们选择不开启(DISABLE)。
    第三个是否开启连续转换模式我选择开启连续转换模式(ENABLE)。
    第四个设置启动规则转换组转换的外部事件,这里我们选择软件触发,选择值为 :
    ADC_ExternalTrigConv_None 即可。
    第五个ADC 数据对齐方式,这里我们选择右对齐方式ADC_DataAlign_Right。
    第六个规则序列的长度,我们实验只开启一个通道,所以值为 1 即可。

    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);
    

    1.3 ADC状态寄存器


    位1 规则组转换结束EOC,0转换未完成,1转换完成,在中断处理函数中将会用到。

    1.4 ADC控制寄存器

    ADC含两个控制寄存器分别为ADC_CR1 ADC_CR2

    1.4.1 ADC控制寄存器 1(ADC_CR1)


    就简单说说一下今天用到的位,其他位的说明,大家可以看看STM32参考手册。

    位19:16:可以选择对应的模式,本次使用选择独立模式,所以这几位置0即可,在库函数版本中已经定义好了,我们直接用就可以了。


    位8:此模式用来扫描一组模拟通道。
    扫描模式可通过设置ADC_CR1寄存器的SCAN位来选择。一旦这个位被设置,ADC扫描所有被ADC_SQRX寄存器(对规则通道)或ADC_JSQR(对注入通道)选中的所有通道。在每个组的每个通道上执行单次转换。在每个转换结束时,同一组的下一个通道被自动转换。如果设置了CONT位,转换不会在选择组的最后一个通道上停止,而是再次从选择组的第一个通道继续转换。如果设置了DMA位,在每次EOC后,DMA控制器把规则组通道的转换数据传输到SRAM中。而注入通道转换的数据总是存储在ADC_JDRx寄存器中。
    本次实验使用关闭扫描模式,位8置0

    1.4.2 ADC控制寄存器 2(ADC_CR2)

    位19:17:用于选择启动规则转换组转换的外部事件。这里使用的是软件触发(SWSTART),所以设置这 3 个位为 111。

    17-19位置1,对应的二进制为:0000 0000 0000 1110 0000 0000 0000 0000
    对应的16进制为:0x000E0000

    位11:ADC_CR2寄存器中的ALIGN位选择转换后数据储存的对齐方式,数据可以左对齐或右对齐。我选择右对齐,将该位置0

    位3:2:复位校准 (Reset calibration)和A/D校准 (A/D Calibration)
    执行复位校准和 AD 校准,注意这两步是必须的!不校准将导致结果很不准确。

    ADC_ResetCalibration(ADC1);//ADC复位
    	while(ADC_GetResetCalibrationStatus(ADC1));//等待ADC复位结束
    	
    	//为了让数据更加精确
    	ADC_StartCalibration(ADC1);//开始校验
    	while(ADC_GetSoftwareStartConvStatus(ADC1));//等待校验结束
    
    

    位1:是否开启连续转换,我选择开启连续转换,将该位置1

    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;		//连续转换
    

    位0:ADON 位用于开关 AD 转换器。

    其通过ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState)这个函数使能,该函数定义如下:

    使能方法为:

    ADC_Cmd(ADC1,ENABLE);
    

    1.4.3 函数ADC_RegularChannelConfig


    该函数可以设定ADC的通道,设定它们的转换顺序和时间,本次我用到的是ADC1的通道0,选择单次采样,采样时间为 239.5 周期

    	ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_239Cycles5);//规则组239.5us
    

    之后配置相应中断参数:

    NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_Init(&NVIC_InitStructure);
    

    2 MQ-3酒精传感器简介

    MQ-3 气体传感器所使用的气敏材料是在清洁空气中电导率较低的二氧化锡(SnO2)。当传感器所处环境中存在酒精蒸气时,传感器的电导率随空气中 酒精蒸气浓度的增加而增大。使用简单的电路即可将电导率的变化转换为与该气体浓度相对应的输出信号。MQ-3 气体传感器对酒精的灵敏度高,可以抵抗汽油、烟雾、水蒸气的干扰。

    优点:
    这种传感器可检测多种浓度酒精气氛,是一款适合多种应用的低成本传感器。其广泛适用于车用酒精气体报警器、工业用酒精气体报警器以及便携式气体检测器。
    缺点:
    需要预热,稳定性较差,受环境温度;不宜应用于计量准确要求的场所
    规格参数:
    1.探测范围:10~1000ppm酒精
    2. 特征气体:125ppm酒精
    3. 加热电压:5±0.2V(AC·DC)
    4. 回路电压:≤24V DC
    5. 负载电阻:可调
    6. 清洁空气中电压:≤1.5V
    7. 灵敏度:Rin air/Rin typical gas≥5
    8. 响应时间:≤10S
    9. 恢复时间:≤30S
    10.元件功耗:≤0.9W
    11.主要芯片:LM393、MQ-3气体传感器
    12.使用寿命:5年

    DO输出:TTL数字量0和1(可以不接)
    AO:模拟量输出端口

    接线图:

    由于是125ppm酒精,故采集的ppm转换公式为:

    Temp * 125/4095;//Temp为获取的AD采样值
    

    测试程序:

    u16 Value = 0;
    
    float ADCx_AverageValue(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);//清空中断标志位
    	
    	}
    }
    
    

    连接酒精传感器后,串口打印的ppm值稳定在34

    把酒精靠近MQ-3传感器看到ppm上升

    3.结语

    今天的分享就到这里,希望能和大家一起进步,有什么疑问请留言,谢谢大家的耐心阅读,如果觉得有用的话给个👍👍👍

    🌜🌜🌜本章结束,我们下一章见🌜🌜🌜

    参考资料:
    1.STM32固件库手册、正点原子STM32不完全手册_库函数版本
    2.学习视频链接

    资料已上传,需要自取

    物联沃分享整理
    物联沃-IOTWORD物联网 » 10.[STM32]ADC中断方式-采集MQ-3酒精传感器检测的酒精浓度

    发表评论