1、DHT11和DHT21传感器

这两种传感器都是奥松公司的产品,具体的传感器说明书在其官网上有(www.aosong.com)。

DHT11 数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数 字模块采集技术和温湿度传感技术,确保产品具有枀高的可靠性与卓越的长期稳定性。传感器包括一 个电容式感湿元件和一个 NTC 测温元件,并与一个高性能 8 位单片机相连接。

DHT21(AM2301)湿敏电容数字温湿度模块是一款含有己校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性与卓越的长期稳定性。传感器包括一个电容式感湿元件和一个高精度测温元件,并与一个高性能 8 位单片机相连接。因此该产品具有品质卓越、超快响应、抗干扰能力强、性价比极高等优点。每个传感器都在极为精确的湿度校验室中进行校准。校准系数以程序的形式储存在单片机中,传感器内部在检测信号的处理过程中要调用这些校准系数。标准单总线接口,使系统集成变得简易快捷。超小的体积、极低的功耗,信号传输距离可达 20 米以上,使其成为各类应用甚至最为苛刻的应用场合的最佳选择。产品为 3 引线(单总线接口)连接方便。特殊封装形式可根据用户需求而提供。

2、温湿度读取方式

两种传感器均采用简化的单总线通信。单总线即只有一根数据线,系统中的数据交换、控制均由单总线完 成。设备(主机或从机)通过一个漏极开路或三态端口连至该数据线,以允许设备在不发送数据时能够释 放总线,而让其它设备使用总线;单总线通常要求外接一个约 4.7kΩ的上拉电阻,这样,当总线闲置时, 其状态为高电平。由于它们是主从结构,只有主机呼叫从机时,从机才能应答,因此主机访问器件都必须 严格遵循单总线序列,如果出现序列混乱,器件将不响应主机。

3、两种传感器的主要区别

包括两点,分别是单总线起始信号的数据总线拉低时间和温湿度高低位数据含义。

DHT11的单总线格式定义:

DHT21的单总线格式定义:

4、微秒级延时函数

根据上面的介绍我们现在需要一个微秒级的精确延时函数,否则就不能成功的读取传感器数据。STM32单片机的滴答定时器可以满足。

(1)保证滴答定时器的时钟频率为72MHz

STM32F103内部8M的内部震荡,经过倍频后最高可以达到72M。在固件库3.0以上,只需要通过两步就可以完成对时钟频率的选择。

①修改system_stm32f10x.c开头的时钟宏定义,如下:

/* #define SYSCLK_FREQ_HSE    HSE_VALUE */
/* #define SYSCLK_FREQ_24MHz 24000000 */
/* #define SYSCLK_FREQ_36MHz 36000000 */
/* #define SYSCLK_FREQ_48MHz 48000000 */
/* #define SYSCLK_FREQ_56MHz 56000000 */
#define SYSCLK_FREQ_72MHz 72000000

②在主函数main中调用SystemInit()函数。

③如果没有成功,需要检查单片机的晶振是否起振。简单的检测方法:

有示波器的可以查看晶振的输出波形,正常应为正弦波。没有示波器的可以利用万用表分别测量晶振的管脚电平,正常应在1/2*VCC左右。

(2)程序编写

①在main()函数中添加:SysTick_Config(72000000 / 1000000);//除以1000000微秒级(100000十微秒级,1000毫秒级),指进入中断的间隔时间

int main(void)
{
SystemInit();
SysTick_Config( / );
}

②Delay.c

#include "stm32f10x.h"
#include "Delay.h" int TimingDelay=; void delay_us(u32 n)
{
TimingDelay=n;
while(TimingDelay!=);
}
void delay_ms(u32 n)
{
while(n--)
{
delay_us();
}
}

Delay.h

#ifndef _DELAY__H_
#define _DELAY__H_ void delay_us(u32 n);
void delay_ms(u32 n); #endif

③stm32f10x_it.c

