基于51单片机的温湿度检测仿真

Proteus仿真电路图
在这里插入图片描述LCD1602.C

#include "LCD1602.h"
 
 /**********************************************
函数功能:LCD1602写命令函数
函数名称:void Lcd1602_Write_Cmd(unsigned char cmd)
**********************************************/
void Lcd1602_Write_Cmd(unsigned char cmd)     //写命令
{
	Read_Busy();
  LCD1602_RS = 0;
  LCD1602_RW = 0;
  LCD1602_DB = cmd;
	LCD_Delay10ms(1);
  LCD1602_EN = 1;
	LCD_Delay10ms(1);
  LCD1602_EN = 0;    
}
 
/**********************************************
函数功能:LCD1602写数据函数
函数名称:void Lcd1602_Write_Data(unsigned char dat) 
**********************************************/
void Lcd1602_Write_Data(unsigned char dat)   //写数据
{
	Read_Busy();
	LCD1602_RS = 1;
	LCD1602_RW = 0;
	LCD1602_DB = dat;
	LCD_Delay10ms(1);
	LCD1602_EN = 1;
	LCD_Delay10ms(1);
	LCD1602_EN = 0;
}

/**********************************************
函数功能:LCD1602字符显示坐标定位函数
函数名称:void LcdSetCursor(unsigned char x,unsigned char y)
**********************************************/
void LcdSetCursor(unsigned char x,unsigned char y)  //坐标显示(x,y),x:行数控制;y:列数控制;
{
	unsigned char addr;
  if(y == 0)
		addr = 0x00 + x;//第一行开始,x表示一行的第x个
  else
    addr = 0x40 + x;//第二行开始,x表示一行的第x个
    Lcd1602_Write_Cmd(addr|0x80);
}
 
/**********************************************
函数功能:LCD1602固定字符显示函数
函数名称:void LcdShowStr(unsigned char x,unsigned char y,unsigned char *str) 
**********************************************/
void LcdShowStr(unsigned char x,unsigned char y,unsigned char *str) 
{
  LcdSetCursor(x,y);      //当前字符的坐标
  while(*str != '\0')     //如果字符串不是换行字符,则继续显示当前字符串。
  {
		Lcd1602_Write_Data(*str++);
  }
}
 
/**********************************************
函数功能:系统上电后LCD1602的初始化
函数名称:void InitLcd1602()            
**********************************************/
void InitLcd1602()              //1602初始化
{
  Lcd1602_Write_Cmd(0x38);    //打开,5*8,8位数据
  Lcd1602_Write_Cmd(0x0c);
  Lcd1602_Write_Cmd(0x06);
  Lcd1602_Write_Cmd(0x01);    //清屏   
}

/**********************************************
函数功能:实现若干个10毫秒的延时
函数名称:void LCD_Delay10ms(unsigned int c)  
**********************************************/
void LCD_Delay10ms(unsigned int c)   //误差 0us
{
	unsigned char i, j;
	for (;c>0;c--)
	{
		i = 20;
		j = 113;
		do
		{
			while (--j);
		} while (--i);
	}
}

void Read_Busy()          //忙检测函数,判断bit7是0,允许执行;1禁止
{
	unsigned char temp;
	LCD1602_DB = 0XFF;  // 十六进制:1111 1111
	LCD1602_RS = 0;  // 0 指令
	LCD1602_RW = 1;	 // 1 读
	do
	{
		LCD1602_EN = 1;		  // 拉高
		temp = LCD1602_DB;  // 将 LCD 状态保存在 temp 中,用于判忙
		LCD1602_EN = 0;		  // 负跳变使能 
	}while(temp & 0x80);  // 结果为 1,LCD 忙,继续循环;结果为 0,LCD 不忙,可以进行后面的操作
}

LCD1602.H

#ifndef __LCD_H_
#define __LCD_H_
/**********************************
当使用的是4位数据传输的时候定义,
使用8位取消这个定义
**********************************/
//#define LCD1602_4PINS
/**********************************
包含头文件
**********************************/
#include "reg52.h"
//---重定义关键词---//
#ifndef uchar
#define uchar unsigned char
#endif
#ifndef uint 
#define uint unsigned int
#endif
/**********************************
51单片机的I/O口定义
**********************************/
#define LCD1602_DB  P0      //data bus 数据总线
sbit LCD1602_RS = P2^0;
sbit LCD1602_RW = P2^1;
sbit LCD1602_EN = P2^2;	 
/**********************************
函数声明
**********************************/
/**********************************
函数名称:void LCD_Delay10ms(unsigned int c);
函数功能:延时函数封闭调用
封闭函数依据:封闭前提为51单片机12MHz
**********************************/
void LCD_Delay10ms(unsigned int c);
void Read_Busy();           //忙检测函数,判断bit7是0,允许执行;1禁止
void Lcd1602_Write_Cmd(unsigned char cmd);     //写命令
void Lcd1602_Write_Data(unsigned char dat);   //写数据
void LcdSetCursor(unsigned char x,unsigned char y);  //坐标显示
void LcdShowStr(unsigned char x,unsigned char y,unsigned char *str);     //显示字符串
void InitLcd1602();         //1602初始化
#endif

