stc12c5a60s DHT11温湿度传感器

∥☆過路亽.° 提交于 2020-01-04 03:25:16

DHT11温湿度传感器

DHT11.h

#ifndef __DHT11_H__
#define __DHT11_H__

#ifndef uchar
#define uchar unsigned char
#endif

#ifndef uint
#define uint unsigned int
#endif
#include <reg52.h>
#include <intrins.h>

//IO口定义
sbit OUT = P2^7;

//函数声明
void RH( uchar *s );
void Delay(uint x);

//声明外部函数
extern void Uart_send_str(char *str, int len);
extern void Uart1Init();
//extern void Uart_send(char str);


#endif

DHT11.c

/******************************************************************/
/*		平台:Keil U4 + DHT11温湿度模块							  */
/*		名称:通过串口显示温湿度								  */
/*		编写:WCT												  */
/*		日期:2019年1月22日16:57:18								  */
/*		QQ:  497950600  										  */
/*		晶振:11.0592MHZ										  */
/*		变更记录:无											  */
/******************************************************************/
#include "DHT11.h"

/**************/
/*   定义区   */
/**************/
uchar U8FLAG;
uchar U8count, U8temp;
uchar U8T_data_H_temp, U8T_data_L_temp, U8RH_data_H_temp, U8RH_data_L_temp, U8checkdata_temp;
uchar U8comdata;
uchar count = 0, count_r = 0; 
uint U16temp1, U16temp2;

void Delay(uint x)
{  //x = 1, 约 20us
	uchar i;
	for( ; x > 0; x --)
	{
		for(i = 0;i < 29; i ++);
	}
}

void Delay_10us()
{
   uchar i;
   i = 25;
   while( -- i );
}

//void Delay(unsigned int x)		//@11.0592MHz 延时1ms
//{
//	while(x--)
//	{
//		unsigned char i, j;
//		_nop_();
//		i = 11;
//		j = 190;
//		do
//		{
//			while (--j);
//		} while (--i);
//	}
//}
//void Delay_10us()		//@11.0592MHz
//{
//	unsigned char i;
//
//	_nop_();
//	_nop_();
//	_nop_();
//	i = 24;
//	while (--i);
//}

/****************************/
/*		字节读取函数        */
/* 湿度数据和温度数据的读取 */
/****************************/
void COM()
{
	uchar i;
	for(i = 0; i < 8; i ++)
	{
		U8FLAG = 2;
		while((!OUT) && U8FLAG ++ ); //等待数据出现
		Delay_10us();
		Delay_10us();
		Delay_10us();
		U8temp = 0;
		//判断数据位是0还是1
		//如果高电平高过预定0高电平则数据位为1
		if( OUT ) //高电平持续大于28us
		{
			U8temp = 1;
		}
		U8FLAG = 2;
		while( ( OUT ) && U8FLAG ++);
		//超时则跳出for循环
		if( U8FLAG == 1)
		{
			break;
		}
		U8comdata <<= 1;
		U8comdata |= U8temp;
	}
}

/***************************************/
/*		温湿度读取子程序			   */
/***************************************/
void RH( uchar *s )
{
	//主机拉低至少18ms
	OUT = 0;
	Delay(900);
	//主机发送完开始信号,拉高20-40us
	OUT = 1;
	Delay(2);
	
	//主机设为输入 判断从机响应信号
	OUT = 1;
	//判断从机是否有低电平响应信号
	if( ! OUT )
	{
		U8FLAG = 2;
		//判断从机发出 80us 的低电平信号是否结束
		while( ( !OUT ) && U8FLAG ++ );
		U8FLAG = 2;
		//判断从机是否发出 80us 的高电平,如发出则进入数据接收状态
		while( OUT && U8FLAG ++ );
		//数据接收状态
		COM();
		U8RH_data_H_temp = U8comdata;
		COM();
		U8RH_data_L_temp = U8comdata;
		COM();
		U8T_data_H_temp = U8comdata;
		COM();
		U8T_data_L_temp = U8comdata;
		COM();
		U8checkdata_temp = U8comdata;
		OUT = 1;

		//数据校验
		U8temp =( U8T_data_H_temp + U8T_data_L_temp + U8RH_data_H_temp + U8RH_data_L_temp );
		if( U8temp == U8checkdata_temp )
		{
			 s[0] = U8RH_data_H_temp; //---湿度高8位--整数部分
			 s[1] = U8RH_data_L_temp; //---湿度低8位--小数部分
			 s[2] = U8T_data_H_temp;  //---温度高8位--整数部分
			 s[3] = U8T_data_L_temp;  //---温度低8位--小数部分
			 s[4] = U8checkdata_temp; //---校验字节
		}
	}	
}

uart.c

