|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区
您需要 登录 才可以下载或查看,没有账号?立即注册
×
#include<reg52.h>
#include<intrins.h>
#define LCD1602_DB P0//LCD数据收发8位并行口
bit flag1s = 0;
bit state=0;
bit temp=0;//数据更新位定义
sbit clk=P1^2;
sbit dout=P1^0;
sbit cs=P1^1;
sbit LCD1602_RS = P2^6;
sbit LCD1602_RW = P2^5;
sbit LCD1602_E = P2^7;//LCD控制接口
sbit IO_18B20 = P3^7;//温度传感器接口
sbit beep=P3^6;//蜂鸣器控制接口
sbit key1=P2^0;
unsigned int flag,time=1,temper=0,result=0,xinlv=0,num=0,water=0,sulv=0;//数据更新时间计数值
//unsigned char IntToString(unsigned char *str, int dat);
void ShowDistance();
void InitLcd1602();
void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str);
bit Get18B20Temp(int *temp);
bit Start18B20();//函数声明
void DelayX10us(unsigned char t)//us级别延时
{
do {
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
} while (--t);
}
void delayms(unsigned int ms)//ms级别延时
{
unsigned int i;
for(i=0;i<123*ms;i++);
}
void keyscan()//按键读取
{
if(key1==0)
{
key1=1;
delayms(50); //消抖
if(key1==0)
{
water++;//判断是否计数
}
}
}
unsigned char TLC549_ADC()
{
unsigned char i,adc;
clk=0;
cs=0;
for(i=0;i<8;i++)
{
adc<<=1;
adc|=dout;
clk=1;
clk=0;
}
cs=1;
delayms(1);
return adc;
}
void main()
{
bit res;
int temp;
int intT, decT;
unsigned char len,co2;//变量定义
unsigned char t[6],display[5],sudu[3];
unsigned char name[]="T:";//初始显示内容
unsigned char CO2[]="CO2:";//初始显示内容
unsigned char water[]="W:";
EA = 1;
TMOD=0x01;
TH0 = 0xFC;
TL0 = 0x18;
ET0 = 1;
TR0 = 1;//定时器0初始化
EX1=1;//定时器1中断初始化
IT1 = 1;
InitLcd1602();
Start18B20();//传感器初始化
LcdShowStr(0,1,name);
LcdShowStr(8,1,CO2);
LcdShowStr(11,0,water);
beep=0;
len=0;
while(1)
{
co2=TLC549_ADC();
display[0]=co2*195/10000+'0';
display[1]='.';
display[2]=co2*195%10000/1000+'0';
display[3]=co2*195%1000/100+'0';
display[4]='\0';
keyscan();//读取按键值
if(flag == 1) //每过100ms更新
{ flag = 0;
ShowDistance();
}
if(state == 1) //每过100ms更新
{ state = 0;
LcdShowStr(12,1,display);
}
if (flag1s)//每过100ms更新温度值
{
flag1s = 0;
res = Get18B20Temp(&temp);
if (res)
{ intT = temp >> 4;
decT = temp & 0xF;
decT = (decT*10) / 16;
}
Start18B20();
}
t[len] =intT/100+'0';
t[len+1] =(intT/10)%10+'0';
t[len+2] =intT%10+'0';
t[len+3] ='.';
t[len+4] =decT/10+'0';
t[len+5] = '\0';
LcdShowStr(2,1, t);//动态显示温度
sudu[0]=sulv/10+'0';
sudu[1]=sulv%10+'0';
sudu[2]='\0';
LcdShowStr(13,0,sudu);
if(temp)//每过100ms判断温度是否超过设定温度
{
temp=0;
if(intT>=38||xinlv>=100||xinlv<=50||sulv<=40||sulv>=80||(co2*195/10000)>=2)
{
beep=1;
}
else
{
beep=0;
}
}
}
}
void Interrupt1() interrupt 2
{
time++;
}
void InterruptTimer0() interrupt 1
{
static unsigned int cnt = 0;
static unsigned char tmr1s = 0;
TH0 = 0xFC;
TL0 = 0x18;
temper++;
if(temper>=100)//数据更新时间计数值
{
temper=0;
temp=1;
state=1;
}
cnt++;
if(cnt >=1000)//数据更新时间计数值
{
cnt = 0;
flag = 1;
//time=time+1;
num++;
xinlv=result*60/num;
result=time;
sulv=water*60/num;
}
tmr1s++;
if (tmr1s >= 100)//数据更新时间计数值
{
tmr1s = 0;
flag1s = 1;
}
}
void ShowDistance()
{
unsigned char buff[3];
unsigned int Distance ;
Distance=xinlv;
buff[2] = Distance%10 + '0';
buff[1] = (Distance/10)%10 + '0';
buff[0] = Distance/100 + '0'; //在lcd上显示
LcdShowStr(0, 0, "HR:");
LcdShowStr(3, 0, &buff);
LcdShowStr(6, 0, "/min");
}
/*unsigned char IntToString(unsigned char *str, int dat) //数据格式转换
{
signed char i = 0;
unsigned char len = 0;
unsigned char buf[6];
if (dat < 0)
{
dat = -dat;
*str++ = '-';
len++;
}
do {
buf[i++] = dat % 10;
dat /= 10;
} while (dat > 0);
len += i;
while (i-- > 0)
{
*str++ = buf + '0';
}
*str = '\0';
return len;
}*/
bit Get18B20Ack() //温度传感器时钟应答判断是否连接
{
bit ack;
EA = 0;
IO_18B20 = 0;
DelayX10us(50);
IO_18B20 = 1;
DelayX10us(6);
ack = IO_18B20;
while(!IO_18B20);
EA = 1;
return ack;
}
void Write18B20(unsigned char dat)//写命令
{
unsigned char mask;
EA = 0;
for (mask=0x01; mask!=0; mask<<=1)
{
IO_18B20 = 0;
_nop_();
_nop_();
if ((mask&dat) == 0)
IO_18B20 = 0;
else
IO_18B20 = 1;
DelayX10us(6);
IO_18B20 = 1;
}
EA = 1;
}
unsigned char Read18B20()//读温度数据
{
unsigned char dat;
unsigned char mask;
EA = 0;
for (mask=0x01; mask!=0; mask<<=1)
{
IO_18B20 = 0;
_nop_();
_nop_();
IO_18B20 = 1;
_nop_();
_nop_();
if (!IO_18B20)
dat &= ~mask;
else
dat |= mask;
DelayX10us(6);
}
EA = 1;
return dat;
}
bit Start18B20()//起始时钟
{
bit ack;
ack = Get18B20Ack();
if (ack == 0)
{
Write18B20(0xCC);
Write18B20(0x44);
}
return ~ack;
}
bit Get18B20Temp(int *temp)//温度数据转换为十进制
{
bit ack;
unsigned char LSB, MSB;
ack = Get18B20Ack();
if (ack == 0)
{
Write18B20(0xCC);
Write18B20(0xBE);
LSB = Read18B20();
MSB = Read18B20();
*temp = ((int)MSB << 8) + LSB;
}
return ~ack;
}
void LcdWaitReady()//lcd初始化函数
{
unsigned char sta;
LCD1602_DB = 0xFF;
LCD1602_RS = 0;
LCD1602_RW = 1;
do {
LCD1602_E = 1;
sta = LCD1602_DB;
LCD1602_E = 0;
} while (sta & 0x80);
}
void LcdWriteCmd(unsigned char cmd) //lcd写命令函数
{
LcdWaitReady();
LCD1602_RS = 0;
LCD1602_RW = 0;
LCD1602_DB = cmd;
LCD1602_E = 1;
LCD1602_E = 0;
}
void LcdWriteDat(unsigned char dat)//lcd写数据函数
{
LcdWaitReady();
LCD1602_RS = 1;
LCD1602_RW = 0;
LCD1602_DB = dat;
LCD1602_E = 1;
LCD1602_E = 0;
}
void LcdSetCursor(unsigned char x, unsigned char y)//设置光标
{
unsigned char addr;
if (y == 0)
{
addr = 0x00 + x;
}
else
{
addr = 0x40 + x;
}
LcdWriteCmd(addr | 0x80);
}
void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str)//lcd显示字符串
{
LcdSetCursor(x, y);
while (*str != '\0')
{
LcdWriteDat(*str++);
}
}
void InitLcd1602()//lcd初始化
{
LcdWriteCmd(0x38);
LcdWriteCmd(0x0C);
LcdWriteCmd(0x06);
LcdWriteCmd(0x01);
} |
|