#include<reg52.h>
#include<SendDataToPC.h>
#include<AcceptData.h>
#define uint unsigned int
#define uchar unsigned char
#include <math.h>
#define LCD1602_DB P0
uchar DHT11[5],RTflag=0;
uchar FLAG;//超时标志位
uchar xdata a;
float idata set0,set1;
float idata set2,set3;
sbit LCD1602_RS = P2^0;
sbit LCD1602_RW = P2^1;
sbit LCD1602_EN = P2^2;
sbit AlarmSystemVoice = P2^3;
sbit AlarmTemperatureFlag_Light = P2^4;
sbit AlarmCoFlag_Light = P2^5;
sbit AlarmCh2oFlag_Light = P2^6;
sbit ALarmSystemLight = P2^7;
sbit AlarmCoFlag_Wind = P1^6;
sbit AlarmCoFlag_Walve = P1^7;
sbit Return = P1^4;
sbit dat=P1^0;
void InitLcd1602();
uchar table[5];
uint xdata wd,sd;
void Delay_t(uint j)
{ uchar i;
for(;j>0;j--)
{
for(i=0;i<27;i++);
}
}
void Delay_10us(void) //10us延时函数
{
uchar i;
i--;
i--;
i--;
i--;
i--;
i--;
}
void delay(uint z)//1毫秒延时函数
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void lcd_write_com(uchar com) //1602写指令
{
LCD1602_RS=0;
LCD1602_RW=0;
LCD1602_EN=1;
P0=com;
delay(1);
LCD1602_EN=0;
}
void lcd_init() //1602初始化
{
lcd_write_com(0x38);
delay(1);
lcd_write_com(0x08);
delay(1);
lcd_write_com(0x01);//1602清屏指令
delay(1);
lcd_write_com(0x06);
delay(1);
lcd_write_com(0x0C);
delay(1);
}
void lcd_write_data(uchar date)//1602写数据
{
LCD1602_RS=1;
LCD1602_RW=0;
LCD1602_EN=1;
P0=date;
delay(1);
LCD1602_EN=0;
}
void write_str(uchar x,uchar y,uchar *s)//在任意地址写符号字母或数字
{
if(y==0)
lcd_write_com(0x80+x);
else
lcd_write_com(0xc0+x);
while(*s)
{
lcd_write_data(*s);
s++;
}
}
void write_shu(uchar x,uchar y,uchar num)//数据显示函数
{
uchar s,g;
if(y==0)
lcd_write_com(0x80+x);
else
lcd_write_com(0xc0+x);
s=num/10;// 数据分离显示
lcd_write_data(0x30+s);
g=num%10;//数据分离显示
lcd_write_data(0x30+g);
}
uchar write_byte1() //读一个字节
{
uchar i,comdata,temp1;
for(i=0;i<8;i++)
{
FLAG=2;
while((!dat)&&FLAG++);//判断数据位是0还是1
Delay_10us();
Delay_10us();
Delay_10us();
temp1=0;
if(dat)temp1=1; // 如果高电平高过预定0高电平值则数据位为 1
FLAG=2;
while((dat)&&FLAG++);//flag先与后加1 如果dat一直为1 uchar型变量 flag 溢出变为0 再自加1
if(FLAG==1)break; //超时则跳出for循环
comdata<<=1;//左移一位 高位在前 低位在后
comdata|=temp1;
}
return (comdata);
}
void DHT11_5() //读5个字节数据 两个字节为温度数据 两个字节为湿度数据 最后一个字节为校验
{
uchar i,temp;
//主机拉低18ms
dat=0;
Delay_t(180);
dat=1;
//总线由上拉电阻拉高 主机延时20us
Delay_10us();
Delay_10us();
Delay_10us();
Delay_10us();
//主机设为输入 判断从机响应信号
dat=1;
//判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行
if(!dat) //T !
{
FLAG=2; //超时标志位
while((!dat)&&FLAG++);//判断从机是否发出 80us 的低电平响应信号是否结束
FLAG=2;
while((dat)&&FLAG++); //判断从机拉高80us是否结束
for(i=0;i<5;i++)//数据接收状态
{
DHT11[i]=write_byte1();
}
dat=1; //释放数据总线 为下一次读取做好准备
temp=(DHT11[0]+DHT11[1]+DHT11[2]+DHT11[3]);
if(temp==DHT11[4]) //数据校验
{
RTflag=1;
}
if(RTflag==1) //如果RTflag=1 说明读取到得数据正确
{
RTflag=0;
// tm[0]=DATARHT[0]/10;
// tm[1]=DATARHT[0]%10;
// tm[2]=DATARHT[1]/10; //湿度
// tm[3]=DATARHT[2]/10;
// tm[4]=DATARHT[2]%10;
// tm[5]=DATARHT[3]/10; //温度
if(DHT11[2]>set1|DHT11[2]<11)
{
AlarmTemperatureFlag_Light = 0;
}
else if( DHT11[0]<set0|DHT11[0]>60)
{
AlarmTemperatureFlag_Light = 0;
}
else
{ AlarmTemperatureFlag_Light = 1;
}
write_str(0,0,"measurement ");//第一行显示湿度
write_shu(12,0,DHT11[0]);
write_str(14,0,"RH");
write_str(0,1,"Temperature ");//第二行为显示温度
write_shu(12,1,DHT11[2]);
write_str(14,1,"^C");
}
}
}
void DisplayDh11()
{
lcd_init(); //1602初始化
delay(500); //等待DHT11温湿度传感器数据稳定 开始激活DHT11
while(1)//循环读取 并更新数据显示
{
delay(1000);//等待DHT11温湿度传感器数据稳定 开始激活DHT11
write_byte1();//读一个字节
DHT11_5(); //读数据
delay(1000); //延时等待
break;
}
}
/***DH11显示********************************/
void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str);
void LcdStar_Co()
{
unsigned char str[] = "Co";
unsigned char tab[]="Conentration ";
InitLcd1602();/* 初始化 1602 液晶 */
LcdShowStr(0, 0, str);
LcdShowStr(3, 0, tab);
LcdShowStr(0, 1, "Measure");
LcdShowStr(13, 1, "ppm");//添加V电压
}
//CO 检测初始化;
void LcdStar_Ch2o()
{
unsigned char str[] = "Ch2o";
unsigned char tab[]="Conentration ";
// InitLcd1602();/* 初始化 1602 液晶 */
LcdShowStr(0, 0, str);
LcdShowStr(4, 0, tab);
LcdShowStr(0, 1, "Measure");
LcdShowStr(13, 1, "ppm");//添加V电压
}
/* 等待液晶准备好 */
void LcdWaitReady()
{
unsigned char sta;
LCD1602_DB = 0xFF;
LCD1602_RS = 0;
LCD1602_RW = 1;
do {
LCD1602_EN = 1;
sta = LCD1602_DB; //读取状态字
LCD1602_EN = 0;
} while (sta & 0x80); //bit7 等于 1 表示液晶正忙,重复检测直到其等于 0 为止
}
/* 向 LCD1602 液晶写入一字节命令, cmd-待写入命令值 */
void LcdWriteCmd(unsigned char cmd)
{
LcdWaitReady();
LCD1602_RS = 0;
LCD1602_RW = 0;
LCD1602_DB = cmd;
LCD1602_EN = 1;
LCD1602_EN = 0;
}
/* 向 LCD1602 液晶写入一字节数据, dat-待写入数据值 */
void LcdWriteDat(unsigned char dat)
{
LcdWaitReady();
LCD1602_RS = 1;
LCD1602_RW = 0;
LCD1602_DB = dat;
LCD1602_EN = 1;
LCD1602_EN = 0;
}
/* 设置显示 RAM 起始地址,亦即光标位置, (x,y)-对应屏幕上的字符坐标 */
void LcdSetCursor(unsigned char x, unsigned char y)
{
unsigned char addr;
if (y == 0) //由输入的屏幕坐标计算显示 RAM 的地址
addr = 0x00 + x; //第一行字符地址从 0x00 起始
else
addr = 0x40 + x; //第二行字符地址从 0x40 起始
LcdWriteCmd(addr | 0x80); //设置 RAM 地址
}
/* 在液晶上显示字符串, (x,y)-对应屏幕上的起始坐标, str-字符串指针 */
void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str)
{
LcdSetCursor(x, y); //设置起始地址
while (*str != '\0') //连续写入字符串数据,直到检测到结束符
{
LcdWriteDat(*str++); //先取 str 指向的数据,然后 str 自加 1
}
}
/* 初始化 1602 液晶 */
void InitLcd1602()
{
LcdWriteCmd(0x38); //16*2 显示, 5*7 点阵, 8 位数据接口
LcdWriteCmd(0x0C); //显示器开,光标关闭
LcdWriteCmd(0x06); //文字不动,地址自动+1
LcdWriteCmd(0x01); //清屏
}
#include <reg52.h>
#include <intrins.h>
#include <math.h>
#define uchar unsigned char
#define uint unsigned int
//ADC0832
sbit CS = P1^1;
sbit CLK = P1^2;
sbit DIO = P1^3;
uchar len;
int channel;
//5位整数,CO浓度显示;
uchar DisplayCo_Buffer[5];
//2位小数,CH20浓度显示;
uchar DisplayCh2o_Buffer[5];
//延时
void DelayMS(uint ms)
{
uchar t;
while(ms--)
{
for(t=0;t<120;t++);
}
}
//获取AD转换结果
uchar Get_AD_Result(int channel)
{
uchar i,dat1 = 0,dat2 = 0;
//起始控制位
CS = 0;
CLK = 0;
DIO = 1; _nop_(); _nop_();
CLK = 1; _nop_(); _nop_();
//第一个下降沿之前 设DI=1/0
//选择单端/差分(SGL/DIF)模式中的单端输入模式
CLK = 0; DIO=1; _nop_();_nop_();
CLK = 1; ; _nop_();_nop_();
//第二个下降沿之前 设DI=0/1 选择CH0/CH1
CLK = 0;DIO = channel; _nop_();_nop_();
CLK = 1;DIO = 1; _nop_();_nop_();
//第三个下降沿之前 DI=1
CLK = 0; DIO = 1; _nop_();_nop_();
//4-11,共8个下降沿读取数据(MSB->LSB)
for(i=0;i<8;i++)
{
CLK = 1; _nop_();_nop_();
CLK = 0; _nop_();_nop_();
dat1 = dat1<<1|DIO;
}
//11-18 共8个下降沿读取数据(LSB->MSB)
for(i=0;i<8;i++)
{
dat2 = dat2|((uchar)(DIO)<<i);
CLK = 1; _nop_();_nop_();
CLK = 0; _nop_();_nop_();
}
CS = 1;
//如果MSB->LSB和LSB->MSB读取数据结果相同,返回读取结果,否者0
return (dat1==dat2) ? dat1 : 0 ;
DelayMS(10);
}
void DispalyCo()
{
uint Data;
InitLcd1602(); //LCD初始化
LcdStar_Co();
DelayMS(10);
//获取AD转换值 最大值255对应最高电压5.00V
//显示三个数 使用500
channel=0;
Data = Get_AD_Result(channel)*5/255;
// 数据分解
Data = pow(2.718,1.0006*Data)*92.442;
if(Data>set2)
{
AlarmCoFlag_Wind =0;
AlarmCoFlag_Walve=1;
}
else
{
AlarmCoFlag_Wind =1;
AlarmCoFlag_Light=1;
AlarmCoFlag_Walve=0;
}
DelayMS(1000);
DisplayCo_Buffer[0]= Data /10000%10+'0';
DisplayCo_Buffer[1] = Data/1000%10+'0';
DisplayCo_Buffer[2] = Data /100%10+'0';
DisplayCo_Buffer[3] = Data /10%10+'0';
DisplayCo_Buffer[4] = Data /1%10+'0';
LcdShowStr(8, 1,DisplayCo_Buffer);
}
void DisplayCh2o()
{
uint Data;
unsigned char str[] = "Ch2o";
unsigned char tab[]="Conentration ";
InitLcd1602(); //LCD初始化
DelayMS(10);
//获取AD转换值 最大值255对应最高电压5.00V
//显示三个数 使用500
channel=1;
Data = Get_AD_Result(channel)*5/255;
// 数据分解
Data = Data*333;
if (Data>set3)
{
AlarmCh2oFlag_Light = 0;;
}
else
{
AlarmCh2oFlag_Light= 1;
}
DisplayCh2o_Buffer[0]= Data /1000%10+'0';
DisplayCh2o_Buffer[1]= Data /100%10+'0';
DisplayCh2o_Buffer[2] = '.';
DisplayCh2o_Buffer[3] = Data /10%10+'0';
DisplayCh2o_Buffer[4] = Data %10+'0';
LcdShowStr(8, 1,DisplayCh2o_Buffer);
LcdStar_Ch2o();
DelayMS(1000);
}
void DisplayAir()
{
InitLcd1602();
while(1)
{
DispalyCo();
DelayMS(1000);
DisplayCh2o();
DelayMS(1000);
break;
}
}
/*************报警*************/
void AlarmInit()
{
set0 = 40; //湿度40%-60%
set1 = 32; //温度11-32
set2 = 2500;
set3 = 5.71;
}
void Alarm()
{ int b,c,d,trouble[3]={1,1,1};
b=AlarmTemperatureFlag_Light;
c=AlarmCoFlag_Wind;
d=AlarmCh2oFlag_Light;
trouble[0]=b;
trouble[1]=c;
trouble[2]=d;
if(trouble[0]&&trouble[1]&&trouble[2]== 1)
AlarmSystemVoice=1;
else
{
AlarmSystemVoice=0;
ALarmSystemLight=0;
if(trouble[1]== 0) //独立报警提示
AlarmCoFlag_Light=0;
if(trouble[2]== 0)
AlarmCh2oFlag_Light=0;
AlarmCoFlag_Wind =0;
}
}
//主函数
void main()
{
AlarmInit();
InitLcd1602();
DisplayDh11();
delay(1000);
DisplayAir();
Alarm();
CommSend();
}
各子程序均有说明,如还有其他问题可回复本帖咨询 |
|