历史上的今天
返回首页

历史上的今天

今天是:2026年03月23日(星期一)

正在发生

2023年03月23日 | STM32CubeMX系列 | DHT11温湿度传感器

2023-03-23 来源:zhihu

1. DHT11简介

DHT11是一款温湿度一体化的数字传感器,该传感器包括一个电阻式测湿元件和一个NTC测温元件,并与一个高性能8位单片机连接。通过单片机微处理器简单的电路连接就能够实时的采集湿度和温度。DHT11与STM32之间能采用简单的单总线进行通讯,仅需一个IO口。传感器内部温度和湿度数据40个bit的数据一次性传给单片机,数据采用校验和方式进行校验,有效的保证数据传输的准确性。 DHT11采用单总线数据格式,即单个数据引脚端口完成输入输出双向传输。其数据包由5个字节(40Bit)组成。数据分小数和整数部分,一次完整的数据传输为40bit,高位先出。数据格式如下图示

根据以上数据,即可算出温度和湿度的值,计算方法如下:

湿度 = byte4.byte3 温度 = byte2.byte1 校验 = byte4 + byte3 + byte2 + byte1

DHT11和单片机的一次通讯最大为3ms左右,建议主机连续读取时间间隔不要小于100ms,下面是DHT11的三种时序:

  • 数据发送时序:首先主机发送开始信号,即拉低数据线保持t1(至少18ms)时间,接着拉高数据线t2(20 ~ 40us)时间;然后读取DHT11的响应,正常的话DHT11会拉低数据线并保持t3(40 ~ 50us)时间作为响应信号,接着DHT11拉高数据线并保持t4(40 ~ 50us)时间后,开始传输数据

  • DHT11输出0时序

  • DHT11输出1时序

2. 硬件设计

D1指示灯用来提示系统运行状态,PG11连接DHT11温湿度传感器用来检测环境温湿度,串口1用来打印温度值

  • D1指示灯

  • PG11

  • USART1

  • TIM7(提供us延时)

3. 软件设计

3.1 STM32CubeMX设置

  • RCC设置外接HSE,时钟设置为72M

  • PC0设置为GPIO推挽输出模式、上拉、高速、默认输出电平为高电平

  • USART1选择为异步通讯方式,波特率设置为115200Bits/s,传输数据长度为8Bit,无奇偶校验,1位停止位

  • PG11设置为GPIO推挽输出模式、上拉、高速

  • 激活TIM7,预分频因子设为72-1,向上计数,自动重载值为65535;因此计数器CNT_CLK = 1MHz,计数器周期为1us

  • 输入工程名,选择工程路径(不要有中文),选择MDK-ARM V5;勾选Generated periphera initialization as a pair of ‘.c/.h’ files per IP ;点击GENERATE CODE,生成工程代码

3.2 MDK-ARM编程

  • 在tim.c文件下实现微秒延时(us)函数

void delay_us(uint16_t us){

    uint16_t differ = 0xffff-us-5;              

    __HAL_TIM_SET_COUNTER(&htim7,differ);   //设定TIM7计数器起始值

    HAL_TIM_Base_Start(&htim7);     //启动定时器 


    while(differ < 0xffff-5){   //判断

        differ = __HAL_TIM_GET_COUNTER(&htim7);     //查询计数器的计数值

    }

    HAL_TIM_Base_Stop(&htim7);

}

创建按键驱动文件DHT11.c 和相关头文件DHT11.h

void DHT11_IO_IN(void){     //IO口方向设置为输入

    GPIO_InitTypeDef GPIO_InitStructure;

    GPIO_InitStructure.Pin = GPIO_PIN_11;

    GPIO_InitStructure.Mode = GPIO_MODE_INPUT;

    HAL_GPIO_Init(GPIOG,&GPIO_InitStructure);

}


void DHT11_IO_OUT(void){    //IO口方向设置为输出

    GPIO_InitTypeDef GPIO_InitStructure;

    GPIO_InitStructure.Pin = GPIO_PIN_11;

    GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;

    GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;

    HAL_GPIO_Init(GPIOG,&GPIO_InitStructure);

}


void DHT11_Rst(void){                 

    DHT11_IO_OUT();     //设置为输出

    DHT11_DQ_OUT_LOW;   //拉低

    HAL_Delay(20);      //至少18ms

    DHT11_DQ_OUT_HIGH;  //拉高 

    delay_us(30);       //至少20~40us

}


