气体传感器实验学院:计信专业:自动化姜木北【实验目的】1. 理解气体传感器的工作原理;2. 掌握单片机驱动气体传感器的方法。
【实验设备】1. 装有IAR 开发工具的PC机一台;2. 下载器一个;3. 物联网多网技术综合教学开发设计平台一套。
【实验原理】1. 气体传感器简介气体传感器是气体检测系统的核心,通常安装在探测头内。
从本质上讲,气体传感器是一种将某种气体体积分数转化成对应电信号的转换器。
探测头通过气体传感器对气体样品进行调理,通常包括滤除杂质和干扰气体、干燥或制冷处理、样品抽吸,甚至对样品进行化学处理,以便化学传感器进行更快速的测量。
2. 气体传感器分类及在本实验中的应用气体传感器通常以气敏特性来分类,主要可分为:半导体型气体传感器、电化学型气体传感器、固体电解质气体传感器、接触燃烧式气体传感器、光化学型气体传感器、高分子气体传感器等。
半导体气体传感器是采用金属氧化物或金属半导体氧化物材料做成的元件,与气体相互作用时产生表面吸附或反应,引起以载流子运动为特征的电导率或伏安特性或表面电位变化。
这些都是由材料的半导体性质决定的。
如图 1.112所示:根据其气敏机制可以分为电阻式和非电阻式两种。
本实验采用的是电阻式半导体气体传感器主要是指半导体金属氧化物陶瓷气体传感器,是一种用金属氧化物薄膜(例如:Sn02,ZnO Fe203,Ti02等)制成的阻抗器件,其电阻随着气体含量不同而变化。
气味分子在薄膜表面进行还原反应以引起传感器传导率的变化。
为了消除气味分子还必须发生一次氧化反应。
传感器内的加热器有助于氧化反应进程。
它具有成本低廉、制造简单、灵敏度高、响应速度快、寿命长、对湿度敏感低和电路简单等优点。
3. 气体传感器MQ-6灵敏度特性灵敏度特性如下图:1.16所示。
当检测到气体时,气体传感器MQ-6的电导率会发生变化,通过调节滑动电阻器(R18)的阻值调配适当的输出电压,以便单片机检测输出信号,做出相应的判断。
图中J15为传感器模组与单片机的接口。
传感器的6引脚为输出引脚,C27为滤波电容。
【程序流程图】程序流程图如图 1.114所示。
【气体传感器的驱动程序】#include "Basic.h"#include "UART.h"void main(void){uint8 SensorValue;LEDPortInit();UART0_Init( BAUD_115200 );SetIOInput(0,0);for( ; ; ){SensorValue = GetIOLevel( 0, 0 );UART0_Send( "Gas Sensor:", sizeof("Gas Sensor:")-1 );UART0_Dis_uNum(SensorValue);if(0 == SensorValue)UART0_Send( "Safe", sizeof("Safe")-1 );else if(1 == SensorValue)UART0_Send( "Alarm!", sizeof("Alarm!")-1 );UART0_Send( "\r\n", sizeof("\r\n")-1 );SET_LED_D8;Delay(5);CLR_LED_D8;Delay(120);}}#include "Basic.h"void delay(uint n){uint i;for(i=0;i<n;i++);for(i=0;i<n;i++);for(i=0;i<n;i++);for(i=0;i<n;i++);for(i=0;i<n;i++);}void Delay(uint n){uint i,j,k;for(i=0;i<n;i++)for(j=0;j<100;j++)for(k=0;k<100;k++)}void LEDPortInit(void){P1SEL &= ~0X02;P2SEL &= ~0X01;P1DIR |= 0X02;P2DIR |= 0X01;CLR_LED_D8;CLR_LED_D9;}uint8 GetCh08bitADC(void){uint8 v = 0;ADCCFG = 0x01;ADCCON1 = 0x33;ADCCON2 = 0xB0;ADCCON1 |= 0x40;while(!(ADCCON1 & 0x80));v = ADCL;v = ADCH;return(v);}void SetIOInput(uint8 group, uint8 bit){switch(group){case 0: P0DIR &= ~(1 << bit); P0SEL &= ~(1 << bit); P0INP |=(1 << bit); break;case 1: P1DIR &= ~(1 << bit); P1SEL &= ~(1 << bit); P1INP |=(1 << bit); break;case 2: P2DIR &= ~(1 << bit); P2SEL &= ~(1 << bit); P2INP |=(1 << bit); break;}}void SetIOOutput(uint8 group, uint8 bit){switch(group){case 0: P0DIR |= (1 << bit); P0SEL &= ~(1 << bit); break;case 1: P1DIR |= (1 << bit); P1SEL &= ~(1 << bit); break;case 2: P2DIR |= (1 << bit); P2SEL &= ~(1 << bit); break;}}uint8 GetIOLevel(uint8 group, uint8 bit){switch(group){case 0: return !!(P0 & (1 << bit));case 1: return !!(P1 & (1 << bit));case 2: return !!(P2 & (1 << bit));}return 0;}void SetIOLevel(uint8 group, uint8 bit, uint8 value){switch(group){case 0:if(value)P0 |= (1 << bit);elseP0 &=~(1 << bit);break;case 1:if(value)P1 |= (1 << bit);elseP1 &=~(1 << bit);break;case 2:if(value)P2 |= (1 << bit);elseP2 &=~(1 << bit);break;}}#include "UART.h"void UART0_Init(BaudSel baud){CLKCONCMD &= ~0X40; //晶振while(!(SLEEPSTA & 0X40)) ; //等待晶振稳定CLKCONCMD &= ~0X47; //TICHSPD128分频,CLKSPD不分频SLEEPCMD |= 0X04; //关闭不用的RC振荡器PERCFG = 0X00;//位置1 P0口P0SEL |= 0X0C;//P0用作串口U0CSR |= 0X80;//UART方式switch(baud){case BAUD_2400: U0GCR |= 6; U0BAUD |= 59; break;case BAUD_4800: U0GCR |= 7; U0BAUD |= 59; break;case BAUD_9600: U0GCR |= 8; U0BAUD |= 59; break;case BAUD_14400: U0GCR |= 8; U0BAUD |= 216; break;case BAUD_19200: U0GCR |= 9; U0BAUD |= 59; break;case BAUD_28800: U0GCR |= 9; U0BAUD |= 216; break;case BAUD_38400: U0GCR |= 10; U0BAUD |= 59; break;case BAUD_57600: U0GCR |= 10; U0BAUD |= 216; break;case BAUD_76800: U0GCR |= 11; U0BAUD |= 59; break;case BAUD_115200: U0GCR |= 11; U0BAUD |= 216; break;case BAUD_230400: U0GCR |= 12; U0BAUD |= 216; break;default : U0GCR |= 11; U0BAUD |= 216; break;}UTX0IF = 0;U0CSR |= 0X40;//允许接收IEN0 |= 0X84;//开总中断,接收中断}void UART0_Send(char *Data,int len){int i;for(i=0;i<len;i++){U0DBUF = *Data++;while(UTX0IF == 0)UTX0IF = 0;}}void UART0_Dis_uNum(uint16 uValue ){uint8 i;char cData[5] = {'0','0','0','0','0'};cData[0] = uValue % 100000 / 10000 + '0';cData[1] = uValue % 10000 / 1000 + '0';cData[2] = uValue % 1000 / 100 + '0';cData[3] = uValue % 100 / 10 + '0';cData[4] = uValue % 10 / 1 + '0';if(0 != uValue ){for( i=0; i<5; i++){if('0' != cData[i] )break;if('0' == cData[i] )cData[i] = ' ';}}else if(0 == uValue ){for( i=0; i<4; i++){cData[i] = ' ';}}UART0_Send(" ", 1);UART0_Send(cData, 5);UART0_Send(" ", 1);}void UART0_Dis_fNum(float fValue ){uint16 uValue = (uint16)( 100 * fValue );char cData[5] = {'0','0','.','0','0'};cData[0] = uValue % 10000 / 1000 + '0';cData[1] = uValue % 1000 / 100 + '0';cData[2] = '.';cData[3] = uValue % 100 / 10 + '0';cData[4] = uValue % 10 / 1 + '0';UART0_Send(" ", 1);UART0_Send(cData, 5);UART0_Send(" ", 1);}#pragma vector = URX0_VECTOR__interrupt void UART0_ISR(void){// static char temp[1];// temp[0] = U0DBUF;// UART0_Send(temp, 1);URX0IF = 0;//清中断标志}【实验结果及现象】当运行该程序并用火焰燃烧传感器端口时可以在串口执行软件窗口中看到如下结果:。