用1602LCD与DS18B20设计的温度报警器仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include <reg51.h>//头文件,52单片机改为52
- #include <intrins.h>
- #define LCD_DATA P0
- sbit LCD_RS = P2^0;
- sbit LCD_RW = P2^1;
- sbit LCD_EN = P2^2;
- unsigned char dispBuff0[16]={'T','E','M',
- 'P',':',' ',' ',' ',' ',' ',' ','C',' ',' ',' ',};//LCD第一行显示
- unsigned char dispBuff1[16]={'D','E','N',
- 'S',':',' ',' ','%',' ',' ',' ',' ',' ',' ',' ',};//LCD第二行显示
- sbit DQ=P2^3; //DS18B20数据端
- unsigned int temperature=0;//温度
- unsigned char fuhao=0;//温度的正负符号
- //AD0809的IO口以及变量定义
- sbit OE=P2^7;
- //sbit ALE=P3^0;
- sbit EOC=P2^6;
- sbit START=P3^0;
- unsigned char density=0;//浓度
- //LED报警指示的IO口以及变量定义
- sbit LED1=P2^4;//温度报警指示
- sbit LED2=P2^5;//浓度报警指示
- #define off 1 //高电平时灯为关闭状态
- #define on 0 //低电平时灯为开启状态
- sbit speaker=P3^1;//蜂鸣器
- void Delay20ms() ;
- void LCD_WriteDat(unsigned char lcd_dat);
- void LCD_WriteCmd(unsigned char lcd_cmd);
- unsigned char LCD_ReadStatus(void);
- void LCD_Goto(unsigned char x,unsigned char y);
- void LCD_Display(unsigned char row,unsigned char *str);
- void delay(unsigned int x)//延时公用程序
- {
- unsigned char j;
- while(x--)
- {
- for(j=0;j<125;j++);
- }
- }
- /*1、LCD模块子函数*/
- void LCD_Init(void)
- {
- Delay20ms();
- /*************************************************
- 功能设置: DB5=1;DB6...=0;
- DB4=1:8位接口; 0:4位接口;
- DB3=1:双行显示;0:单行显示;
- DB3=1:5×10点阵;0:5×7点阵;
- *************************************************/
- LCD_WriteCmd(0x38); //8位机接口、双行显示、5×7字符点阵;
- /*************************************************
- 显示控制:DB3=1;DB4...=0;
- DB2=1:开启显示;0:关闭LCD显示;
- DB1=1:显示光标;0:光标隐藏;
- DB0=1:光标闪烁;0:光标闪烁关闭;
- *************************************************/
- LCD_WriteCmd(0x0c); //显示开启、光标不显示也不闪烁;
- /*************************************************
- 清屏指令:DB0=1;DB1...=0;
- *************************************************/
- LCD_WriteCmd(0x01); //清屏;
- /****************************************************************
- 访问模式:DB2=1;DB3...=0;
- DB1=1:对内部Ram读写后AC自增,否则自减;
- DB0=1:与DB1设置有关,对DD RAM写时同时整屏移动1位;
- *****************************************************************/
- LCD_WriteCmd(0x06); //光标右移一位、整屏不移动;
-
- LCD_Goto(0,0);
- }
- void LCD_WriteDat(unsigned char lcd_dat)
- {
- unsigned char tmp;
- tmp = LCD_ReadStatus(); //读状态;
- while((tmp & 0x80)) //是否忙 ?
- {
- tmp = LCD_ReadStatus();
- }
-
- LCD_RS = 1;
- LCD_RW = 0;
- LCD_DATA = lcd_dat;
- _nop_();
- LCD_EN = 0;
- _nop_();
- _nop_();
- LCD_EN = 1;
-
- }
- void LCD_WriteCmd(unsigned char lcd_cmd)
- {
- unsigned char tmp;
- tmp = LCD_ReadStatus();
- while((tmp & 0x80))
- {
- tmp = LCD_ReadStatus();
- }
-
- LCD_RS = 0;
- LCD_RW = 0;
- LCD_DATA = lcd_cmd;
- _nop_();
- LCD_EN = 0;
- _nop_();
- _nop_();
- LCD_EN = 1;
- }
- unsigned char LCD_ReadStatus(void)
- {
- unsigned char tmp;
- #if 0
- LCD_RS = 0;
- LCD_RW = 1;
- LCD_EN = 1;
- tmp = LCD_DATA;
- LCD_EN = 0;
- #endif
- LCD_DATA = 0xff;
- LCD_RS = 0;
- LCD_RW = 1;
- LCD_EN = 0;
- _nop_();
- _nop_();
- LCD_EN = 1;
- tmp = LCD_DATA;
- return tmp;
- }
- void LCD_Goto(unsigned char x,unsigned char y)
- {
- unsigned char tmp;
- if(y) //若是第二行;
- {
- tmp = 0xc0 + x;
- LCD_WriteCmd(tmp);
- }
- else
- {
- tmp = 0x80 + x;
- LCD_WriteCmd(tmp);
- }
- }
-
- void LCD_Display(unsigned char row,unsigned char *str)
- {
- if(row)
- {
- LCD_Goto(0,1);
- }
- else
- {
- LCD_Goto(0,0);
- }
- while(*str != '\0')
- {
- LCD_WriteDat(*str++);
- }
- }
- void Delay20ms() //粗略延时;
- {
- unsigned int tmp = 50000;
- while(tmp--);
- }
-
- /*2、DS18B2模块*/
- void delay_18B20(unsigned int i)
- {
- while(i--);
- }
- /**********ds18b20初始化函数**********************/
- void Init_DS18B20(void)
- {
- unsigned char x=0;
- DQ = 1; //DQ复位
- delay_18B20(2); //稍做延时
- DQ = 0; //单片机将DQ拉低
- delay_18B20(60); //精确延时 大于 480us
- DQ = 1; //拉高总线
- delay_18B20(2);
- x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
- delay_18B20(15);
- }
- /***********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(2);
- DQ = 1;
- dat>>=1;
- }
- }
- void ReadTemperature(void)
- {unsigned char readdata[2]={0,0};
- fuhao=0;
- temperature=0;
- delay_18B20(40); // this message is very important
- Init_DS18B20();
- WriteOneChar(0xCC); // 跳过读序号列号的操作
- WriteOneChar(0x44); // 启动温度转换
- delay_18B20(40); // this message is wery important
- Init_DS18B20();
- WriteOneChar(0xCC); //跳过读序号列号的操作
- WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
- delay_18B20(40);
- readdata[0]=ReadOneChar(); //读取温度值低位
- readdata[1]=ReadOneChar(); //读取温度值高位
- if (readdata[1]>127)
- {readdata[0]^=0xff;//求补码
- readdata[1]^=0xff;
- fuhao=1;//符号为“-”
- }
- temperature =readdata[1]*256+readdata[0] ;
- temperature =temperature*0.625+0.5 ;//放大了10倍
- }
- /*3、AD模块*/
- void AD0809()//0809转换数据
- {
- START=0;_nop_();
- START=1;_nop_();
- START=0;_nop_();
- while(EOC==0);
- OE=1;_nop_();
- density=P1;_nop_();
- OE=0;
- }
- void timer0() interrupt 1 //这里输出蜂鸣器信号
- {TH0=254;//频率为1600hz时计时器初值
- TL0=200;
- speaker=!speaker;
- }
- void main()
- {unsigned char DEN=0;
- LCD_Init();//初始化LCD
- /*计时器0设置*/
- TMOD=0x11;//定时器1、2工作于方式1
- TH0=254;//频率为1600hz时计时器初值
- TL0=200;
- ET0=1;
- EA=1;
- speaker=1;
- while(1)
- {
- /*LCD第一行显示温度*/
- ReadTemperature();//读取温度值
-
- if (fuhao)
- {dispBuff0[5]='-';}
- else
- {dispBuff0[5]='+';}
- dispBuff0[6]=(temperature/1000)%10+'0';//温度值百位
- dispBuff0[7]=(temperature/100)%10+'0';//温度值十位
- dispBuff0[8]=(temperature/10)%10+'0';//温度值个位
- dispBuff0[9]='.';
- dispBuff0[10]=(temperature)%10+'0';//温度值小数点后一位;
- /*LCD第2行显示浓度*/
- AD0809();//ad转换,浓度
- DEN=(density*100/256);
- dispBuff1[5]=(DEN/10)%10+'0';//浓度值十位
- dispBuff1[6]=(DEN/1)%10+'0';//浓度值个位
- LCD_Display(0,dispBuff0);//LCD第一行显示
- LCD_Display(1,dispBuff1);//LCD第二行显示
- delay(20);
- /*报警程序*/
- if (temperature>=400 && !fuhao)//温度大于40摄氏度
- {LED1=on;}
- else
- {LED1=off;}
- if (density>=50)//浓度大于50
- {LED2=on;}
- else
- {LED2=off;}
- if (temperature>=400 && !fuhao && DEN>=50)//响蜂鸣器
- {TR0=1;}
- else
- {TR0=0;}
- }//while
- }//main
复制代码
所有资料51hei提供下载:
DS18B20温度传感器和MQ2烟雾传感器的火灾报警器设计.rar
(95.25 KB, 下载次数: 169)
|