目录

一、DHT11单总线原理

二、代码详解

三、代码


代码见文章末尾

一、DHT11单总线原理

DHT11温湿度传感器只需要一根线即可和MCU进行数据交换,无数据传输时,单线应为高电平状态,具体流程、交互协议如下

一次传输40bit数据,16位湿度,16位温度,8位校验和

总线空闲状态为高电平,如果没有接受到主机发送的开始信号,DHT11不会进行数据采集。主机必须把总线拉低大于18ms时间,以保证DHT11能接收到起始信号。dht11接受到主机的开始信号后

,等待主机开始信号结束。DHT11接着发送80us的低电平响应信号。主机发完开始信号后,切换到输入模式,或输出高电平(输出模式可以输入),总线拉高,延时等待20-40us用以接受80us的dht11响应信号。

二、代码详解

主机拉低电平18ms

拉高等待dht11响应

每一位之前有50us的准备信号,1高电平70us,0高电平28us,首先延时30us确定0或1,虽然0位28us,多出2us即使全为0也不会影响数据为判断,下一位会用while来校正,读者可以自行计算这一段。

ReadDat<<=1;
        ReadDat|=temp;

8位左移一位,再按位与即可实现高位先接收。

校验和不对,即可进行丢弃。

三、代码

//dht11.c程序
#include "dht11.h"
#include "Delay.h"uint8_t dat[5]={0x00,0x00,0x00,0x00,0x00};
uint8_t sum=0;//初始化为输出void DHT11_GPIO_OUT(void)
{GPIO_InitTypeDef  GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);    //开启挂载GPIO的总线APB2GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出,输入也是有效GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);
}//初始化为输入void DHT11_GPIO_IN(void)
{GPIO_InitTypeDef  GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入,不可以输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);
}//读一个字节
uint8_t DHT_Read_Byte(void)
{uint8_t temp;uint8_t ReadDat=0;uint8_t retry = 0;    uint8_t i;//二进数除以十即为数据for(i=0;i<8;i++){//消耗准备信号低电平50uswhile(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14)==0&&retry<100){Delay_us(1); retry++;      }retry=0;//虽然0信号持续时间为28us,retry循环非常巧妙,//避免问题,相当于如果一直是0的话可以避免延时带来的多出时间Delay_us(30);//如果是0,那temp=0起作用,非0,仍然在高电平时间内//因为如果数据是0的话持续时间短,故先预置0,简化代码。temp=0;//数字信号0,temp=0//数字0信号高电平持续28us,数字1信号高电平70us,延时30us以确认数字0或1if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14)==1) {temp=1;}            //数字1信号高电平剩余40uswhile(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14)==1&&retry<100){     Delay_us(1);retry++;}retry=0;//<<=左移赋值符号,|=先或再赋值,得到1位数据,即8bitReadDat<<=1;ReadDat|=temp;}    return ReadDat;
}uint8_t DHT_Read(void)
{uint8_t i;uint8_t retry = 0;//stm32 PB14设置为输出,发送开始信号低电平18ms,高电平40usDHT11_GPIO_OUT();GPIO_ResetBits(GPIOB,GPIO_Pin_14);//拉低引脚输出电平Delay_ms(18);//保证dht11能收到起始信号GPIO_SetBits(GPIOB,GPIO_Pin_14);//拉高引脚输出电平Delay_us(40);//延时40us,等待dht11响应信号//stm32 PB14设置为输入,检查并接收响应信号低电平80us,高电平80usDHT11_GPIO_IN();//可以不切换,直接输出高电平,输入也是开启的Delay_us(20);//延时20us,dht11响应低电平80us,还剩60us,检查是否是低电平以确定是否有响应信号if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14)==0){   //第一个循环消耗响应低电平60uswhile(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14)==0&&retry<100)//接收响应信号低电平剩余60us{Delay_us(1);retry++;        }retry=0;//超过100us自动向下运行,以免卡死//消耗dht11拉高80uswhile(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14)==1&&retry<100)//接收响应信号高电平80us{Delay_us(1);retry++;            }retry=0;//接收8字节数据,每传送1bit之前先进行拉低50us//接收了5位数据,40bitfor(i=0;i<5;i++){dat[i]=DHT_Read_Byte();}Delay_us(50);//DHT11拉低总线50us作为一字节结束信号,或者使用以下语句//     while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14)==0&&retry<100)//消耗拉低总线的50us
//      {
//          SysTick_Delay_us(1);
//          retry++;
//      }
//      retry=0;}sum=dat[0]+dat[1]+dat[2]+dat[3];//校验和if(dat[4]==sum){return 1;}elsereturn 0;
}