extern int TimingDelay;
void SysTick_Handler(void)
{
if(TimingDelay!=)
{
TimingDelay--;
}
}

5、编写读传感器数据程序

①DHxx.c

#include "stm32f10x.h"
#include "DHxx.h"
#include "Delay.h"
#include "sys.h"
u8 tdata[]={0x00,0x00,0x00,0x00};
u8 sbuf,check; //***************************************************************************/
// //uchar i;
// uchar U8FLAG,k;
// uchar U8count,U8temp;
// uchar U8T_data_H,U8T_data_L,U8RH_data_H,U8RH_data_L,U8checkdata;
// uchar U8T_data_H_temp,U8T_data_L_temp,U8RH_data_H_temp,U8RH_data_L_temp,U8checkdata_temp;
// uchar U8comdata;
// uint ReceiveHighByte;
// uint ReceiveLowByte;
//***************Global defination for DHT11 end****//
void DHT_PortIN(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOB,&GPIO_InitStructure);
}
void DHT_PortOUT(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOB,&GPIO_InitStructure);
}
unsigned char StartDHT11(void)
{
DHT_PortOUT();
DHT_Out = ;
delay_ms(); //DHT11>18ms DHT_Out = ;
DHT_PortIN();
delay_us(); if(!DHT_In)
{
while(!DHT_In);
while(DHT_In);
return ;
}
return ;
} unsigned char StartDHT21(void)
{
DHT_PortOUT();
DHT_Out = ;
delay_ms(); //DHT21>800us DHT_Out = ;
DHT_PortIN();
delay_us(); if(!DHT_In)
{
while(!DHT_In);
while(DHT_In);
return ;
}
return ;
}
void com(void)
{
u8 i,tt;
tt = ;
for(i = ;i<;i++)
{
sbuf <<= ;
delay_us();
while(!DHT_In);
delay_us();
tt = ;
while(tt++);
if(DHT_In)
{
sbuf |= 0x01;
delay_us();
}
else
{
sbuf &= 0xfe;
}
}
}
u8 ReadDHT11(void)
{
u8 sum;
if(StartDHT11())
{
com();
tdata[]=sbuf;
com();
tdata[]=sbuf;
com();
tdata[]=sbuf;
com();
tdata[]=sbuf;
com();
check = sbuf;
sum = (tdata[]+tdata[]+tdata[]+tdata[]);
}
if(check == sum)
return();
else
return ;
} u8 ReadDHT21(void)
{
u8 sum;
if(StartDHT21())
{
com();
tdata[]=sbuf;
com();
tdata[]=sbuf;
com();
tdata[]=sbuf;
com();
tdata[]=sbuf;
com();
check = sbuf;
sum = (tdata[]+tdata[]+tdata[]+tdata[]);
}
if(check == sum)
return();
else
return ;
}

DHxx.h                     //(注意:我这边定义的DATA管脚为PB1)

#ifndef _DHXX__H_
#define _DHXX__H
#include "sys.h"
#define DHT_Out PBout(1)
#define DHT_In PBin(1) #define uchar unsigned char
#define uint unsigned int unsigned char StartDHT11(void);
unsigned char StartDHT21(void);
void DHT_PortIN(void);
void DHT_PortOUT(void);
u8 ReadDHT11(void);
u8 ReadDHT21(void);
void com(void);
//********************************** //********************************** extern u8 tdata[];
extern u8 sbuf;
extern u8 check; #endif

②sys.h

#include "stm32f10x.h"

