STC12C5A60S2驱动DHT11温湿度模块传感器

快速导航
STC12已封装好的函数库

DTH11器件说明书:
https://note.youdao.com/s/A3ez5ubT

/*
 *程序名:DHT11驱动程序
 *硬件支持:STC12C5A60S2 DH11
 *接口说明:DHT11:Vcc GND DATA
 *晶振说明:11.0592MHZ
 *作者:小途
 */


#include <STC12C5A60S2.H>

#define uchar unsigned char
#define uint unsigned int

#define JUDGE  30                //用于判断通信的0和1,与单片机速度和晶振频率有关

sbit DATA = P2^0;                //定义数据引脚

uchar dat_r[5];                  //用于存放从DHT11读取到的数值

/*********************************************************************************************
函数名称:Delay30us();/Delay20ms();/Delay1s();
函数功能:延时函数
参  数:无
返回值:无
结  果:延时相应时间
备  注:振荡晶体为11.0592MHz(所有延时函数Copy自STC-ISP(v6.85).exe)
**********************************************************************************************/
void Delay30us()		//@11.0592MHz
{
	unsigned char i;

	i = 80;
	while (--i);
}

void Delay20ms()                //@11.0592MHz
{
        unsigned char i, j, k;

        i = 1;
        j = 216;
        k = 35;
        do
        {
                do
                {
                        while (--k);
                } while (--j);
        } while (--i);
}

