烟雾及温度报警器无火焰传感器仿真图
LSR16041使用说明
说明:K1设置按键,用来设置设定报警温度和烟雾浓度。
K2增加,K3减少。K4确定,只有确定后设置的报警值才有用。
设定报警数值后,当温度或者烟雾浓度达到设定值就会报警。
烟雾及温度报警器无火焰传感器的程序(部分预览)完整版请下载附件:
- #include <reg52.h>
- #include <stdio.h>
- #include <intrins.h>
- #include <absacc.h>
- #include <ctype.h>
- #include <math.h>
- #include <string.h>
- //#include "I2C.h"
- #include "lcd1602.h"
- #include "adc0832.h"
- sbit K1= P1^2;
- sbit K2= P1^3;
- sbit K3= P1^4;
- sbit K4= P1^5;
- sbit K5= P1^6;
- sbit K6= P1^7;
- sbit DQ= P2^7;
- sbit BUZZ= P2^6;
-
- uchar tmpdisplay[8]; //定义显示缓存数组
- bit read_flag=0; //定义读时钟标志位
- bit mode=0; //显示模式0正常1设定
- uchar set_position=0;
- uchar set_tempure=0; //设定温度
- uchar set_smokescope=0; //设定浓度
- int real_tempure=0; //实际温度
- uchar real_smokescope=0; //实际烟雾浓度
- uchar cursor_position=0;//光标位置
-
- uchar time_counter_50ms=0;
- uchar smokescope=0;
- uchar first_read_tempe=0;//第一次读取温度数值
- unsigned char t[2],*pt; //用来存放温度值,测温程序就是通过这个数组与主函数通信的
- unsigned char TempBuffer1[10]={0x2b,0x30,0x30,0x30,0x2e,0x30,0x30,0xdf,0x43,'\0'};//{0x2b,0x31,0x32,0x32,0x2e,0x30,0x30,0xdf,0x43,'\0'};
- //显示实时温度,上电时显示+122.00C
- /*
- unsigned char TempBuffer0[16]={0x54,0x48,0x3a,0x2b,0x31,0x32,0x35,0x20,
- 0x54,0x4c,0x3a,0x2b,0x31,0x32,0x34,'\0'}; */
- //显示温度上下限,上电时显示TH:+125 TL:+124C
- unsigned char code dotcode[4]={0,25,50,75};
- /***因显示分辨率为0.25,但小数运算比较麻烦,故采用查表的方法*******
- 再将表值分离出十位和个位后送到十分位和百分位********************/
- void covert1(void) //将温度转换为LCD显示的数据
- {
-
- unsigned char x=0x00,y=0x00;
- t[0]=*pt;
- pt++;
- t[1]=*pt;
- if(t[1]>0x07) //判断正负温度
- {
- TempBuffer1[0]=0x2d; //0x2d为"-"的ASCII码
- t[1]=~t[1]; /*下面几句把负数的补码*/
- t[0]=~t[0]; /* 换算成绝对值*********/
- x=t[0]+1; /***********************/
- t[0]=x; /***********************/
- if(x>255) /**********************/
- t[1]++; /*********************/
- }
- else TempBuffer1[0]=0x2b; //0xfe为变"+"的ASCII码
- t[1]<<=4; //将高字节左移4位
- t[1]=t[1]&0x70; //取出高字节的3个有效数字位
- x=t[0]; //将t[0]暂存到X,因为取小数部分还要用到它
- x>>=4; //右移4位
- x=x&0x0f; //和前面两句就是取出t[0]的高四位
- t[1]=t[1]|x; //将高低字节的有效值的整数部分拼成一个字节
- TempBuffer1[1]=t[1]/100+0x30; //+0x30 为变 0~9 ASCII码
- if( TempBuffer1[1]==0x30) TempBuffer1[1]=0xfe; //百位数消隐
- TempBuffer1[2]=(t[1]%100)/10+0x30; //分离出十位
- TempBuffer1[3]=(t[1]%100)%10+0x30; //分离出个位
- t[0]=t[0]&0x0c; //取有效的两位小数
- t[0]>>=2; //左移两位,以便查表
- x=t[0];
- y=dotcode[x]; //查表换算成实际的小数
- TempBuffer1[5]=y/10+0x30; //分离出十分位
- TempBuffer1[6]=y%10+0x30; //分离出百分位
- }
- //十进制转为十六 ,比如把10转为0x10,注意区分
- uchar data_to_hex(uchar temp_data)
- {
- return (temp_data/10*16+temp_data%10);
- }
- /********************************************************************
- * 名称 : Delay_1ms()
- * 功能 : 延时子程序,延时时间为 1ms * x
- * 输入 : x (延时一毫秒的个数)
- * 输出 : 无
- ***********************************************************************/
- void Delay_1ms(uint i)//1ms延时
- {
- uchar x,j;
- for(j=0;j<i;j++)
- for(x=0;x<=148;x++);
- }
- //*********************************
- //按键扫描程序
- //mode:0,不支持连续按;1,支持连续按;
- //*********************************
- uchar KEY_Scan(uchar mode)
- {
- static uchar key_up=1;//按键按松开标志
- if(mode)key_up=1; //支持连按
- if(key_up&&(K1==0||K2==0||K3==0||K4==0||K5==0||K6==0))
- {
- Delay_1ms(5);//去抖动
- key_up=0;
- if(K1==0)return 1;
- else if(K2==0)return 2;
- else if(K3==0)return 3;
- else if(K4==0)return 4;
- else if(K5==0)return 5;
- }else if(K1==1&&K2==1&&K3==1&&K4==1&&K5==1&&K6==1)key_up=1;
- return 0;// 无按键按下
- }
- void delay_18B20(unsigned int i)
- {
- while(i--);
- }
- /**********ds18b20初始化函数**********************/
- void Init_DS18B20(void)
- {
- unsigned char x=0;
- DQ = 1; //DQ复位
- delay_18B20(8); //稍做延时
- DQ = 0; //单片机将DQ拉低
- delay_18B20(80); //精确延时 大于 480us
- DQ = 1; //拉高总线
- delay_18B20(14);
- x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
- delay_18B20(20);
- }
- /***********ds18b20读一个字节**************/
- unsigned char ReadOneChar(void)
- {
- unsigned char i=0;
- unsigned char dat = 0;
- for (i=8;i>0;i--)
- {
- DQ = 0; // 给脉冲信号
- dat>>=1;
- DQ = 1; // 给脉冲信号
- if(DQ)
- dat|=0x80;
- delay_18B20(4);
- }
- return(dat);
- }
- /*************ds18b20写一个字节****************/
- void WriteOneChar(unsigned char dat)
- {
- unsigned char i=0;
- for (i=8; i>0; i--)
- {
- DQ = 0;
- DQ = dat&0x01;
- delay_18B20(5);
- DQ = 1;
- dat>>=1;
- }
- }
- /**************读取ds18b20当前温度************/
- unsigned char *ReadTemperature(char TH,char TL,unsigned char RS)
- { unsigned char tt[2];
- Init_DS18B20();
- WriteOneChar(0xCC); // 跳过读序号列号的操作
- WriteOneChar(0x4E); // //写入"写暂存器"命令,修改TH和TL和分辩率配置寄存器
- //先写TH,再写TL,最后写配置寄存器
- WriteOneChar(TH); //写入想设定的温度报警上限
- WriteOneChar(TL); //写入想设定的温度报警下限
- WriteOneChar(RS); //写配置寄存器,格式为0 R1 R0 1,1 1 1 1
- //R1R0=00分辨率娄9位,R1R0=11分辨率为12位
- delay_18B20(80); // this message is wery important
- Init_DS18B20();
- WriteOneChar(0xCC); // 跳过读序号列号的操作
- WriteOneChar(0x44); // 启动温度转换
- delay_18B20(80); // this message is wery important
- Init_DS18B20();
- WriteOneChar(0xCC); //跳过读序号列号的操作
- WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
- delay_18B20(80);
- tt[0]=ReadOneChar(); //读取温度值低位
- tt[1]=ReadOneChar(); //读取温度值高位
- return(tt);
- }
- void Time0_init()
- {
- TMOD |= 0x01; //使用模式1,16位定时器
- TH0 = (65536-50000)/256; //定时器装入初始值10ms
- TL0 = (65536-50000)%256;
- EA = 1; //总中断
- ET0 = 1;//定时器0初始化
- TR0 = 1;
- }
- //************************************
- //定时器初始化
- //初始化为10MS定时器
- //************************************
- void Time1_init()
- {
- TMOD |= 0x10; //使用模式1,16位定时器
- TH1 = (65536-10000)/256; //定时器装入初始值10ms
- TL1 = (65536-10000)%256;
- EA = 1; //总中断
- ET1 = 1;//定时器1初始化
- TR1 = 1;
- }
- //换算采集的烟雾浓度AD值,转换为百分制
- void covert_scope_data(uchar temp_data)
- {
- uchar temp=0;
- temp=(temp_data<<1)/5;
- if(temp_data>127)temp+=50;
- if(temp==100)
- {
- LCD_Print(12,1,"100");
- }
- else
- {
- LCD_Print(12,1," ");
- write_secondline(13, data_to_hex(temp));
- }
- real_smokescope=temp;
- }
- void main()
- {
- uchar tem=0;
- BUZZ=1;
- init_lcd1602();
- Time0_init();
- Time1_init();
-
- while(1)
- {
- switch(KEY_Scan(0)) //扫描按键
- {
- case 1://K1
- mode=1;
- set_position++;
- if(set_position>2)set_position=1;
- if(set_position==1)
- {
- cursor_position=6;
- }
- else if(set_position==2)
- {
- cursor_position=12;
- }
- break;
- case 2://K2
- if(set_position==1)
- {
- set_tempure++;
-
- }
- else if(set_position==2)
- {
- set_smokescope++;
- }
- break;
- case 3://K3
- if(set_position==1)
- {
- set_tempure--;
- }
- else if(set_position==2)
- {
- set_smokescope--;
- }
- break;
- case 4://K4
- set_position=0;
- cursor_position=0;
- mode=0;
- break;
- }
- if(set_tempure>120)set_tempure=30; //限幅
- else if(set_tempure<30)set_tempure=120;
- if(set_smokescope>100) set_smokescope = 20;
- else if(set_smokescope<20) set_smokescope=100;
- write_com(0x0c); //关闭光标闪烁
- if(set_tempure>=100)
- {
- LCD_Print(4,0,"1");
- tem=set_tempure-100;
- }
- else
- {
- LCD_Print(4,0," ");
- tem=set_tempure;
- }
- write_firstline(5,data_to_hex(tem));
- if(set_smokescope>=100)
- {
- LCD_Print(10,0,"1");
- tem=set_smokescope-100;
- }
- else
- {
- LCD_Print(10,0," ");
- tem=set_smokescope;
- }
- write_firstline(11,data_to_hex(tem));
- if((mode==0)&&(first_read_tempe)) //正常情况下进行比较报警
- {
- if((real_smokescope>=set_smokescope)||(real_tempure>=set_tempure))
- {
- BUZZ=0; //打开报警
- }
- else
- {
- BUZZ=1; //关闭报警
- }
- }
- covert_scope_data(smokescope); //***显示烟雾的浓度
- LCD_Print(2,1,TempBuffer1); //显示温度
- //write_firstline(11,data_to_hex(real_tempure));
- if(cursor_position) //打开闪烁
- {
- write_com(0x80+cursor_position);
- write_com(0x0e);
- }
- }
- }
-
- void time0(void)interrupt 1
- {
- static temp_time_counter0=0;
- unsigned char TH=110,TL=-20; //下一步扩展时可能通过这两个变量,调节上下限
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256;
- temp_time_counter0++;
- time_counter_50ms++;
- if(time_counter_50ms>200)time_counter_50ms=200;
- if(temp_time_counter0>3)
- {
- temp_time_counter0=0;
- if(first_read_tempe==0) //首次上电多次读取温度再进行显示
- {
- pt=ReadTemperature(TH,TL,0x3f); //上限温度-22,下限-24,分辨率10位,也就是0.25C,TM R1 R0 1 1 1 1 1 //读取温度,温度值存放在一个两个字节的数组中,
- first_read_tempe=1; //置一表示读取到了温度
- }
- else
- {
- pt=ReadTemperature(TH,TL,0x3f); //上限温度-22,下限-24,分辨率10位,也就是0.25C,TM R1 R0 1 1 1 1 1 //读取温度,温度值存放在一个两个字节的数组中,
- covert1();
- if(TempBuffer1[5]||TempBuffer1[6]) //有小数就进1.
- real_tempure = (TempBuffer1[2]-0x30)*10+TempBuffer1[3]-0x30+1;
- else
- real_tempure = (TempBuffer1[2]-0x30)*10+TempBuffer1[3]-0x30;
- if(TempBuffer1[1]==0x31) //说明此时有百位
- {
- real_tempure+=100;
- }
- if(TempBuffer1[0]==0x2d) //负温度
- {
- real_tempure*=-1;
- }
- }
- }
- }
- void time1(void)interrupt 3
- {
- TH1=(65536-10000)/256;
- TL1=(65536-10000)%256;
- smokescope = choiceADC(0); //读取ADC数值
- }
复制代码
注:如果解压后kile工程打不开,请下高版本,或者打开“TXT代码”文件夹里的TXT文件,复
制里面的代码到自己新建的工程里。
关于kile和proteus的学习这里就不赘述了,相信大家有能力搞定的。
所有资料下载:
烟雾及温度报警器无火焰传感器LSR160416.rar
(529.41 KB, 下载次数: 281)
|