///////////////////////////////////////////////////////////////
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
#define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum))
//IO地址映射
#define GPIOA_ODR_Addr (GPIOA_BASE+12) //0x4001080C
#define GPIOB_ODR_Addr (GPIOB_BASE+12) //0x40010C0C
#define GPIOC_ODR_Addr (GPIOC_BASE+12) //0x4001100C
#define GPIOD_ODR_Addr (GPIOD_BASE+12) //0x4001140C
#define GPIOE_ODR_Addr (GPIOE_BASE+12) //0x4001180C
#define GPIOF_ODR_Addr (GPIOF_BASE+12) //0x40011A0C
#define GPIOG_ODR_Addr (GPIOG_BASE+12) //0x40011E0C #define GPIOA_IDR_Addr (GPIOA_BASE+8) //0x40010808
#define GPIOB_IDR_Addr (GPIOB_BASE+8) //0x40010C08
#define GPIOC_IDR_Addr (GPIOC_BASE+8) //0x40011008
#define GPIOD_IDR_Addr (GPIOD_BASE+8) //0x40011408
#define GPIOE_IDR_Addr (GPIOE_BASE+8) //0x40011808
#define GPIOF_IDR_Addr (GPIOF_BASE+8) //0x40011A08
#define GPIOG_IDR_Addr (GPIOG_BASE+8) //0x40011E08 //IO口操作,只针对单一的IO口//n的值小于16
#define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) //输出
#define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) //输入 #define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n)
#define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) #define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n)
#define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n) #define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n)
#define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n) #define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n)
#define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n) #define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n)
#define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n) #define PGout(n) BIT_ADDR(GPIOG_ODR_Addr,n)
#define PGin(n) BIT_ADDR(GPIOG_IDR_Addr,n)
/////////////////////////////////////////////////////////////////

③main.c

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include <stdio.h>
#include "system.h"
#include "sys.h"
#include "DHxx.h"
#include "Delay.h"
int main(void)
{
SystemInit();
SysTick_Config( / );
while()
{
ReadDHT11();// ReadDHT21();//读取的信息在DHxx.c的tdata[]数组中
delay_ms();
delay_ms(); //注意读取间隔应该在2秒以上
}
}

6、参考

【1】单片机stm32时钟频率 http://www.elecfans.com/dianzichangshi/20171113578546.html

【2】https://wenku.baidu.com/view/6306fbf484254b35eefd3428.html

【3】http://www.aosong.com/products-28.html

人不曾老去,直至悔恨取代了梦想!---约翰.巴里摩

转载需说明出处,笔者总结之前的知识,与大家分享,有问题的可以留给我哦~

 

STM32读取温湿度传感器DHT11和DHT21(AM2301)系列问题的更多相关文章

  1. [转载] 树莓派读取温湿度传感器DHT11

    原文地址: http://blog.csdn.net/liang890319/article/details/8739683 硬件: 树莓派 2.0 DHT模块  接树莓派5V GND GPIO1 功 ...

  2. 进阶之路(中级篇) - 016 温湿度传感器DHT11

    如果想使用 Arduino 开发板驱动 DHT11 来获取温湿度的时候建议使用第三方的库,这样可以加快程序的开发速度,而且不容易出错,下面的代码我已经安转了第三方的库了.详细的安装方法请参考极客先锋的 ...

  3. 温湿度传感器DHT11程序示例

    DHT11概述 HT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器. 它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性与卓越的长期稳定性.传感器包括一个电阻式 ...

  4. 使用Arduino Wire Library读取温湿度传感器AM2321

    AM2321是采用I2C总线或单总线通讯的国产温湿度传感器.在AM2321手册中,当采用I2C通讯时,手册指定了多处需要主机等待的时间间隔,包括: (1)唤醒传感器时,从机不回复ACK,但主机主要等待 ...

  5. 在树莓派上读取DHT11温湿度传感器-python代码实现及常见问题(全面简单易懂)

    最近由于自己的课题需要,想要用在树莓派上使用DHT11温湿度传感器来读取空气中温湿度,遇到了几个问题,解决之后也对之前的知识进行了回顾,总结,特整理如下,希望能给也在学习树莓派的小伙伴们带来一些帮助. ...

  6. 基于CC2530/CC2430 的温湿度采集系统--DHT11

    采用常用的温湿度传感器DHT11 参见论坛中实例视频讲解http://bphero.com.cn/forum.php?mod=viewthread&tid=15&extra=page% ...

  7. Arduino I2C + 温湿度传感器AM2321

    (2015.5.17:本日志的内容有所更新,参见<使用Arduino Wire Library读取温湿度传感器AM2321>.) AM2321是广州奥松电子生产的数字式温湿度传感器.虽是国 ...

  8. STM32驱动DHT11温湿度传感器

    DHT11 是一款湿温度一体化的数字传感器.该传感器包括一个电阻式测湿元件和一个 NTC 测温元件,并与一个高性能 8 位单片机相连接.通过单片机等微处理器简单的电路连接就能够 实时的采集本地湿度和温 ...

  9. STC15系列通用-STC15F2K60S2/STCW4K32S4读取DHT11温湿度传感器数据串口输出代码实例工程免费下载

    //为了方便大家调试,另附程序工程共大家下载,下载地址:https://www.90pan.com/b1908750 ​ //************************** //程序说明:stc ...

