# Gas sensor **Repository Path**: shenjiayuan/Gas-sensor ## Basic Information - **Project Name**: Gas sensor - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2016-03-20 - **Last Updated**: 2021-11-03 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README #Gas sensor /*头文件*/ #include #include /*AD转化的三个重要寄存器定义*/ // sfr 函数用来说明地址 sfr ADC_CONTR=0xBC; //定义A/D转化控制寄存器的地址 sfr ADC_DATA=0xBD; //定义A/D转化结果寄存器的高8位结果 sfr ADC_LOW2=0xBE;  //低2位结果 sfr P1_ADC_EN=0x9D; //定义A/D转化功能允许寄存器的地址 sfr P4=0xC0; //定义P4端口的地址 /*****************宏定义******************/ #define uint unsigned int #define uchar unsigned char #define ADC_POWER 0x80  //ADC电源控制位 #define ADC_FLAG 0x10  //ADC完成标志 #define ADC_START 0x08  //ADC起动控制位 //AD转换速度选择 #define ADC_SPEEDHH 0x00  //90个时针周期转化一次 #define ADC_SPEEDH 0x20 //180个时钟 周期转化一次 #define ADC_SPEEDL 0x40 //360个时钟周期转化一次 #define ADC_SPEEDLL 0x60  //540个时钟周期转化一次 #define uint unsigned int #define uchar unsigned char uint ad_value,NH4_value; float AN_value; /***********位操作端口定义**************/ //sbit函数是定义具体的某一位 //定义单片机I/O口 P1.0的伪名称叫led 这样你要对P1.0控制时直接写 led=1,或者=0 //51单片机有四个并行端口,分别命名为P0,P1,P2,P3,每个端口有8位,用来传输数// 据或地址信息 sbit set_key=P1^4; //“设置”键 K1 sbit add_key=P1^5; //“加”键 K2 sbit cut_key=P1^7; // “减”键 K3 sbit speak=P3^7; // 蜂鸣器 sbit JK=P3^6; // 继电器 sbit qian_wei=P1^0; sbit bai_wei=P1^1; sbit shi_wei=P1^2; sbit ge_wei=P1^3; uchar y_data[4]; //储存烟雾的数据 int set_data=50; //报警初始值的设定 uchar temp[4]={0,0,0,0}; uchar bianma[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//定义显示数据单元 uchar flog4; //布尔类型 void delay_1ms(uchar i) //延时函数 { uint x,y; for(x=i;x>0;x--) for(y=124;y>0;y--); } // 烟雾浓度在数码管上的显示 void display() { qian_wei=0; bai_wei=1; shi_wei=1; ge_wei=1; P2=bianma[y_data[0]]; delay_1ms(5); qian_wei=1; bai_wei=0; shi_wei=1; ge_wei=1; P2=bianma[y_data[1]]; delay_1ms(5); P2=0xff; qian_wei=1; bai_wei=1; shi_wei=0; ge_wei=1; P2=bianma[y_data[2]]; delay_1ms(5); P2=0xff; qian_wei=1; bai_wei=1; shi_wei=1; ge_wei=0; P2=bianma[y_data[3]]; delay_1ms(5); P2=0xff; } //浓度设置值在数码管上的显示 void display2() { temp[0]=set_data/1000; temp[1]=(set_data%1000)/100; temp[2]=(set_data%100)/10; temp[3]=set_data%10; qian_wei=0; bai_wei=1; shi_wei=1; ge_wei=1; P2=bianma[temp[0]]; delay_1ms(5); P2=0xff; qian_wei=1; bai_wei=0; shi_wei=1; ge_wei=1; P2=bianma[temp[1]]; delay_1ms(5); P2=0xff; qian_wei=1; bai_wei=1 ; shi_wei=0; ge_wei=1; P2=bianma[temp[2]]; delay_1ms(5); P2=0xff; qian_wei=1; bai_wei=1; shi_wei=1; ge_wei=0; P2=bianma[temp[3]]; delay_1ms(5); P2=0xff; } /********** 模数转换初始换函数******************/ void init_ADC() { P1_ADC_EN=0x40; ADC_DATA=0; ADC_LOW2=0; ADC_CONTR=ADC_SPEEDLL|ADC_POWER;  //清除结果寄存器  delay_1ms(20);  //ADC上电并延时 } /********** 模拟量转化为数据量(转换函数)******************/ uint ADC(uchar num) //参数num用于指定是哪个模拟量转换 { // ADC模块开启供电、配置速度并打开指定的某个通道。 ADC_CONTR=ADC_POWER|ADC_SPEEDLL|num|ADC_START; _nop_();_nop_();_nop_();_nop_(); //运行四个机器周期 while(!(ADC_CONTR&ADC_FLAG)); //等待转换完成标志 ADC_CONTR&=~ADC_FLAG; // close ADC ad_value=ADC_DATA*4+ADC_LOW2; //转换的结果是十位的 高八位放在ADC_DATA中 低两位放在ADC_LOW2 return ad_value; // 将转换后的数字量返回 } /********** 模数转换后数据处理函数******************/ void pos_AD() { AN_value=ADC(6); // 装换氨气的浓度 把转换后的数字量结果赋给AN_value delay_1ms(5); // /***对转换后的数字量进行矫正***/ if(AN_value>900) { AN_value=900; } NH4_value=(900-AN_value)*0.9765625; y_data[0]=NH4_value/1000; //将气体浓度值的个位 十位 百位 千位 分开 用于显示 y_data[1]=(NH4_value%1000)/100; y_data[2]=(NH4_value%100)/10; y_data[3]=NH4_value%10; } /********** 报警处理函数******************/ void baojing() { if(set_data5000) { set_data=5000; } } } if(cut_key==0) { delay_1ms(5); if(cut_key==0) { set_data=set_data-1; while(cut_key==0); if(set_data<=0) { set_data=0; } } } display2(); } else { pos_AD(); display(); baojing(); } } }