uint8_t DHT11_Check(void){   

    uint8_t retry=0;

    DHT11_IO_IN();      

    while (DHT11_DQ_IN&&retry<100){ //拉低40~80us

        retry++;

        delay_us(1);

    };   

    if(retry>=100)return 1;

    else retry=0;

    while (!DHT11_DQ_IN&&retry<100){ //拉高40~80us

        retry++;

        delay_us(1);

    };

    if(retry>=100)return 1;     

    return 0;   //检测到DHT11返回0

}


uint8_t DHT11_Read_Bit(void){

    uint8_t retry=0;

    while(DHT11_DQ_IN&&retry<100){  //等待变为低电平

        retry++;

        delay_us(1);

    }

    retry=0;

    while(!DHT11_DQ_IN&&retry<100){ //等待变为高电平

        retry++;

        delay_us(1);

    }

    delay_us(40);   //等待40us

    if(DHT11_DQ_IN)return 1;

    else return 0;         

}


uint8_t DHT11_Read_Byte(void){        

    uint8_t i,dat;

    dat=0;

    for (i=0;i<8;i++){

        dat<<=1; 

        dat|=DHT11_Read_Bit();

    }                           

    return dat;

}


uint8_t DHT11_Read_Data(uint16_t *temp,uint16_t *humi){        

    uint8_t buf[5];

    uint8_t i;

    DHT11_Rst();

    if(DHT11_Check()==0){

        for(i=0;i<5;i++){

            buf[i]=DHT11_Read_Byte();

        }

        if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4]){

            *humi=(buf[0]<<8) + buf[1];

            *temp=(buf[2]<<8) + buf[3];

        }

    }else return 1;

    return 0;       

}


uint8_t DHT11_Init(void){

    GPIO_InitTypeDef GPIO_Initure;  //PG11的初始化已经在cubemx中完成,可以忽略此段初始化代码

    __HAL_RCC_GPIOG_CLK_ENABLE();           

    GPIO_Initure.Pin=GPIO_PIN_11;           

    GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;  

    GPIO_Initure.Pull=GPIO_PULLUP;         

    GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH;

    HAL_GPIO_Init(GPIOG,&GPIO_Initure);    

    DHT11_Rst();

    return DHT11_Check();

}

在main.c文件下编写DHT11测试代码

int main(void){

  /* USER CODE BEGIN 1 */

  uint16_t temperature;

  uint16_t humidity;

  /* USER CODE END 1 */

  HAL_Init();

  SystemClock_Config();

  MX_GPIO_Init();

  MX_TIM7_Init();

  MX_USART1_UART_Init();

  /* USER CODE BEGIN 2 */

  while(DHT11_Init()){

    printf("DHT11 Checked failed!!!rn");

    HAL_Delay(500);

  }

  printf("DHT11 Checked Sucess!!!rn");

  /* USER CODE END 2 */

  while (1){

    DHT11_Read_Data(&temperature,&humidity);

    printf("DHT11 Temperature = %d.%d degreern",temperature>>8,temperature&0xff);

    printf("DHT11 Humidity = %d.%d%%rn",humidity>>8,humidity&0xff);       

    HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_0);

    HAL_Delay(500);

  }

}


4. 下载验证

编译无误下载到开发板后,可以看到D1指示灯不断闪烁,串口不断打印出当前温湿度值。串口输出如下信息:


DHT11 Checked Sucess!!! DHT11 Temperature = 28.20 degree DHT11 Humidity = 30.21%

推荐阅读

史海拾趣

GREATECS公司的发展小趣事

在电子行业中,有许多伟大的企业(GREATECS公司,这里假设为泛指多个杰出电子企业)通过不同的路径和策略实现了显著的发展。以下是五个相关故事,每个故事均基于事实,旨在展示这些企业如何成长和壮大。

1. 通用电气(General Electric, GE)的多元化扩张

