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;
}
来源:CSDN
作者:_Hello Spring
链接:https://blog.csdn.net/wct3344142/article/details/103804581