随机推荐

  1. PHPStorm 最新版 去掉参数提示 parameter name hints

    最新的phpstorm有个默认开启的参数名和类型提示功能, 这对于开发有很大的帮助,但是对于有些同学来说,刚开始可鞥不是很习惯,所以就需要把他给关闭. 在 配置面板中搜索 parameter name ...

  2. sql语句转为Model

    在跟数据库打交道的时候,有一个常用的应用,就是把数据库中的表转为程序中的对象,也就是说表中的列转为对象的属性.对于字段比较少的,我们可以直接复制过去改,但是字段数比较多的时候,借助工具类实现比较方便而 ...

  3. Linux系统默认权限之umask

    默认情况下,目录权限值为755, 普通文件权限值为644, 那么这个值是由谁规定的,追究其原因是 umask [root@adminx]# vim /etc/profile 1.假设umask值为:0 ...

  4. Java Swing应用程序 JComboBox下拉框联动查询

    在web项目中,通过下拉框.JQuery和ajax可以实现下拉框联动查询. 譬如说,当你查询某个地方时,页面上有:省份:<下拉框省份> 市区:<下拉框市区> 县乡:<下拉 ...

  5. BIOS相关

    BIOS设置中恢复默认设置的选项是Load Optimized Defaults, 但是有的电脑是restore,我的就是 有的电脑进入bios需要按住Fn+F2一些操作也需要按Fn,比如说保存并退出 ...

  6. 浅析C#之委托、Action、Func

    一.委托 1.1 委托的定义 delegate(委托)是一种可用于封装命名方法或匿名方法的引用类型, 委托类似于 C++ 中的函数指针: .Net通过委托来提供回调函数机制. 声明一个委托类型 int ...

  7. js 显示数字不断增加

    一个小小的函数,很容易看懂,就不过多解释了,只为下次用时直接用就ok了... function countUp(count) { var div_by = 100, speed = Math.roun ...

  8. 教你怎么样在大陆直接使用google搜索

    一.环境准备 我们需要一个nginx的模块来进行设置,ngx_http_google_filter_module.前提我们是有一个海外的VPS,并且可以访问谷歌,我的VPS是亿速云香港的. 首先先感受 ...

  9. Matlab绘图基础——散点生成三角网(TIN)

    %例一:二维三角网TIN模型的生成 X=rand(10,2)*5; dt=DelaunayTri(X(:,1),X(:,2));       %生成三角网 triplot(dt);hold on;   ...

  10. Java基础学习笔记八 Java基础语法之接口和多态

    接口 接口概念 接口是功能的集合,同样可看做是一种数据类型,是比抽象类更为抽象的”类”.接口只描述所应该具备的方法,并没有具体实现,具体的实现由接口的实现类(相当于接口的子类)来完成.这样将功能的定义 ...