通用电气(GE)的故事始于1888年,由托马斯·爱迪生创立,最初专注于电力和照明领域。随着时间的推移,GE通过一系列的战略并购和内部创新,逐渐扩展到电机、电动机制造、航空、医疗设备、核能等多个领域。在20世纪,GE成为全球最大的多元化企业之一,其业务遍布全球。特别是在杰克·韦尔奇担任CEO期间(1981-2001),通过大规模的并购和扩张,GE的营业收入和市值显著增长。然而,2008年金融危机后,GE面临经济困境,随后进行了战略调整,出售金融资产并重点发展核心业务,如今仍是全球领先的科技和工业公司之一。

2. 索尼(Sony)的创新之路

索尼公司成立于1946年,最初由井深大和盛田昭夫创立,起初是一家小型电子产品制造商。索尼的崛起得益于其持续的创新精神和对消费者需求的敏锐洞察。1958年,索尼推出了世界上第一台便携式晶体管收音机,开启了便携式电子产品的新时代。随后,索尼又推出了Walkman便携式音乐播放器、PlayStation游戏机等一系列革命性产品,这些产品不仅改变了人们的娱乐方式,也奠定了索尼在全球电子行业的领先地位。索尼的成功在于其不断追求技术创新和产品质量,以及对市场趋势的准确把握。

3. 三星电子的崛起

三星电子是韩国最大的电子企业,其发展历程充满了挑战与机遇。起初,三星主要从事贸易和低端电子产品制造。然而,在20世纪80年代末至90年代初,三星决定实施“新经营”战略,通过大规模投资研发、提升产品质量和品牌形象,实现了从低端制造商向高端科技企业的转型。在半导体、智能手机、显示面板等领域,三星取得了重大突破,成为全球市场的领导者。三星的成功在于其强大的研发能力、高效的供应链管理以及对市场变化的快速响应。

4. 英特尔(Intel)的芯片霸主地位

英特尔公司成立于1968年,最初是一家专注于半导体存储器的初创企业。然而,随着日本存储器制造商的崛起,英特尔面临了巨大的竞争压力。在关键时刻,英特尔决定放弃存储器业务,转而专注于微处理器(CPU)的研发和生产。这一战略转型使英特尔迅速崛起为全球最大的CPU制造商,其“Intel Inside”计划更是深入人心,成为个人电脑行业的标准配置。英特尔的成功在于其强大的技术创新能力、对市场需求的精准把握以及与全球合作伙伴的紧密合作。

5. 华为的技术突破与全球化战略

华为作为中国电子行业的代表企业,其发展历程充满了传奇色彩。起初,华为主要从事电信设备的研发和销售。然而,随着技术的不断进步和市场需求的不断变化,华为逐渐将业务扩展到智能手机、云计算、人工智能等多个领域。华为的成功在于其持续的技术研发投入、对全球市场的深入洞察以及灵活的市场策略。特别是在5G技术方面,华为取得了重大突破,成为全球领先的5G解决方案提供商。同时,华为还积极推动全球化战略,与全球多个国家和地区的运营商建立了紧密的合作关系。

Great American Electronics公司的发展小趣事

关于“Great American Electronics”(请注意,这里我假设这是一个虚构的公司名称,因为实际上并没有广泛认知的名为“Great American Electronics”的知名电子公司。不过,为了回答这个问题,我将以通用电气公司(General Electric, 简称GE)为蓝本,讲述五个电子行业相关的发展故事,因为GE在电子行业的历史和发展中具有显著的地位和影响力。)

1. 电气时代的开创者

故事背景:通用电气公司(GE)的起源可以追溯到美国发明家托马斯·阿尔瓦·爱迪生。1878年,爱迪生成立了爱迪生电灯公司,并在新泽西州的门洛帕克实验室发明了第一只商用白炽灯。1882年,爱迪生照明公司在纽约建造了美国第一个中央发电站,开启了电气时代。尽管爱迪生并未直接参与GE的成立,但他的贡献为GE的后续发展奠定了坚实的基础。

关键事件:爱迪生将电力商业化,使电力成为了一种可以广泛应用的能源形式。这一创举不仅改变了人们的生活方式,也为GE在电气行业的崛起提供了历史性的机遇。

2. 合并与转型的里程碑

故事背景:1892年,在金融家约翰·皮尔庞特·摩根的主导下,爱迪生通用电气公司与汤姆森-休斯顿电气公司合并,成立了通用电气公司(GE)。这一合并标志着GE从单一的电力业务向多元化发展的转型。