【初篇】DHT11连接STM32、One wire单总线原理、GPIO代码详解相关推荐

  1. STM32开发实战:W25Q32JV SPI Flash详解

    STM32开发实战:W25Q32JV SPI Flash详解 在STM32单片机的应用中,使用SPI Flash能够有效地扩展程序和数据存储空间.W25Q32JV SPI Flash是一种常用的Fla ...

  2. 负载均衡原理与实践详解 第三篇 服务器负载均衡的基本概念-网络基础

    负载均衡原理与实践详解 第三篇 服务器负载均衡的基本概念-网络基础 系列文章: 负载均衡详解第一篇:负载均衡的需求 负载均衡详解第二篇:服务器负载均衡的基本概念-网络基础 负载均衡详解第三篇:服务器负 ...

  3. 来FAL学风控|风控策略分析师的日常是怎样的?(案例+代码详解篇)

    风控策略分析师的日常是怎样的?(案例+代码详解篇) FAL金科应用研究院 做了5年的金融,3年的数据分析工作,从17年6月才真正接触代码,算不到熟练,但在不断的学习和工作实践中目前是可以解决任何问题的 ...

  4. 负载均衡原理与实践详解 第五篇 负载均衡时数据包流程详解

    负载均衡原理与实践详解 第五篇 负载均衡时数据包流程详解 系列文章: 负载均衡详解第一篇:负载均衡的需求 负载均衡详解第二篇:服务器负载均衡的基本概念-网络基础 负载均衡详解第三篇:服务器负载均衡的基 ...

  5. STM32通过IIC读取MPU6050原始数据过程详解

    STM32通过IIC读取MPU6050数据过程详解 一:硬件介绍 此款MPU6050是通过IIC来与MCU通信的,它有两个IIC接口,第一个是主IIC,通过SCL和SDA两条线与MCU通信:第二个辅助 ...

  6. 《STM32从零开始学习历程》——CAN通讯代码详解

    <STM32从零开始学习历程>@EnzoReventon CAN通讯代码详解 相关链接: <STM32从零开始学习历程>--CAN通讯协议物理层 CAN-bus规范 V2.0版 ...

  7. 深度篇——目标检测史(七) 细说 YOLO-V3目标检测 之 代码详解

    返回主目录 返回 目标检测史 目录 上一章:深度篇--目标检测史(六) 细说 YOLO-V3目标检测 下一章:深度篇--目标检测史(八) 细说 CornerNet-Lite 目标检测 论文地址:< ...

  8. STM32固件库文件树及构成详解

    (想要pfd格式文件的可以留下邮箱) STM32固件库文件树及构成详解(库版本:STM32F10x_StdPeriph_Lib_V3.5.0) 库减压后所有文件夹构成如下: /

  9. 微信小程序系列(7)如何用微信小程序写一个论坛?贴心代码详解(五)删帖页【完结篇】

    源代码已开源,如果对你有帮助可以点个星:https://github.com/linkaimin/xdzs 写论坛不难,重点是各页面之间的信息传递! 先放成品图,虽然有点单调....但是麻雀虽小五脏俱 ...

最新文章

  1. 特斯拉纯视觉FSD版本Bug频发!马斯克:不认真测试的车主就取消资格
  2. [工具向]__androidstudio签名打包apk及配置自动签名
  3. 为什么我不建议你买保险?
  4. 在企业内部使用openssl创建私有CA
  5. oracle数据库中表被锁,Oracle数据库表被锁问题处理
  6. android r 编译找不到头文件_「投稿」iOS逆向——砸壳与反编译
  7. 资深架构师手把手教你性能优化
  8. 十八般武艺玩转GaussDB(DWS)性能调优:路径干预
  9. 释放链表内存C语言,最简单的链表删除第一个节点时释放内存的问题
  10. 【SQL练习题】排序
  11. vivoy27android版本,vivo Y27手机系统是什么?vivo Y27能升级安卓4.3吗?
  12. 【笔记】【机器学习基础】非负矩阵分解
  13. Matlab科研绘图颜色补充(特别篇)—51种中国传统颜色
  14. 宝付浅谈物流无人机发展历程
  15. 丹佛机场行李处理系统
  16. 2021SC@SDUSC山东大学软件学院软件工程应用与实践--YOLOV5代码分析(十)plots.py-2
  17. 1M = 1048576 字节 1G = 1073741824 字节 1T = 1099511627776 字节
  18. 3DMAX解析愤怒的小鸟
  19. Ribbon负载均衡及Feign消费者调用服务
  20. 人工智能安全政策与标准

热门文章

  1. 钉钉开发系列(十一)钉钉网页扫码登录
  2. 使用DQL命令查询数据(总篇1~3)
  3. 烧友必读《音响二十要》转台湾音响大师刘汉盛毕生精华
  4. Ext入门的第一个程序(1)
  5. 腾讯云 sdk调用 显示 图片解码失败 解决方案
  6. 2021年京东撸货还能做吗?轻松实现利益最大化,新手必看!
  7. IEEE754 详点
  8. Ghost高级教程——克隆备份
  9. ts数据包33位pts
  10. 视频和PPT已公开 | 第八届中国互联网测试大会·2021 MTSC 上海站