|
要求如下:
(1)用温湿度模块采集当前环境的温度和湿度,并在LCD上显示;
(2)用按键可以设定一个温度范围,当前温度不在所设置的温度范围内时,LED闪动报警,当温度在设定温度范围内时,停止报警;
(3)用按键可以设定一个湿度范围,当前湿度不在所设置的湿度范围内时,LED闪动报警,当湿度在设定湿度范围内时,停止报警;
(4)LCD上能正确显示当前温度、湿度、设定温度、设定湿度;
(5)显示系统持续工作的时间,从系统上电开始计时,到目前为止,总共运行了多少时间,格式为“HH:MM:SS”。
完成情况:
(1)LCD上显示--------完成
(2)设定温湿度范围---完成(k1:界面切换 k2:数值加 k3:数值减)
(3)显示持续时间-----完成
LCD1602.h
#include "reg51.h"
#ifndef __LCD1602_H_
#define __LCD1602_H_
#define LCD1602_DATAPINS P0
typedef unsigned char uchar;
typedef unsigned int uint;
sbit DATA=P2^0; //定义数据线
sbit LCD1602_RS=P2^6; //定义rs端口
sbit LCD1602_RW=P2^5; //定义rw端口
sbit LCD1602_E=P2^7; //定义en端口
void LcdWriteCom(uchar com);
void LcdWriteData(uchar dat);
void LcdInit();
#endif
LCD1602.c
#include "led1602.h"
/*******************************************************************************
* 函 数 名 : Lcd1602_Delay1ms
* 函数功能 : 延时函数,延时1ms
* 输 入 : c
* 输 出 : 无
* 说 名 : 该函数是在12MHZ晶振下,12分频单片机的延时。
*******************************************************************************/
void Lcd1602_Delay1ms(uint c) //误差 0us
{
uchar a,b;
for (; c>0; c--)
{
for (b=199;b>0;b--)
{
for(a=1;a>0;a--);
}
}
}
/*******************************************************************************
* 函 数 名 : LcdWriteCom
* 函数功能 : 向LCD写入一个字节的命令
* 输 入 : com
* 输 出 : 无
*******************************************************************************/
#ifndef LCD1602_4PINS //当没有定义这个LCD1602_4PINS时
void LcdWriteCom(uchar com) //写入命令
{
LCD1602_E = 0; //使能
LCD1602_RS = 0; //选择发送命令
LCD1602_RW = 0; //选择写入
LCD1602_DATAPINS = com; //放入命令
Lcd1602_Delay1ms(1); //等待数据稳定
LCD1602_E = 1; //写入时序
Lcd1602_Delay1ms(5); //保持时间
LCD1602_E = 0;
}
#else
void LcdWriteCom(uchar com) //写入命令
{
LCD1602_E = 0; //使能清零
LCD1602_RS = 0; //选择写入命令
LCD1602_RW = 0; //选择写入
LCD1602_DATAPINS = com; //由于4位的接线是接到P0口的高四位,所以传送高四位不用改
Lcd1602_Delay1ms(1);
LCD1602_E = 1; //写入时序
Lcd1602_Delay1ms(5);
LCD1602_E = 0;
LCD1602_DATAPINS = com << 4; //发送低四位
Lcd1602_Delay1ms(1);
LCD1602_E = 1; //写入时序
Lcd1602_Delay1ms(5);
LCD1602_E = 0;
}
#endif
/*******************************************************************************
* 函 数 名 : LcdWriteData
* 函数功能 : 向LCD写入一个字节的数据
* 输 入 : dat
* 输 出 : 无
*******************************************************************************/
#ifndef LCD1602_4PINS
void LcdWriteData(uchar dat) //写入数据
{
LCD1602_E = 0; //使能清零
LCD1602_RS = 1; //选择输入数据
LCD1602_RW = 0; //选择写入
LCD1602_DATAPINS = dat; //写入数据
Lcd1602_Delay1ms(1);
LCD1602_E = 1; //写入时序
Lcd1602_Delay1ms(5); //保持时间
LCD1602_E = 0;
}
#else
void LcdWriteData(uchar dat) //写入数据
{
LCD1602_E = 0; //使能清零
LCD1602_RS = 1; //选择写入数据
LCD1602_RW = 0; //选择写入
LCD1602_DATAPINS = dat; //由于4位的接线是接到P0口的高四位,所以传送高四位不用改
Lcd1602_Delay1ms(1);
LCD1602_E = 1; //写入时序
Lcd1602_Delay1ms(5);
LCD1602_E = 0;
LCD1602_DATAPINS = dat << 4; //写入低四位
Lcd1602_Delay1ms(1);
LCD1602_E = 1; //写入时序
Lcd1602_Delay1ms(5);
LCD1602_E = 0;
}
#endif
/*******************************************************************************
* 函 数 名 : LcdInit()
* 函数功能 : 初始化LCD屏
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
#ifndef LCD1602_4PINS
void LcdInit() //LCD初始化子程序
{
LcdWriteCom(0x38); //开显示
LcdWriteCom(0x0c); //开显示不显示光标
LcdWriteCom(0x06); //写一个指针加1
LcdWriteCom(0x01); //清屏
LcdWriteCom(0x80); //设置数据指针起点
}
#else
void LcdInit() //LCD初始化子程序
{
LcdWriteCom(0x32); //将8位总线转为4位总线
LcdWriteCom(0x28); //在四位线下的初始化
LcdWriteCom(0x0c); //开显示不显示光标
LcdWriteCom(0x06); //写一个指针加1
LcdWriteCom(0x01); //清屏
LcdWriteCom(0x80); //设置数据指针起点
}
#endif
main.c
/********************************************************************************************************/
#include<reg51.h>
#include<intrins.h>
#include<led1602.h>
#define uchar unsigned char //无符号字符型类型数据
#define uint unsigned int //无符号整型数据
sbit led=P2^2;
sbit k1=P3^1;
sbit k2=P3^2;
sbit k3=P3^3;
uchar dat_r[4]; //用于存放从DHT11读取到的数值
uchar num[]="0123456789";
uchar Disp[]="RTHC%·";
uint i,j,k;
uchar hrh=80,lrh=40,hth=20,lth=5;
uchar c[8];
uchar b[8],shi,fen,miao;
uchar R_H,R_L,T_H,T_L,RH,RL,TH,TL,revise;
void Timer0Init();
/*********************************************************************************************
函数名:延时函数
调 用:Delay30us();/Delay20ms();/Delay1s();
参 数:无
返回值:无
结 果:延时相应时间
备 注:振荡晶体为11.0592MHz(所有延时函数Copy自STC-ISP(v6.85).exe)
**********************************************************************************************/
void delay(uint i)
{
while(i--);
}
void Delay30us() //@11.0592MHz-40
{
unsigned char i;
i = 11;
while (--i);
}
void Delay20ms() //@11.0592MHz
{
unsigned char i, j;
i = 36;
j = 217;
do
{
while (--j);
} while (--i);
}
void Delay1s() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
i = 8;
j = 1;
k = 243;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
/*********************************************************************************************
函数名:DHT11启动函数
结 果:DHT11开始工作
**********************************************************************************************/
void DHT11_start() // 主机控制DHT11开始工作
{
DATA=1; // 主线空闲状态
_nop_();
_nop_();
DATA=0; // 主机发送开始工作信号
Delay20ms(); //延时18ms以上
DATA=1; // 拉高并延时等待DHT11响应
Delay30us();
}
/*********************************************************************************************
函数名:DHT11读数据函数
调 用:? = DHT11_rec_byte();
参 数:无
返回值:
结 果:读DHT11数据并保存到dat
备 注:
**********************************************************************************************/
uchar DHT11_rec_byte() //接收一个字节
{
uchar i,dat=0;
for(i=0;i<8;i++) //从高到低依次接收8位数据
{
while(!DATA); ////等待50us低电平过去
Delay30us();
Delay30us(); //延时60us,如果还为高则数据为1,否则为0
dat<<=1; //左移位使正确接收8位数据,数据为0时直接移位
if(DATA==1) //数据为1时,使dat加1来接收数据1
dat+=1;
while(DATA); //等待数据线拉低
}
return dat;
}
/*********************************************************************************************
函数名:接收DHT11的40位的数据并校验
调 用:? = DHT11_receive();
参 数:无
返回值:无
结 果:结果保存到dat_r[ i]中
备 注:
**********************************************************************************************/
void DHT11_receive() //接收40位的数据
{
DHT11_start(); // 主机控制DHT11开始工作
if(DATA==0)
{
while(DATA==0); //等待拉高
Delay30us();
Delay30us();
Delay30us(); //拉高后延时80us
R_H=DHT11_rec_byte(); //接收湿度高八位
R_L=DHT11_rec_byte(); //接收湿度低八位
T_H=DHT11_rec_byte(); //接收温度高八位
T_L=DHT11_rec_byte(); //接收温度低八位
revise=DHT11_rec_byte(); //接收校正位
Delay30us(); //结束
if((R_H+R_L+T_H+T_L)==revise) //校正
{
RH=R_H;
RL=R_L;
TH=T_H;
TL=T_L;
}
/*数据处理,方便显示*/
dat_r[0]='0'+(RH/10);
dat_r[1]='0'+(RH%10);
dat_r[2]='0'+(TH/10);
dat_r[3]='0'+(TH%10);
}
}
void Timer0Init()
{
TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。
TH0=0Xd8; //给定时器赋初值,定时10ms
TL0=0Xf0;
TR0=1;//打开定时器
}
void timepros()
{
b[0]=num[shi/10];
b[1]=num[shi%10];
b[2]=0x3a;
b[3]=num[fen/10];
b[4]=num[fen%10];
b[5]=0x3a;
b[6]=num[miao/10];
b[7]=num[miao%10];
}
void secondtimepros()
{
c[0]=num[lrh/10];
c[1]=num[lrh%10];
c[2]=num[hrh/10];
c[3]=num[hrh%10];
c[4]=num[lth/10];
c[5]=num[lth%10];
c[6]=num[hth/10];
c[7]=num[hth%10];
}
void keyprosA()
{
if(k1==0) //检测按键 K1 是否按下
{
delay(1000); //消除抖动 一般大约 10ms
if(k1==0) //再次判断按键是否按下
{
i++; //led 状态取反
LcdWriteCom(0x01);
}
while(!k1); //检测按键是否松开
}
}
void keyprosB()
{
if(k2==0) //检测按键 K1 是否按下
{
delay(1000); //消除抖动 一般大约 10ms
if(k2==0) //再次判断按键是否按下
{
j++; //led 状态取反
LcdWriteCom(0x01);
}
while(!k2); //检测按键是否松开
}
}
void keyprosC()
{
if(k3==0) //检测按键 K1 是否按下
{
delay(1000); //消除抖动 一般大约 10ms
if(k3==0) //再次判断按键是否按下
{
k++; //led 状态取反
LcdWriteCom(0x01);
}
while(!k3); //检测按键是否松开
}
}
/*********************************************************************************************
函数名:主函数
结 果:读DHT11数据并送到1602显示**********************************************************************************************/
void main (void)
{
static uint n;
Timer0Init();
LcdInit();
Delay1s(); //LCD初始化
while(1)
{
keyprosA();
keyprosB();
keyprosC();
if(TF0==1) //定时器T0溢出标志
{
TF0=0;
TH0=0Xd8; //给定时器赋初值,定时10ms
TL0=0Xf0;
n++;
}
if(n==100)
{
n=0;
miao++;
if(miao==60)
{
miao=0;
fen++;
if(fen==60)
{
fen=0;
shi++;
if(shi==60)
{
shi=0;
miao=0;
fen=0;
}
}
}
if(i%5==0)
{
DHT11_receive();//接受数据
if(RH>hrh||RH<lrh||TH>hth||TH<lth)
{
led=~led;
}
else
{
led=1;
}
LcdWriteCom(0x80);//uchar Disp[]="RTHC%·";
LcdWriteData(Disp[0]);//R
LcdWriteData(Disp[2]);//H
LcdWriteData(0X3a);//:
LcdWriteData(dat_r[0]);
LcdWriteData(dat_r[1]);
LcdWriteData(Disp[4]);
LcdWriteCom(0x08+0x80);
LcdWriteData(Disp[1]);//T
LcdWriteData(Disp[2]);//H
LcdWriteData(0X3a);//:
LcdWriteData(dat_r[2]);
LcdWriteData(dat_r[3]);
LcdWriteData(Disp[3]);
timepros();
LcdWriteCom(0x44+0x80);
LcdWriteData(b[0]);
LcdWriteData(b[1]);
LcdWriteData(0X3a);
LcdWriteData(b[3]);
LcdWriteData(b[4]);
LcdWriteData(0X3a);
LcdWriteData(b[6]);
LcdWriteData(b[7]);
}
else if(i%5==1)
{
if(j!=0)
{
lrh=lrh+j;
j=0;
}
if(k!=0)
{
lrh=lrh-k;
k=0;
}
secondtimepros();
//首行
LcdWriteCom(0x80);//uchar Disp[]="RTHC%·";
LcdWriteData(Disp[0]);//R
LcdWriteData(Disp[2]);//H
LcdWriteData(0X3a);//:
LcdWriteData(c[0]);
LcdWriteData(c[1]);
LcdWriteData(Disp[4]);
LcdWriteData(0X2a);//<
LcdWriteCom(0x08+0x80);
LcdWriteData(Disp[0]);//T
LcdWriteData(Disp[2]);//H
LcdWriteData(0X3a);//:
LcdWriteData(c[2]);
LcdWriteData(c[3]);
LcdWriteData(Disp[4]);
LcdWriteCom(0x40+0x80);
LcdWriteData(Disp[1]);//T
LcdWriteData(Disp[2]);//H
LcdWriteData(0X3a);//:
LcdWriteData(c[4]);
LcdWriteData(c[5]);
LcdWriteData(Disp[3]);
LcdWriteCom(0x48+0x80);
LcdWriteData(Disp[1]);//T
LcdWriteData(Disp[2]);//H
LcdWriteData(0X3a);//:
LcdWriteData(c[6]);
LcdWriteData(c[7]);
LcdWriteData(Disp[3]);
}
else if(i%5==2)
{
if(j!=0)
{
hrh=hrh+j;
j=0;
}
if(k!=0)
{
hrh=hrh-k;
k=0;
}
secondtimepros();
//首行
LcdWriteCom(0x80);//uchar Disp[]="RTHC%·";
LcdWriteData(Disp[0]);//R
LcdWriteData(Disp[2]);//H
LcdWriteData(0X3a);//:
LcdWriteData(c[0]);
LcdWriteData(c[1]);
LcdWriteData(Disp[4]);
LcdWriteCom(0x08+0x80);
LcdWriteData(Disp[0]);//T
LcdWriteData(Disp[2]);//H
LcdWriteData(0X3a);//:
LcdWriteData(c[2]);
LcdWriteData(c[3]);
LcdWriteData(Disp[4]);
LcdWriteData(0X2a);//<
LcdWriteCom(0x40+0x80);
LcdWriteData(Disp[1]);//T
LcdWriteData(Disp[2]);//H
LcdWriteData(0X3a);//:
LcdWriteData(c[4]);
LcdWriteData(c[5]);
LcdWriteData(Disp[3]);
LcdWriteCom(0x48+0x80);
LcdWriteData(Disp[1]);//T
LcdWriteData(Disp[2]);//H
LcdWriteData(0X2a);//:
LcdWriteData(c[6]);
LcdWriteData(c[7]);
LcdWriteData(Disp[3]);
}
else if(i%5==3)
{
if(j!=0)
{
lth=lth+j;
j=0;
}
if(k!=0)
{
lth=lth-k;
k=0;
}
secondtimepros();
//首行
LcdWriteCom(0x80);//uchar Disp[]="RTHC%·";
LcdWriteData(Disp[0]);//R
LcdWriteData(Disp[2]);//H
LcdWriteData(0X3a);//:
LcdWriteData(c[0]);
LcdWriteData(c[1]);
LcdWriteData(Disp[4]);
LcdWriteCom(0x08+0x80);
LcdWriteData(Disp[0]);//T
LcdWriteData(Disp[2]);//H
LcdWriteData(0X3a);//:
LcdWriteData(c[2]);
LcdWriteData(c[3]);
LcdWriteData(Disp[4]);
LcdWriteCom(0x40+0x80);
LcdWriteData(Disp[1]);//T
LcdWriteData(Disp[2]);//H
LcdWriteData(0X3a);//:
LcdWriteData(c[4]);
LcdWriteData(c[5]);
LcdWriteData(Disp[3]);
LcdWriteData(0X2a);//<
LcdWriteCom(0x48+0x80);
LcdWriteData(Disp[1]);//T
LcdWriteData(Disp[2]);//H
LcdWriteData(0X3a);//:
LcdWriteData(c[6]);
LcdWriteData(c[7]);
LcdWriteData(Disp[3]);
}
else if(i%5==4)
{
if(j!=0)
{
hth=hth+j;
j=0;
}
if(k!=0)
{
hth=hth-k;
k=0;
}
secondtimepros();
//首行
LcdWriteCom(0x80);//uchar Disp[]="RTHC%·";
LcdWriteData(Disp[0]);//R
LcdWriteData(Disp[2]);//H
LcdWriteData(0X3a);//:
LcdWriteData(c[0]);
LcdWriteData(c[1]);
LcdWriteData(Disp[4]);
LcdWriteCom(0x08+0x80);
LcdWriteData(Disp[0]);//T
LcdWriteData(Disp[2]);//H
LcdWriteData(0X3a);//:
LcdWriteData(c[2]);
LcdWriteData(c[3]);
LcdWriteData(Disp[4]);
LcdWriteCom(0x40+0x80);
LcdWriteData(Disp[1]);//T
LcdWriteData(Disp[2]);//H
LcdWriteData(0X3a);//:
LcdWriteData(c[4]);
LcdWriteData(c[5]);
LcdWriteData(Disp[3]);
LcdWriteCom(0x48+0x80);
LcdWriteData(Disp[1]);//T
LcdWriteData(Disp[2]);//H
LcdWriteData(0X3a);//:
LcdWriteData(c[6]);
LcdWriteData(c[7]);
LcdWriteData(Disp[3]);
LcdWriteData(0X2a);//<
}
}
}
}
|
-
视频.gif
(4.26 MB, 下载次数: 69)
成果图
评分
-
查看全部评分
|