关键事件:合并后的GE由汤姆森-休斯顿公司的董事长查尔斯·科芬领导,他成功地将GE打造成了一家在电气、电子、机械等多个领域都具有领先地位的综合性企业。科芬的管理理念和组织结构设计为GE日后的长期发展奠定了坚实的基础。

3. 科研与创新的典范

故事背景:在查尔斯·科芬的领导下,GE建立了美国第一家研究实验室,并致力于推动科技创新和产品研发。这一举措使得GE在多个技术领域取得了重大突破。

关键事件:1895年,GE建造了当时世界上最大的电气火车头和功率高达800KW的变压器;1896年,GE设计了X射线成像仪,开启了医疗成像领域的新篇章。这些创新成果不仅展示了GE的技术实力,也为公司带来了丰厚的商业回报。

4. 战争与扩张的机遇

故事背景:两次世界大战为GE提供了巨大的发展机遇。在战争期间,GE凭借其强大的生产能力和技术实力,为军队提供了大量的电气设备和武器装备。

关键事件:第一次世界大战后,GE在新兴的电工技术部门——无线电方面居于统治地位;第二次世界大战则使GE的产量和利润额急剧增长。战争期间的扩张不仅增强了GE的市场地位,也为公司带来了丰富的技术积累和人才储备。

5. 全球化与多元化的战略

故事背景:进入20世纪后半叶,GE开始实施全球化和多元化战略,通过并购和合作等方式不断拓展业务范围和市场版图。

关键事件:在杰克·韦尔奇的领导下,GE从一家制造企业转变为以服务业和电子商务为导向的企业巨头。韦尔奇推行的“六西格玛”质量标准、全球化和电子商务战略几乎重新定义了现代企业。同时,GE还通过收购阿尔斯通、贝克休斯等知名企业进一步巩固了其在轨道交通、电力电网、油气等领域的领先地位。如今,GE已经成为全球最大的提供技术和服务业务的跨国公司之一,在电子行业中具有举足轻重的地位。

Handok Co Ltd公司的发展小趣事

在电子行业中,Hamlin(现为Littelfuse的一部分)的发展充满了创新与挑战的故事。以下是五个关于Hamlin如何在Littelfuse旗下发展壮大的实际案例:

1. 从独立到并购:Hamlin的加入

Hamlin,一家在传感器领域享有盛誉的公司,于2012年被Littelfuse收购。这一战略举措标志着Littelfuse在电路保护基础上,进一步向传感器与功率器件领域扩展。Hamlin的加入为Littelfuse带来了丰富的传感器技术,特别是其在磁性传感器方面的专长,使得Littelfuse能够为客户提供更全面的解决方案。这次并购不仅增强了Littelfuse在汽车电子和工业市场的竞争力,也为其后续的技术创新和市场拓展奠定了坚实基础。

2. 创新引领:55300系列传感器的诞生

Hamlin在加入Littelfuse后,继续发挥其创新优势,推出了55300系列非接触式磁性传感器。这一系列传感器克服了传统干簧开关在机械磨损和污染方面的限制,具有长寿命、高速度、不受恶劣环境影响的特点。其广泛的工作温度范围和集成的汽车级EMI/EMC测试,使得这些传感器在汽车和工业市场得到了广泛应用,如液压缸位置、变速箱换挡位置等关键控制领域。

3. 技术突破:Hamlin在车用传感器领域的贡献

随着汽车行业的快速发展,对安全、节能和舒适性的要求日益提高。Hamlin利用其在磁感应技术上的专长,为Littelfuse的车用传感器产品线增添了新的活力。Hamlin的车用传感器涵盖了安全类、动力总成、排放和舒适性四大类别,通过检测转速、位移、位置和角度等参数,为汽车提供了精准的监控和控制。这些传感器不仅提升了汽车的性能和安全性,也满足了消费者对驾驶体验的高要求。

4. 市场拓展:Littelfuse与Hamlin的全球化战略

在Hamlin的助力下,Littelfuse加快了全球化步伐。通过在欧洲、亚洲和美国的持续扩张,Littelfuse的产品和服务覆盖了更广泛的市场。Hamlin的传感器技术成为了Littelfuse在全球市场上的一张重要名片,吸引了众多国际客户的关注。同时,Littelfuse也加大了对新兴市场的投入,特别是在中国市场,通过与本土合作伙伴的紧密合作,进一步提升了品牌影响力和市场份额。

