基于51单片机、TLC549做出温湿度和烟雾报警器代码
时间: 2023-10-02 11:06:04 浏览: 116
基于51单片机+TLC549芯片A-D转换器应用软件程序源码+Proteus仿真实例+文档资料.zip
以下是基于51单片机和TLC549的温湿度和烟雾报警器代码:
```
#include<reg52.h>
#include<intrins.h>
#include<math.h>
#define uchar unsigned char
#define uint unsigned int
sbit DQ=P2^0; //DQ连接到P2.0
sbit RS=P1^0; //LCD1602的RS引脚连接到P1.0
sbit EN=P1^1; //LCD1602的EN引脚连接到P1.1
uchar smog=0; //烟雾报警标志位
uchar temp,humi; //温湿度数值
void delay(uint x) //延时函数
{
uint i,j;
for(i=x;i>0;i--)
for(j=110;j>0;j--);
}
void LCD_WaitReady(void) //LCD等待函数
{
uchar sta;
do
{
RS=0; //RS=0, RW=1, E=1, 读状态
EN=1;
sta=P0;
EN=0;
}while(sta&0x80); //当忙标志为1时等待
}
void LCD_WriteCmd(uchar cmd) //LCD写命令函数
{
LCD_WaitReady();
RS=0; //RS=0, RW=0, E=1, 输入命令
EN=1;
P0=cmd;
EN=0;
}
void LCD_WriteDat(uchar dat) //LCD写数据函数
{
LCD_WaitReady();
RS=1; //RS=1, RW=0, E=1, 输入数据
EN=1;
P0=dat;
EN=0;
}
void LCD_Init(void) //LCD初始化函数
{
delay(15);
LCD_WriteCmd(0x38); //16*2显示,5*7点阵字符,8位数据接口
delay(5);
LCD_WriteCmd(0x38); //16*2显示,5*7点阵字符,8位数据接口
delay(5);
LCD_WriteCmd(0x38); //16*2显示,5*7点阵字符,8位数据接口
delay(5);
LCD_WriteCmd(0x0c); //开显示,无光标,无闪烁
delay(5);
LCD_WriteCmd(0x01); //清除显示,光标回到起始位置
delay(5);
LCD_WriteCmd(0x06); //文字从左到右移动
delay(5);
}
void Ds18b20Chk(void) //DS18B20初始化函数
{
uchar chk;
DQ=1;
_nop_();
_nop_();
_nop_();
DQ=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
chk=DQ;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
DQ=1;
}
uchar Ds18b20ReadByte(void) //DS18B20读取一个字节
{
uchar i,j;
uchar dat=0;
for(i=0;i<8;i++)
{
DQ=1;
_nop_();
_nop_();
_nop_();
dat>>=1;
DQ=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
j=DQ;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
if(j) dat|=0x80;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
DQ=1;
}
return dat;
}
void Ds18b20WriteByte(uchar dat) //DS18B20写入一个字节
{
uchar i;
for(i=0;i<8;i++)
{
DQ=1;
_nop_();
_nop_();
_nop_();
DQ=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
if(dat&0x01)
DQ=1;
else
DQ=0;
dat>>=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
DQ=1;
}
}
void Ds18b20Start(void) //DS18B20开始转换函数
{
Ds18b20Chk();
Ds18b20WriteByte(0xcc); //跳过ROM操作
Ds18b20WriteByte(0x44); //温度转换命令
}
void Ds18b20ReadTemp(void) //DS18B20读温度函数
{
uchar temp1,temp2;
Ds18b20Chk();
Ds18b20WriteByte(0xcc); //跳过ROM操作
Ds18b20WriteByte(0xbe); //读暂存器命令
temp1=Ds18b20ReadByte(); //读低字节
temp2=Ds18b20ReadByte(); //读高字节
temp=(temp2<<4)|(temp1>>4);
}
void Dht11Start(void) //DHT11开始转换函数
{
uchar i;
DQ=1;
delay(5);
DQ=0;
delay(20);
DQ=1;
delay(30);
i=DQ;
delay(3);
}
uchar Dht11ReadByte(void) //DHT11读取一个字节
{
uchar i,j,dat=0;
for(i=0;i<8;i++)
{
while(!DQ);
delay(3);
j=0;
if(DQ)
j=1;
delay(5);
dat<<=1;
dat|=j;
}
return dat;
}
void Dht11ReadTempHumi(void) //DHT11读取温湿度函数
{
uchar dht11[5]={0,0,0,0,0};
uchar i,j;
Dht11Start();
if(!DQ) //DHT11响应
{
while(!DQ);
while(DQ);
for(i=0;i<5;i++)
dht11[i]=Dht11ReadByte();
humi=dht11[0];
temp=dht11[2];
}
}
void AdcInit(void) //ADC初始化函数
{
P1|=0x08; //P1.3置高
ADC_CONTR=0xe0; //ADC转换时钟=系统时钟/32
delay(2);
}
uchar AdcConvert(uchar ch) //ADC转换函数
{
ADC_CONTR&=0xf0; //清除原通道结果
ADC_CONTR|=ch; //选择通道
ADC_CONTR|=0x08; //启动转换
while(!(ADC_CONTR&0x10)); //等待转换结束
ADC_CONTR&=0xef; //清除转换结束标志
return ADC_RES; //返回转换结果
}
void main()
{
LCD_Init(); //LCD初始化
AdcInit(); //ADC初始化
while(1)
{
Ds18b20Start(); //DS18B20开始转换
Dht11ReadTempHumi(); //DHT11读取温湿度
smog=AdcConvert(3); //ADC读取烟雾值
LCD_WriteCmd(0x01); //清屏
LCD_WriteCmd(0x80); //光标移到第一行第一列
LCD_WriteDat('T'); //显示温度
LCD_WriteDat(':');
LCD_WriteDat(temp/10+'0');
LCD_WriteDat(temp%10+'0');
LCD_WriteDat('C');
LCD_WriteDat(' ');
LCD_WriteDat(' ');
LCD_WriteDat('H'); //显示湿度
LCD_WriteDat(':');
LCD_WriteDat(humi/10+'0');
LCD_WriteDat(humi%10+'0');
LCD_WriteDat('%');
LCD_WriteCmd(0xc0); //光标移到第二行第一列
LCD_WriteDat('S'); //显示烟雾
LCD_WriteDat(':');
LCD_WriteDat(smog/100+'0');
LCD_WriteDat(smog%100/10+'0');
LCD_WriteDat(smog%10+'0');
if(smog>200) //烟雾超过200时报警
{
LCD_WriteDat(' ');
LCD_WriteDat('!');
smog=1;
}
else
smog=0;
delay(1000); //延时1秒
}
}
```
请注意,这只是一个简单的示例代码,可能需要根据实际情况进行修改和优化。此外,本代码仅供参考学习之用,使用时请遵循相关法律法规。
阅读全文