#include<reg51.h>
#include"lcd.h"
#include"ds1302.h"
#include"i2c.h"
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit DHT11_DATA=P3^7;
sbit KEY0=P1^0;
sbit KEY1=P1^7;
sbit KEY2=P1^2;
sbit BEEP=P2^2;
uchar Overtime_counter; //判断等待是否超时的计数器。利用uchar型的数值范围进行自动延时控制(时长由初值决定),并判断是否超时
uchar bit_value; //从DATA总线上读到的位值
uchar T_data_H,T_data_L,RH_data_H,RH_data_L,checkdata;//校验过的温度高8位,温度低8位,湿度高8位,湿度低8位,校验和8位
uchar T_data_H_temp,T_data_L_temp,RH_data_H_temp,RH_data_L_temp,checkdata_temp;//未经校验的数据
uchar comdata; //从DHT11读取的一个字节的数据
void LcdDisplay();
uint num=0;
uint t=0;
uint count=0;
uint set_quan=20;
uint licheng=0;
//--定义全局变量--//
unsigned int num0 = 66,num1 = 23,n;
//--声明全局函数--//
void At24c02Write(unsigned char ,unsigned char );
unsigned char At24c02Read(unsigned char );
void Delay10ms(unsigned int c); //误差 0us
void init()
{
TMOD=1;
TH0=(65535-50000)/256;
TH1=(65535-50000)%256;
IT0=1;
EX0=1;
TR0=1;
ET0=1;
EA=1;
}
void Delay_10us(void);
void Delay_100us(uint i);
void Delay_100ms(uint i);
/*****************从DHT11读取一个字节函数******************/
void Read_Byte(void);
/*****************DHT11读取五个字节函数******************/
void Read_DHT11(void);
void main()
{
LcdInit();
//Ds1302Init();
init();
KEY0=1;
KEY1=1;
KEY2=1;
BEEP=0;
// At24c02Write(2,12);//将路程写入存储
// Delay_100ms(1);
// At24c02Write(1,23);//将路程写入存储
set_quan = At24c02Read(2);
licheng=At24c02Read(0)*256+At24c02Read(1);
while(1)
{
set_quan = At24c02Read(2);
licheng=At24c02Read(0)*256+At24c02Read(1);
if(KEY0==0)
{
// BEEP=!BEEP;
set_quan++;
At24c02Write(2,set_quan);//将设置的最大速度写入存储
}
if(KEY1==0)
{
set_quan--;
At24c02Write(2,set_quan);//将设置的最大速度写入存储
}
if(KEY2==0)
{
licheng=0;
At24c02Write(0,0);//将路程写入存储
Delay_100ms(1);
At24c02Write(1,0);//将路程写入存储
}
Read_DHT11();/////////调用温湿度读取子程序
Ds1302ReadTime();
LcdDisplay();
}
}
void Delay10ms(unsigned int c) //误差 0us
{
unsigned char a, b;
//--c已经在传递过来的时候已经赋值了,所以在for语句第一句就不用赋值了--//
for (;c>0;c--)
{
for (b=38;b>0;b--)
{
for (a=130;a>0;a--);
}
}
}
/*******************************************************************************
* 函 数 名 : void At24c02Write(unsigned char addr,unsigned char dat)
* 函数功能 : 往24c02的一个地址写入一个数据
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void At24c02Write(unsigned char addr,unsigned char dat)
{
I2C_Start();
I2C_SendByte(0xa0, 1);//发送写器件地址
I2C_SendByte(addr, 1);//发送要写入内存地址
I2C_SendByte(dat, 0); //发送数据
I2C_Stop();
}
/*******************************************************************************
* 函 数 名 : unsigned char At24c02Read(unsigned char addr)
* 函数功能 : 读取24c02的一个地址的一个数据
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
unsigned char At24c02Read(unsigned char addr)
{
unsigned char num;
I2C_Start();
I2C_SendByte(0xa0, 1); //发送写器件地址
I2C_SendByte(addr, 1); //发送要读取的地址
I2C_Start();
I2C_SendByte(0xa1, 1); //发送读器件地址
num=I2C_ReadByte(); //读取数据
I2C_Stop();
return num;
}
void inter() interrupt 0
{
count ++;
}
void timer() interrupt 1
{
t++;
if(t>=20)
{
t=0;
num=count;
if(count>=set_quan)BEEP=0;
else BEEP=1;
licheng=licheng+count;
count=0;
At24c02Write(0,licheng/256);//将路程写入存储
Delay_100ms(1);
At24c02Write(1,licheng%256);//将路程写入存储
}
TH0=(65535-50000)/256;
TH1=(65535-50000)%256;
}
void LcdDisplay()
{
LcdWriteCom(0x80+0X40);
LcdWriteData('0'+TIME[2]/16); //时
LcdWriteData('0'+(TIME[2]&0x0f));
LcdWriteData('-');
LcdWriteData('0'+TIME[1]/16); //分
LcdWriteData('0'+(TIME[1]&0x0f));
LcdWriteData('-');
LcdWriteData('0'+TIME[0]/16); //秒
LcdWriteData('0'+(TIME[0]&0x0f));
LcdWriteData(' ');
// licheng=12345;
LcdWriteData('0'+licheng/10000);
LcdWriteData('0'+licheng%10000/1000);
LcdWriteData('0'+licheng%1000/100);
LcdWriteData('0'+licheng%100/10);
LcdWriteData('0'+licheng%10);
// LcdWriteData('0'+At24c02Read(0)/100);
// LcdWriteData('0'+At24c02Read(0)%100/10);
// LcdWriteData('0'+At24c02Read(0)%10);
// LcdWriteData(' ');
// LcdWriteData('0'+At24c02Read(1)/100);
// LcdWriteData('0'+At24c02Read(1)%100/10);
// LcdWriteData('0'+At24c02Read(1)%10);
LcdWriteCom(0x80);
// LcdWriteData('0'+TIME[4]/16); //月
LcdWriteData('0'+(TIME[4]&0x0f));
LcdWriteData('-');
LcdWriteData('0'+TIME[3]/16); //日
LcdWriteData('0'+(TIME[3]&0x0f));
LcdWriteData(' ');
// LcdWriteData('0'+set_quan/1000);//显示设置的圈数上限
LcdWriteData('0'+set_quan%1000/100);
LcdWriteData('0'+set_quan%100/10);
LcdWriteData('0'+set_quan%10);
LcdWriteCom(0x89);
// LcdWriteData('0'+num/1000);
LcdWriteData('0'+num%1000/100);
LcdWriteData('0'+num%100/10);
LcdWriteData('0'+num%10);
LcdWriteData(' ');
LcdWriteData('0'+T_data_H/10);
LcdWriteData('0'+T_data_H%10); //显示温度 num1
// LcdWriteData('0'+num1/10);
// LcdWriteData('0'+num1%10); //显示温度 num1
LcdWriteData('C');
}
void Delay_10us(void)
{
uchar i;
i--;
i--;
i--;
i--;
i--;
i--;
}
void Delay_100us(uint i)
{
uchar j;
for(;i>0;i--)
{
for(j=0;j<10;j++)
Delay_10us();
}
}
void Delay_100ms(uint i)
{
uint j;
for(;i>0;i--)
{
for(j=0;j<10000;j++)
Delay_10us();
}
}
/*****************从DHT11读取一个字节函数******************/
void Read_Byte(void)
{
uchar i;
for(i=0;i<8;i++) //循环8次,读取8bit的数据
{
Overtime_counter=2;
while((!DHT11_DATA)&&Overtime_counter++);
Delay_10us(); //26-28us的低电平判断门限
Delay_10us();
bit_value=0; //跳过门限后判断总线是高还是低,高为1,低为0
if(DHT11_DATA)
bit_value=1;
Overtime_counter=2;
while((DHT11_DATA)&&Overtime_counter++);
if(Overtime_counter==1)
break; //超时则跳出for循环
comdata<<=1; //左移1位,LSB补0
comdata|=bit_value; //LSB赋值
}
}
/*****************DHT11读取五个字节函数******************/
void Read_DHT11(void)
{
uchar checksum;
DHT11_DATA=0; //主机拉低18ms
Delay_100us(180);
DHT11_DATA=1; //总线由上拉电阻拉高 主机延时20us-40us
Delay_10us();
Delay_10us();
Delay_10us();
Delay_10us();
DHT11_DATA=1; //主机转为输入或者输出高电平,DATA线由上拉电阻拉高,准备判断DHT11的响应信号
if(!DHT11_DATA) //判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行
{
Overtime_counter=2; //判断DHT11发出的80us的低电平响应信号是否结束
while((!DHT11_DATA)&&Overtime_counter++);
Overtime_counter=2; //判断DHT11是否发出80us的高电平,如发出则进入数据接收状态
while((DHT11_DATA)&&Overtime_counter++);
Read_Byte(); //读取湿度值整数部分的高8bit
RH_data_H_temp=comdata;
Read_Byte(); //读取湿度值小数部分的低8bit
RH_data_L_temp=comdata;
Read_Byte(); //读取温度值整数部分的高8bit
T_data_H_temp=comdata;
Read_Byte(); //读取温度值小数部分的低8bit
T_data_L_temp=comdata;
Read_Byte(); //读取校验和的8bit
checkdata_temp=comdata;
DHT11_DATA=1;//读完数据将总线拉高
checksum=(T_data_H_temp + T_data_L_temp + RH_data_H_temp + RH_data_L_temp);//进行数据校验
if(checksum==checkdata_temp)
{
RH_data_H = RH_data_H_temp;
RH_data_L = RH_data_L_temp;
T_data_H = T_da