5. 持续增长与未来展望

自Hamlin加入以来,Littelfuse的业绩实现了持续增长。通过不断的研发投入和市场拓展,Littelfuse在电路保护、传感器与功率器件领域均取得了显著成就。展望未来,Littelfuse将继续依托Hamlin等子公司的技术优势和市场资源,推动产品创新和市场升级。同时,随着新能源汽车、物联网等新兴领域的快速发展,Littelfuse将迎来更多的发展机遇和挑战,为电子行业的进步贡献更多力量。

Everspin Technologies公司的发展小趣事

Everspin Technologies公司的起源可以追溯到飞思卡尔半导体公司。在2004年,摩托罗拉将其半导体业务剥离,创建了飞思卡尔半导体。这家公司在磁阻随机存取存储器(MRAM)领域进行了大量研究和开发工作。随着MRAM技术的成熟,飞思卡尔半导体决定将其MRAM部门独立出来,于是在2008年,Everspin Technologies公司正式成立,专注于MRAM的设计、制造和销售。

FEIG ELECTRONIC公司的发展小趣事

FEIG ELECTRONIC与意法半导体(STMicroelectronics)的合作是其发展史上的又一重要篇章。两家公司共同研发了一种非接触式个性化设置系统,该系统能够在短时间内完成对托盘上有意法半导体ST25DV NFC动态标签的货品的个性化设置,无需打开产品电源或包装。这一创新技术不仅大大提高了产品生产效率,还为客户提供了更加便捷、高效的服务体验。

EPT公司的发展小趣事

随着品牌影响力的不断提升,EPT开始积极拓展OEM/ODM业务。公司凭借先进的生产技术和严格的质量管理体系,成功与多家国内外知名企业建立了合作关系。通过为客户提供定制化的产品和服务,EPT不仅实现了业务的快速增长,还为其积累了丰富的行业经验。

问答坊 | AI 解惑

Intel计划第四季度发布9款Merom处理器

Intel计划第四季度发布9款Merom处理器据国外网站The Inquirer报道,Intel计划在今年第四季度发布9款采用Merom核心的双核处理器,其他更多的Merom核心处理器将在2007年上半年陆续发布。     按照Intel的路线图,将在下半年推出N ...…

查看全部问答>

单片机外围电路设计

单片机外围电路设计…

查看全部问答>

SJF 2440 刚才需要的朋友过来拿吧。

SJF 2440 刚才需要的朋友过来拿吧。…

查看全部问答>

Windows Embedded为航天圆梦

网络化、信息化的要求随着因特网技术的成熟、带宽的提高日益提高,使得航天时代不仅促进了运载火箭技术,应用卫星技术与深空探测技术的迅猛发展,而且也使因特网发展成了太空网,延伸到了1亿2000万公里的火星,促进了嵌入式技术在航天应用的迅 ...…

查看全部问答>

Windows XP Embedded哪里能下载?谁能解释一下这个系统?

对这个系统不太了解,具体怎么使用? 谁能提供一个下载地址?谢谢 网络不太好,从微软官网下不动..…

查看全部问答>

EVC4.0为什么将 standard sdk改成 pocket pc 2003 cpu就100%

由于出现这个问题: hello.rc(13) : fatal error RC1015: cannot open include file \'aygshell.h\' 所以要把工具栏上第三行第二个项standard sdk改成 pocket pc 2003 ,可是一改这个CPU就100了,而且EVC也没反应,改也改不过来,有没有其它办法来 ...…

查看全部问答>

verilog assign语句的用法1

  (1)module assign_test (                        clk,         &nb ...…

查看全部问答>

ST大陆代理真的不行啊!

                                 NXP ARM 的破玩艺都能这么火! 可惜ST ARM空有一身好本领!…

查看全部问答>

IntPrioritySet( )和IntPriorityGroupingSet( )有什么区别

 函数 IntPriorityGroupingSet(  )和 IntPriorityGroupingGet(  )用来管理抢占式优先级和子优先级的分组设置   函数 IntPrioritySet(  )和 IntPriorityGet(  )用来管理一个片内外设的优先级   两者有什么区 ...…

查看全部问答>