/**********************************************/
/*			平台:Keil U4 + STC12C5A60S       */
/*			名称:串口通信					  */
/*			编写:WCT						  */
/*			日期:2019年1月21日18:43:49		  */
/*			QQ: 497950600					  */
/*			晶振:11.0592MHZ				  */
/*			变更记录: 无					  */
/**********************************************/

#include <reg52.h>

#define F_f 11059200UL   //晶振频率11.0692MHZ
#define Baud_rate 9600UL //波特率9600

sfr AUXR = 0x8E; //定义特殊功能寄存器AUXR
sfr BRT = 0x9C;	 //定义独立波特率发生寄存器BRT

void Uart_send_str(unsigned char *str, int len)
{
	int i;
	for(i = 0; i < len; i ++ )
	{
		SBUF = str[i];
		while( !TI ); //等待发送完成
		TI = 0; 	  //清除发送中断请求
	}
}

//void Uart_send(char str)
//{
//	SBUF = str;
//	while( !TI ); //等待发送完成
//	TI = 0; 	  //清除发送中断请求
//}

void Uart1Init()
{
	PCON &= 0x7F; // 波特率不加倍
	SCON = 0x50;  // 设置串行通信工作方式1,并允许串行接受
	AUXR &= 0xFB; // 独立波特率发生器时钟12T
	BRT = 256 - F_f / (12 * Baud_rate * 32); //独立波特率发生器装载初值
	AUXR |= 0x11; // 允许独立波特率发生器作为串口波特率发生器,并开启
	EA = 1;	      // 开启总中断
	ES = 1;		  // 开启串行中断
}

//UART中断处理函数
void Uart1Routine() interrupt 4
{
	unsigned char uart_sbuf;
	if(RI) //接受完成RI = 1;
	{
		uart_sbuf = SBUF;
		if(uart_sbuf == 0xaa )
		{
			Uart_send_str("ok", 2);
		}
		RI = 0;	 //清除接受中断请求
	}
}

LED_show.c

/*************************************************/
/*		平台:Keil U4 + STC12C5A60S2			 */
/*		名称:LED显示数据 + 串口显示			 */
/*		编写:WCT								 */
/*		日期:2019年1月23日13:39:14		         */
/*		QQ:  497950600						     */
/*		晶振:11.0592							 */
/*		变更记录:无							 */
/*************************************************/
#include <reg52.h>
#include <stdio.h>
#include "DHT11.h"

sfr AUXR = 0x8e;

//定义位选
sbit ASEG = P1^2;
sbit BSEG = P1^3;
sbit CSEG = P1^4;
sbit DSEG = P1^5;

uchar code smgduan[]=	 //共阴数码管显示0~F的值
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

uchar showdata[4] = { 0 }; //用于显示数据
uchar outdata[6] = { "RS232" }; //定义发送字节数
uchar out[30] = { 0 };

void seg4show( uchar i )
{
	switch( i )
	{
		case 0:
			ASEG = 0; BSEG = 1; CSEG = 1; DSEG = 1; break;
		case 1:
			ASEG = 1; BSEG = 0; CSEG = 1; DSEG = 1; break;
		case 2:
			ASEG = 1; BSEG = 1; CSEG = 0; DSEG = 1; break;
		case 3:
			ASEG = 1; BSEG = 1; CSEG = 1; DSEG = 0; break;
		default:
			ASEG = 1; BSEG = 1; CSEG = 1; DSEG = 1; break;
	}
	P0 = showdata[i];
//	Delay(10);
//		
}

void dataProcess()
{
	showdata[0] = smgduan[ outdata[0] / 10 ];
	showdata[1] = smgduan[ outdata[0] % 10 ];
	showdata[2] = smgduan[ outdata[2] / 10 ];
	showdata[3] = smgduan[ outdata[2] % 10 ];	
}

void timer0_init()
{
	AUXR &= 0x7f; //12T
	TMOD |= 0x02; //方式2 8位自动重装载
	TH0 = 0x48; //200us
	TL0 = 0x48;
	EA = 1; //开启总中断允许
	ET0 = 1; //开启定时器中断允许
	TF0 = 0; //消除TF0标志
	TR0 = 1; //开启定时
}

void main()
{
	Uart1Init();
	timer0_init();
//	Uart_send_str(outdata);
//	Uart_send_str("\n"2);
	Delay(5000); //延时1S
	
	while(1)
	{
		RH(outdata); //调用温湿度读取函数
		dataProcess(); //数据处理
		sprintf(out, "湿度:%d%%, 温度:%d℃\n", (int)(outdata[0]), (int)(outdata[2]));
//		Uart_send_str(out);//调用串口发送函数
		//读取模块数据周期不小于 2S
		Delay(50000);
		Delay(50000);
	}	
}

void timer0_Routine() interrupt 1
{
	static uchar i;
	seg4show( i / 5 );
	i ++;
	if( i % 10 == 0 ) 
	{
		P0 = 0x00;
	}
	i = i % 20;
	
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!