一、MQ-7气体传感器所使用的气敏材料是在清洁空气中电导率较低的二氧化锡(SnO2)。采用高低温循环检测方式低温(1.5v加热)检测一氧化碳,传感器的电导率随空气中一氧化碳气体浓度增长而增长,高温(5.0v加热)清洗低温时吸附的杂散气体。使用简单的电路便可将电导率的变化,转换为与该气体浓度相对应的输出信号。函数
二、MQ-7气体传感器对一氧化碳的灵敏度高,这种传感器可检测多种含一氧化碳的气体,是一款适合多种应用的低成本传感器。ui
MQ-7标准工做条件:spa
MQ-7浓度与电压的曲线:pwa
MQ-7灵敏度特性曲线:3d
根据曲线表能够列出部分Rs/R0与ppm的对应值,以下:code
Rs/R0blog |
1.6ip |
1ci |
0.6it |
0.46 |
0.39 |
0.28 |
0.21 |
ppm |
50 |
100 |
200 |
300 |
400 |
600 |
1000 |
Rs/R0与ppm的计算公式,以下(根据Excel生成的公式):
ppm = 98.322f * pow(Rs/R0, -1.458f)
传感器的表面电阻Rs,是经过与其串联的负载电阻RL上的有效电压信号VRL输出而得到的。两者之间的关系为:
Rs/RL = (Vc - VRL) / VRL
ppm:为一氧化碳的浓度
VRL:电压输出值
Rs:器件在不一样气体,不一样浓度下的电阻值。
R0:器件在洁净空气中的电阻值。
传感器的表面电阻Rs,是经过与其串联的负载电阻RL上的有效电压信号VRL输出而得到的。两者之间的关系为:
RS/RL = (Vc - VRL) / VRL
三、Sensor_ Co.c文件代码
#define CAL_PPM 10 // 校准环境中PPM值 #define RL 10 // RL阻值 // 传感器初始化 void MQ7_Init(void) { GPIO_InitTypeDef GPIO_InitStruct; // 定义 GPIO 初始化结构体变量 ADC_InitTypeDef ADC_InitStruct; // 定义 ADC初始化结构体变量 DMA_InitTypeDef DMA_InitStruct; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE); // 使能 GPIOA 时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE); // 使能 ADC1 时钟 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN; // 模拟输入 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0; // ADC通道引脚 GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; // 上拉 GPIO_Init(GPIOA, &GPIO_InitStruct); // 初始化 ADC_DeInit(ADC1); // 复位 ADC ADC_StructInit(&ADC_InitStruct); // 使用默认值填充 ADC_InitStruct成员 ADC_InitStruct.ADC_ContinuousConvMode = ENABLE; // 连续转换模式 ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right; // 数据对齐 ADC_InitStruct.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; // 禁止触发检测,使用软件触发 ADC_InitStruct.ADC_ScanDirection = ADC_ScanDirection_Upward; // 启动向上扫描模式 (from CHSEL0 to CHSEL17) ADC_InitStruct.ADC_Resolution = ADC_Resolution_12b; // 12 位模式 ADC_Init(ADC1,&ADC_InitStruct); // ADC 初始化 ADC_ChannelConfig(ADC1,ADC_Channel_0,ADC_SampleTime_239_5Cycles); // 配置ADC注入通道0及周期采样时间 ADC_GetCalibrationFactor(ADC1); // 校准 ADC ADC_Cmd(ADC1,ENABLE); // ADC 使能 ADC_StartOfConversion(ADC1); // 开始 ADC1 转换 DMA_DeInit(DMA1_Channel1); // 复位 DMA_StructInit(&DMA_InitStruct); DMA_InitStruct.DMA_BufferSize = 1; // 总体的数据个数 DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC; // 指定外设为发送源 DMA_InitStruct.DMA_M2M = DMA_M2M_Disable; // 关闭两个存储区互相访问 DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)&ADC_Value; // 存储区基地址 DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; // 存储区每次接收两个字节 DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable; // 存储区地址自增 DMA_InitStruct.DMA_Mode = DMA_Mode_Circular; // 开启循环模式 DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR; // 外设地址 DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // 外设每次传输两个字节 DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // 外设地址不自增 DMA_InitStruct.DMA_Priority = DMA_Priority_High; // 设置通道转换优先级 DMA_Init(DMA1_Channel1, &DMA_InitStruct); // 初始化 ADC_DMARequestModeConfig(ADC1,ADC_DMAMode_Circular); // 使能ADC的DMA循环转换模式 DMA_Cmd(DMA1_Channel1, ENABLE); //DMA 使能 ADC_DMACmd(ADC1, ENABLE); // ADC DMA 使能 ADC_StartOfConversion(ADC1); // 开始 ADC1 转换 } /**************************************** * RS/R0 ppm * * 1.6 50 * * 1 100 * * 0.6 200 * * 0.46 300 * * 0.39 400 * * 0.28 600 * * 0.21 1000 * * ppm = 98.322f * pow(RS/R0, -1.458f) * ***************************************/ static float R0; // 传感器校准函数 void MQ7_PPM_Calibration(float RS) { R0 = RS / pow(CAL_PPM / 98.322, 1 / -1.458f); } // 获取传感器的值 float MQ7_GetPPM(void) { float Vrl = 3.3f * ADC_Value / 4095.f; float RS = (3.3f - Vrl) / Vrl * RL; if(boot_time_ms < 3000) // 获取系统执行时间,3s前进行校准 { MQ7_PPM_Calibration(RS); } float ppm = 98.322f * pow(RS/R0, -1.458f); return ppm; }
四、 Sensor_ Co.h文件代码
#ifndef _BSP_ADC_DMA_H_ #define _BSP_ADC_DMA_H_ #include "stm32f0xx.h" extern __IO uint16_t ADC_Value; void ADC_DMA_Init(void); void DMA1_Calculation(void); #endif
五、主函数代码
int main() { MQ7_Init(); // 传感器初始化 USART1_Init();// 串口初始化 SYSTICK_Init(1); // 滴答定时器初始化 while(1) { printf("CO:%.2f ppm\n", MQ7_GetPPM()); // 计算一氧化碳浓度并经过串口打印 SYSTICK_DelayMs(500); } }