void Delay1s()		//@11.0592MHz
{
	unsigned char i, j, k;

	i = 43;
	j = 6;
	k = 203;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

//==============================================================================================


//串口初始化,晶振11.0592,波特率9600
void UartInit(void)		//9600bps@11.0592MHz
{
	PCON &= 0x7F;		//波特率不倍速
	SCON = 0x50;		//8位数据,可变波特率
	AUXR |= 0x04;		//独立波特率发生器时钟为Fosc,即1T
	BRT = 0xDC;		//设定独立波特率发生器重装值
	AUXR |= 0x01;		//串口1选择独立波特率发生器为波特率发生器
	AUXR |= 0x10;		//启动独立波特率发生器
	
	EA = 1;//开总中断
	ES = 1;//开串口中断
}

//向串口发送一段字符串
void prints(char *s)
{
	while(*s != '\0')//发送字符串,直到遇到0才结束
	{
		SBUF = *s++;
		while(!TI);
		TI = 0;
	}
}

//向串口发送一个字符
void putchar(char ch)
{
	SBUF = ch;
	while(!TI);TI = 0;
}



/********************************************************
 * 函数名称:GetData(void)
 * 函数功能:DHT11读数据函数
 * 输入:无
 * 返回:失败->-1,-2,-3,-4;成功->0
 * 结果:读DHT11数据并保存到数组dat_r[]
 * 
 ********************************************************/
char GetData (void)
{
        uchar i,j;                                //for循环变量
        uchar t;                                //超时判断
        uchar dat8=0;                        //一次读取的8位数据,需要读5次

        DATA = 0;                                //主机发起始信号
        Delay20ms();                        //主机拉低总线至少18ms
        DATA = 1;                                //主机拉高总线20~40us
        Delay30us();

        t = 80;                                        //设置超时等待时间
        while(DATA && t--);                //等待DHT11拉低总线
        if(t == 0)                                //超时
        {
                DATA = 1;
                return -1;                        //通信错误退出,返回错误信号:-1
        }

        //等80us响应信号
        t = 250;                                //设置超时等待时间
        while(!DATA && t--);        //等待DHT11拉高总线
        if(t == 0)                                //超时
        {
                DATA = 1;
                return -2;                        //通信错误退出,返回错误信号:-2
        }

        //等80us响应信号
        t = 250;                                //设置超时等待时间
        while(DATA && t--);                //等待DHT11拉低总线
        if(t == 0)                                //超时
        {
                DATA = 1;
                return -3;                        //通信错误退出,返回错误信号:-3
        }

        for(j=0; j<5; j++)                //5次读取
        {
                for(i=0; i<8; i++)                        //1次8个位
                {
                        //等待50us开始时隙
                        t = 150;                                //设置超时等待时间
                        while(!DATA && t--);        //等待DHT11拉高总线
                        if(t == 0)                                //超时
                        {
                                DATA = 1;
                                return -4;                        //通信错误退出,返回错误信号:-4
                        }
                        t = 0;                                        //记录时间清零
                        while(DATA && ++t);                //等待并记录高电平持续时间
                        dat8 <<= 1;
                        if(t > JUDGE)                        //高电平持续时间较长(70us)
                                dat8 += 1;                        //传输值为1
                        //else dat8 += 0;
                }
                dat_r[j] = dat8;
        }

        Delay30us();                //等待DHT11拉低50us
        Delay30us();
        DATA = 1;                        //结束,拉高总线
        return 0;                        //返回成功信号
}

/*********************************************************************************************
函数名:数据校验函数
调  用:? = Check();
参  数:无
返回值:成功->0;失败->-1;
结  果:数据校验
备  注:数据传送正确时校验和数据等于“8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据”所得结果的末8位。
**********************************************************************************************/
char Check(void)
{
        uchar i;                        //for循环变量
        uint chk=0;                        //校验和
        for(i=0; i<4; i++)
                chk += dat_r[i];                //累加
        if((uchar)chk != dat_r[4])        //比对
                return -1;                                //返回错误信号:-1
        else
                return 0;                                //返回正确信号:0
}

/********************************************************
 * 函数名称:SendOutData()
 * 函数功能:向串口发送DH11温湿度数据原始数据
 * 输入:无
 * 返回:无
 * 注意事项:需要初始化串口、函数运行过程要核验数据函数
 * 数据格式:8bit温度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数据+8bit校验和
 * 
 ********************************************************/
void SendOutData()
{
    char i;
    i = GetData();        //读数据
    if(i != 0)            //有错误
    {
            //UART_T(-i);        //返回错误值
            return;              //重新开始
    }
    i = Check();        	  //数据校验
    if(i != 0)                //有错误
    {
            //UART_T(-i);        	//返回错误值
            return;                 //重新开始
    }

    putchar(dat_r[0]);                //湿度整数
    putchar(dat_r[1]);                //湿度小数(根据数据手册,DHT11小数部分一直是0没用)
    putchar(dat_r[2]);                //温度整数
    putchar(dat_r[3]);                //温度小数(根据数据手册,DHT11小数部分一直是0没用)
    putchar(dat_r[4]);                //校验值
    Delay1s();                        //经测试,两次连读要至少延时80ms        
}

/*****************************************
 *函数名称:SendOutDH11Str()
 *函数功能:向串口发送温湿度数据
 *输入:无
 *返回:无
 *****************************************/
void SendOutDH11Str()
{
	char i;
	uchar HD11_str[13];//发送的数据
	uchar RH,RL,TH,TL,revise; 
    i = GetData();        //读数据
    if(i != 0)            //有错误
    {
            //UART_T(-i);        //返回错误值
            return;              //重新开始
    }
    i = Check();        	  //数据校验
    if(i != 0)                //有错误
    {
            //UART_T(-i);        	//返回错误值
            return;                 //重新开始
    }
	
	RH = dat_r[0];//湿度整数
	RL = dat_r[1];//湿度小数(根据数据手册,DHT11小数部分一直是0没用)
	TH = dat_r[2];//温度整数
	TL = dat_r[3];//温度小数(根据数据手册,DHT11小数部分一直是0没用)
	revise = dat_r[4];//校验值
	
	
	//数据处理
	HD11_str[0]=RH/10+'0';
	HD11_str[1]=(RH%10)+'0';
	HD11_str[2]='%';
	HD11_str[3]='R';
	HD11_str[4]='H';
	HD11_str[5]=' ';
	HD11_str[6]=' ';
	HD11_str[7]=(TH/10)+'0';
	HD11_str[8]=(TH%10)+'0';
	HD11_str[9]='^';
	HD11_str[10]='C';
	
	
	prints(HD11_str);
	Delay1s();                        //经测试,两次连读要至少延时80ms     
}


void main()
{
    UartInit();                //串口初始化
    Delay1s();                 //等待DHT11稳定
    while (1)
    {
		/*
		备注:Demo程序只能选择一种发送方式,编译警告提示有未调用段,属于正常现象可忽略
		*/
		
		
		
		/*向串口发送一段原始数据*/
//        SendOutData();
		
		
		
		/*向串口已字符串形式发送数据*/
		SendOutDH11Str();
		
    }
}

运行结果
请添加图片描述

  • 3
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值