历史上的今天
返回首页

历史上的今天

今天是:2025年01月08日(星期三)

正在发生

2020年01月08日 | DHT11驱动程序

2020-01-08 来源:51hei

前几天在某宝上看到DHT11,感觉蓝色的外壳做的很漂亮,然后就买了1个。结果发现网上的程序都是给旧12T单片机用的,注释也没几句,用着很不顺手。所以就自己按照数据手册编了驱动程序。还是自己的程序用着顺手~~~~拿来和大家分享~~~~


/*********************************************************************************************

程序名:    DHT11驱动程序

编写人:    王朗的诱惑

编写时间:  2015年8月4日

硬件支持:  STC12C5A60S2  DHT11

接口说明:  DHT11:VCC GND DATA 

*********************************************************************************************

说明:1、单片机是STC12C5A60S2,晶振频率12MHz,实验成功。换用12T单片机或别的晶振的时候要修改

          延时函数和JUDGE。程序里判断超时的变量t的阀值也要改。

          2、好东西要共享,大家随意折腾~~

*********************************************************************************************/

#include


typedef unsigned char        uchar;

typedef unsigned int        uint;


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


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


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


/*********************************************************************************************

函数名:延时函数

调  用:Delay30us();/Delay20ms();/Delay1s();

参  数:无

返回值:无 

结  果:延时相应时间

备  注:振荡晶体为12MHz(所有延时函数Copy自STC-ISP(v6.85).exe)

**********************************************************************************************/

void Delay30us()                //@12.000MHz

{

        unsigned char i;


        i = 87;

        while (--i);

}



void Delay20ms()                //@12.000MHz

{

        unsigned char i, j, k;


        i = 1;

        j = 234;

        k = 113;

        do

        {

                do

                {

                        while (--k);

                } while (--j);

        } while (--i);

}


void Delay1s()                //@12.000MHz

{

        unsigned char i, j, k;


        i = 46;

        j = 153;

        k = 245;

        do

        {

                do

                {

                        while (--k);

                } while (--j);

        } while (--i);

}


/*********************************************************************************************

函数名:UART串口初始化函数

调  用:UART_Init();

参  数:无

返回值:无

结  果:启动UART串口接收中断,允许串口接收,启动T/C1产生波特率(占用)

备  注:振荡晶体为12MHz,PC串口端设置 [ 4800,8,无,1,无 ]

**********************************************************************************************/

void UART_Init (void){

        EA = 1; //允许总中断(如不使用中断,可用//屏蔽)

        ES = 1; //允许UART串口的中断


        TMOD = 0x20;        //定时器T/C1工作方式2

        SCON = 0x50;        //串口工作方式1,允许串口接收(SCON = 0x40 时禁止串口接收)

        TH1 = 0xF3;        //定时器初值高8位设置

        TL1 = 0xF3;        //定时器初值低8位设置

        PCON = 0x80;        //波特率倍频(屏蔽本句波特率为2400)

        TR1 = 1;        //定时器启动    

}


/*********************************************************************************************

函数名:UART串口发送函数

调  用:UART_T (?);

参  数:需要UART串口发送的数据(8位/1字节)

返回值:无 

结  果:将参数中的数据发送给UART串口,确认发送完成后退出

备  注:

**********************************************************************************************/

void UART_T (uchar UART_data){ //定义串口发送数据变量

        SBUF = UART_data;        //将接收的数据发送回去

        while(TI == 0);                //检查发送中断标志位

        TI = 0;                        //令发送中断标志位为0(软件清零)

}


/*********************************************************************************************

函数名:DHT11读数据函数

调  用:? = GetData();

参  数:无

返回值:失败->-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);                //等待并记录高电平持续时间

推荐阅读

史海拾趣

问答坊 | AI 解惑

新能源新趋势

新能源几乎成了“绿色”动力的代言。去年底发布的《新能源汽车生产准入管理规则》对新能源汽车有准确的定义,指采用非常规的车用燃料作为动力来源(或使用常规的车用燃料、采用新型车载动力装置),综合车辆的动力控制和驱动方面的先进技术,形成的 ...…

查看全部问答>

关于监控用的摄像头用的LED是什么样的?

遥控器用的红外LED,因为红外LED发出的光不完全是红外光,也包含部分的可见光(红色)成分,所以肉眼能看到少许光。遥控器使用的LED,一般发射角度是30度左右,用户即使没有完全对准目标,也能有效操作。在没有外界红外线干扰的时候,遥控距离可以 ...…

查看全部问答>

wince5.0怎么设置才能实现通过路由上网

最近我刚买一块2440的开发板,跑wince5.0,按照PC机设置wince,连上网线后不能上网!不知道是什么原因。PC机可以通过网线与ARM板通信。ftp和fttp都正常。那我应该怎么样设置或还需要哪些工作才能实现我这块开发板与网络的连接呢。…

查看全部问答>

wince安全性问题

在wince 6.0中我有一个客户端程序,先后两次调用InitializeSecurityContext用于和google服务器端进行安全认证,第一次调用返回的是SEC_I_CONTINUE_NEEDED,第二次返回的是SEC_E_WRONG_PRINCIPAL,请问怎么解决啊?是不是和证书有关系?相同程序在wi ...…

查看全部问答>

各位好心人帮忙解决一个usb驱动问题

小弟现在正在做一个Linux下usb鼠标驱动的程序,但编写程序时总是提示找不到linux/usb.h,望大家帮忙指点,岂求ING………

查看全部问答>

【招聘】汇编语言入门图书兼职作者

【招聘】汇编语言入门图书兼职作者 本公司是业内知名IT图书策划出版公司,正在运作一本汇编语言入门相关图书。想征求关于汇编语言的设计高手参与编写。有意者请将个人介绍和联系方式(QQ或MSN)发到本人邮箱macuilhy@sina.cn。…

查看全部问答>

讲了那么多技术,有没有导购的?

                                 要1K STM32f103c8T6,找谁?…

查看全部问答>

u8 sd_raw_get_info(struct sd_raw_info* info)中struct怎么理解

u8 sd_raw_get_info(struct sd_raw_info* info) { …… } 这个子程序怎么用啊,像u8 mmcWrite(u32 sector, u8* buffer)这种,我在主程序中只要定义unsigned char SD_Write1[]={\"0123456789\"}; 就可以用了mmcWrite(SD_Write1); 但是这个定义 ...…

查看全部问答>

TI 电源设计小贴士 9

欢迎来到电源设计小贴士!随着现在对更高效、更低成本电源解决方案需求的强调,我们创建了该专栏,就各种电源管理课题提出一些对您有帮助的小技巧。该专栏面向各级设计工程师。无论您是从事电源业务多年还是刚刚步入电源领域,您都可以在这里找到一 ...…

查看全部问答>