DHT11.H

#ifndef _DHT11_H_
#define _DHT11_H_

#include <reg52.h>
#include "intrins.h"
#include "stdio.h"

sbit Temp_data = P1^0;

unsigned int  rec_dat[4];
unsigned char rec_dat_lcd0[6];
unsigned char rec_dat_lcd1[6];
unsigned char rec_dat_lcd2[6];
unsigned char rec_dat_lcd3[6];

void DHT11_start();                    //DHT11起始信号	
unsigned char DHT11_rec_byte();        //接收一个字节
void DHT11_receive();                  //接收温湿度数据
void DHT11_delay_us(unsigned char n);  //延时us   --2*n+5us
void DHT11_delay_ms(unsigned int z);   //延时ms
#endif

DHT11.C

#include "intrins.h"
#include "DHT11.h"

void DHT11_start()//DHT11起始信号	
{
	Temp_data=1;
	DHT11_delay_us(2);
	Temp_data=0;
	DHT11_delay_ms(20);
	Temp_data=1;
	DHT11_delay_us(13);
}

unsigned char DHT11_rec_byte()//接收一个字节
{	
	unsigned char i,dat;	
	for(i=0;i<8;i++)
	{
			while(!Temp_data);
		  DHT11_delay_us(8);
			dat<<=1;
			if(Temp_data==1)
			{
				dat+=1;
			}
			while(Temp_data);
	}
	return dat;	
}

void DHT11_receive()//接收温湿度数据
{
	unsigned int R_H,R_L,T_H,T_L;
	unsigned char RH,RL,TH,TL,revise;
	DHT11_start();
	Temp_data=1;
	if(Temp_data==0)
	{
		while(Temp_data==0);          //等待拉高     
		DHT11_delay_us(40);           //拉高后延时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();    //接收校正位
    DHT11_delay_us(25);           //结束
    if((R_H+R_L+T_H+T_L)==revise) //校正
    {
			RH=R_H;
      RL=R_L;
      TH=T_H;
      TL=T_L;
	  } 
    /*数据处理,方便显示*/
    rec_dat[0]=RH;
    rec_dat[1]=RL;
    rec_dat[2]=TH;
    rec_dat[3]=TL;
	}	
}
void DHT11_delay_us(unsigned char n)//延时us   --2*n+5us
{
	unsigned int c;
	for(c=2*n+5;c>0;c--)
	{
		_nop_();
	}
}

void DHT11_delay_ms(unsigned int z)//延时ms
{
	unsigned char i, j;
	for(;z>0;z--)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
	}
}

main.c

#include "reg52.h"
#include "intrins.h"
#include "stdio.h"
#include "LCD1602.h"
#include "DHT11.h"

sfr AUXR=0X8E; //NOTES:sbit是位操作,用于将某个sfr中具体位赋值给一个变量 

void Timer0Init(void);		//1毫秒@11.0592MHz
void Show_Temperature_Humidity();
void Systeminitial();

//主函数
void main()
{	
	Systeminitial();
	while(1);
}

//中断函数,每次定时器溢出进入中断,执行中断函数
void time0() interrupt 1
{
	//将温湿度测试以及显示函数封闭处理,以提高中断函数的可读性
	Show_Temperature_Humidity();
}

void Timer0Init(void)		//1毫秒@11.0592MHz
{
	AUXR &= 0x7F;		//定时器时钟12T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x18;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	
	EA=1;//打开总中断,打开定时器0中断
	ET0=1;
}

void Systeminitial()
{
	Timer0Init();//初始化定时器
	InitLcd1602();
	//显示固定字符串标识符
	LcdShowStr(0,0,"Humid:");
	LcdShowStr(0,1,"Tempt:");
}

void Show_Temperature_Humidity()
{
  static unsigned int c=0;
  c++;
	if(c==25)
	{
		c=0;
		//显示固定字符串标识符
		LcdShowStr(0,0,"Humid:");
		LcdShowStr(0,1,"Tempt:");
		DHT11_delay_ms(150);
		DHT11_receive();
		//这个函数是打印字符函数,应该是起到数值转化的作用。
		sprintf(rec_dat_lcd0,"%d",rec_dat[0]);
		sprintf(rec_dat_lcd1,"%d",rec_dat[1]);
		sprintf(rec_dat_lcd2,"%d",rec_dat[2]);
		sprintf(rec_dat_lcd3,"%d",rec_dat[3]);
		DHT11_delay_ms(100);
		//湿度
		LcdShowStr(6,0,rec_dat_lcd0);
		LcdShowStr(8,0,".");
		LcdShowStr(9,0,rec_dat_lcd1);
		LcdShowStr(10,0,"%");
		//温度
		LcdShowStr(6,1,rec_dat_lcd2);
		LcdShowStr(8,1,".");
		LcdShowStr(9,1,rec_dat_lcd3);
		LcdShowStr(10,1,"C");
	}
}




  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不知何时归家

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值