0


基于stm32的太空人温湿度时钟项目——DHT11(HAL库)

  1. **项目介绍:**本项目属于**复合型**项目,主要包括的功能模块有**RTC时钟**,**OLED动态显示**,**DHT11温湿度传感器**。稍作修改可以作为一级菜单界面等使用,本文将会详细讲解各部分原理与编程思路,文章末尾会有**源码开源(HAL库)。**
  2. **硬件设备:**STM32F103C8T6,OLED,HDT11
  3. ** 硬件实物图:**

  1. **效果图:**

** 引脚连接:**

OLED:

VCC --> 3.3V

GND --> GND

SCL --> PB10

SDA --> PB11

DHT11:

DATA --> PA9

VCC --> 3.3V

GND --> GND

一、 DHT11简介

1.1 DTH11概念与介绍

  1. DHT11 是广州奥松有限公司生产的一款**湿温度一体**化的数字传感器。该传感器包括一个电阻式测湿元件和一个 NTC 测温元件,并与一个高性能 8 位单片机相连接。通过单片机等微处理器简单的电路连接就能够实时的**采集本地湿度和温度**。DHT11 与单片机之间能采用简单的**单总线进行通信****(DATA引脚)**,仅仅需要一个I/O 口。传感器**内部湿度和温度数据 40Bit**的数据一次性传给单片机,数据采用校验和方式进行校验,有效的保证数据传输的准确性。**DHT11 功耗很低,5V 电源电压下,工作平均最大电流 0.5mA。**(正常使用3.3V即可)

工作电压范围:3.5V-5.5V
工作电流 :平均 0.5mA
湿度测量范围:20-90%RH
温度测量范围:0-50℃
湿度分辨率 :1%RH 8 位
温度分辨率 :1℃ 8 位
采样周期 :1S
单总线结构
与 TTL 兼容(5V)

  1. **注意事项:**DTH11由于物理与化学结构性质,是比较容易损坏的,需要尽量远离恶劣坏境进行工作测量。如果实在不小心,对DHT1传感器造成了破坏,读者可以去网上搜索一下修复教程进行抢救一下。

实物图:

1.2 DTH11工作原理

  1. 前文有提到:DTH11传感器只具有3根引脚,所以是**单总线**进行通讯(DATA),为了方便读者对于通讯原理与编程的同步高效率理解。关于时序的通讯方式将在本文**代码段部分**逐个详细讲解。
  2. ** 单片机读取数据**

** DHT11数字湿温度传感器采用单总线数据格式。即,单个数据引脚端口完成输入输出双向传输。其数据包由5Byte(5个字节=40Bit)组成。数据分小数部分整数部分**,具体格式在下面说明。一次完整的数据传输为40bit,高位先出。

校验方式:校验和数据为前四个字节相加。

  1. 传感器数据输出的是未编码的**二进制数据**。数据(湿度、温度、整数、小数)之间应该分开处理。如果,某次从传感器中读取如下5Byte数据:

由以上数据就可得到湿度和温度的值,计算方法:
humi (湿度)= byte4 . byte3=45.0 (%RH)
temp (温度)= byte2 . byte1=28.0 ( ℃)
jiaoyan(校验)= byte4+ byte3+ byte2+ byte1=73(=humi+temp)(校验正确)
注意:DHT11一次通讯时间最大3ms,主机连续采样间隔建议不小于100ms。(这一点在时序编程的时候也会经常体现出来)

  1. if(data[0] + data[1] + data[2] + data[3] == data[4])
  2. {
  3. //执行程序
  4. }

** ** 时序部分是笔者认为DHT11最为重要的部分,结合代码与文字描述可能会让读者有更好的理解,读者可以调至下文代码段进行学习。

二、RTC简介

  1. **RTC**(Real Time Clock)即实时时钟,RTC究其本质还是一个**定时器**(独立的定时器)。RTC模块拥有一个**连续计数的计数器**,在相应的软件配置下,可以提供时钟**日历的功能**。修改计数器的值可以重新设置当前时间和日期 RTC还包含用于管理**低功耗模式**的**自动唤醒单元**。

断电情况下 RTC仍可以独立运行 只要芯片的备用电源一直供电,RTC上的时间会一直走。(部分最小系统板是没有芯片备用电源的,所以不一定都可以掉电仍然计时)

  1. 其拥有的两个 32 位寄存器包含**二进码十进数格式 (BCD)** 的秒、分钟、小时( 12 24 小时制)、星期几、日期、月份和年份。此外,还可提供二进制格式的亚秒值。系统可以自动将月份的天数补偿为 2829(闰年)、30 31 天。

RCT特征:

● 可编程的预分频系数:分频系数高为220
● 32位的可编程计数器,可用于较长时间段的测量。
● 2个分离的时钟:用于APB1接口的PCLK1和RTC时钟(RTC时钟的频率必须小于PCLK1时钟 频率的四分之一以上)。
● 可以选择以下三种RTC的时钟源
● HSE时钟除以128;
LSE振荡器时钟;(比较常用的)
● LSI振荡器时钟

2个独立的复位类型:
● APB1接口由系统复位;
● RTC核心(预分频器、闹钟、计数器和分频器)只能由后备域复位

3个专门的可屏蔽中断
● 1.闹钟中断,用来产生一个软件可编程的闹钟中断。

  1. 2.秒中断,用来产生一个可编程的周期性中断信号(长可达1秒)。
  2. 3.溢出中断,指示内部可编程计数器溢出并回转为0的状态。

RTC时钟源:

三种不同的时钟源可被用来驱动系统时钟(SYSCLK):

  1. **HSI振荡器时钟**
  2. **HSE振荡器时钟**
  3. **PLL时钟**

CubexMX时钟树下的选择:

三、OLED简介与使用

  1. 关于OLED的使用与原理不熟悉的笔者欢迎去笔者另一篇文章学习【强烈推荐】基于stm32OLED各种显示实现(含动态图)_混分巨兽龙某某的博客-CSDN博客

四、CubexMX配置

** 1、RCC配置外部高速晶振(精度更高)——HSE;RTC时钟选择:LSE;**

  1. **2SYS配置:Debug设置成Serial Wire**(**否则可能导致芯片自锁**);

  1. **3GPIO配置:PA9设置为普通输出(DHT11DATA接线引脚);**

  1. ** 4RTC配置:年月日,时分秒;**

** 5、TIM2配置:由上面可知DHT11的使用需要us级的延迟函数,HAL库自带只有ms的,所以需要自己设计一个定时器;**

** 6、I2C2配置:作为OLED的通讯方式;**

  1. **7、时钟树配置**

** 8、工程配置**

五、代码部分

5.1 DTH11代码:

  1. 要编写出DHT11温湿度传感器的程序代码,需要从**DHT11时序图**来分析:
  2. 如下图所示,用户MCU发送一次开始信号后,DHT11从**低功耗模式**转换到**高速模式**,等待主机开始信号结束后,DHT11发送响应信号,送出**40bit的数据**,并触发一次信号采集,用户可选择读取部分数据。从模式下,DHT11接收到开始信号触发一次温湿度采集,如果没有接收到主机发送开始信号,DHT11不会主动进行温湿度采集。**采集数据后转换到低速模式**。

总结:DHT11的代码实现总共分为6个部分

  1. 1DTH11——DATA引脚配置
  2. 2DHT11复位函数(即MCU发出起始信号)
  3. 3DHT11检查函数
  4. 4、读取DHT11一位数据(返回值0/1
  5. 5、读取一个字节(返回值:读到的数据)
  6. 6、读取显示温湿度传感器数据

5.1.1 配置输入输出

** 由于DHT11温湿度传感器采用了单总线通讯的方式,所以DATA引脚连接的PB9必须既要设置成输入也要设置成输出。**

  1. /**
  2. * @brief 设置引脚模式
  3. * @param mode: 0->out, 1->in
  4. * @retval None
  5. */
  6. static void DHT11_GPIO_MODE_SET(uint8_t mode)
  7. {
  8. if(mode)
  9. {
  10. /* 输入 */
  11. GPIO_InitTypeDef GPIO_InitStruct;
  12. GPIO_InitStruct.Pin = GPIO_PIN_9; // 9号引脚
  13. GPIO_InitStruct.Mode = GPIO_MODE_INPUT; // 输入模式
  14. GPIO_InitStruct.Pull = GPIO_PULLUP; // 上拉输入
  15. HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  16. }
  17. else
  18. {
  19. /* 输出 */
  20. GPIO_InitTypeDef GPIO_InitStructure;
  21. GPIO_InitStructure.Pin = GPIO_PIN_9; // 9号引脚
  22. GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; // Push Pull 推挽输出模式
  23. GPIO_InitStructure.Pull = GPIO_PULLUP; // 上拉输出
  24. GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; // 高速
  25. HAL_GPIO_Init(GPIOB,&GPIO_InitStructure);
  26. }
  27. }

5.1.2 DHT11复位函数

  1. 复位DHT11就是发送**DHT11起始信号**,告诉传感器通讯开始。**起始信号**要求主机MCU先将总线PB9拉为**低电平**持续**至少18ms(这里设置20ms)**,随后主机MCU将总线PB9设置为**高电平**持续**20~40us(这里取中间值30usHAL库中没有us,这里需要TIM2定时器制作一个延迟函数)**![](https://img-blog.csdnimg.cn/bc3e59fdfbdc4b70ae9d08e465a3c581.png)​

us延迟函数:

  1. /**
  2. * @brief 定时器延时us,Prescaler -> 32-1
  3. * @param us: <= 65535
  4. * @retval None
  5. */
  6. void Tims_delay_us(uint16_t nus)
  7. {
  8. __HAL_TIM_SET_COUNTER(DLY_TIM_Handle, 0);
  9. __HAL_TIM_ENABLE(DLY_TIM_Handle);
  10. while (__HAL_TIM_GET_COUNTER(DLY_TIM_Handle) < nus)
  11. {
  12. }
  13. __HAL_TIM_DISABLE(DLY_TIM_Handle);
  14. }

DTH11复位函数(起始):

  1. /**
  2. * @brief 温湿度传感器启动信号发送
  3. * @param void
  4. * @retval None
  5. */
  6. void DHT11_START(void)
  7. {
  8. DHT11_GPIO_MODE_SET(0); // 主机设置为输出模式
  9. DHT11_PIN_RESET; // 主机拉低电平
  10. HAL_Delay(20); // 主机等待 18 < ms > 30
  11. DHT11_GPIO_MODE_SET(1); // 主机设置为输入模式,等待DHT11答应
  12. } // 因为设置了上拉输入,GPIO -> 1

5.1.3 DHT11检查函数

  1. **检查DHT11是否正常**,正常的话会在单片机发送起始信号完成后,**传感器返回80us低电平**,**然后发送80us高电平**。即证明DHT11工作正常,该函数工作正常返回0,否则返回1,该函数中利用了while循环检测在一定时间内的电平变化,此类用法在后面也会经常用到。(笔者这里采用了**另一种检查DHT11**是否正常的方式,就是**直接延迟40us**,虽然读取**PB9引脚**的数值,为1则正常,为0则重启DHT11即可)

  1. /**
  2. * @brief 检测温湿度传感器是否存在(检测DHT11的应答信号)
  3. * @param void
  4. * @retval 0/1
  5. */
  6. unsigned char DHT11_Check(void)
  7. {
  8. Tims_delay_us(40);
  9. if(DHT11_READ_IO == 0) // 检测到DHT11应答
  10. {
  11. return 1;
  12. }
  13. else // 检测到DHT11不应答
  14. {
  15. return 0;
  16. }
  17. }

** 5.1.4 读取DHT11一位数据**

  1. 这里延时**40us后判断引脚电平**,来判断该位**数据为10**。之所以是40微秒是因为传感器数字0的信号持续时间为**26-28us。**同时,从笔者日常实验中发现,DHT11中最好不要频繁使用延迟函数取可以检验DHT11是否正常工作,**很有可能造成死机或者数据为0。**
  1. /**
  2. * @brief 读取一位数据 1bit
  3. * @param void
  4. * @retval 0/1
  5. */
  6. unsigned char DHT11_READ_BIT(void)
  7. {
  8. while(!DHT11_READ_IO); // 过度数据的低电平
  9. Tims_delay_us(40); // 过度数据的高电平
  10. if(DHT11_READ_IO) // 此时如果还为高电平则数据为 1
  11. {
  12. while(DHT11_READ_IO); // 过度数据的高电平
  13. return 1;
  14. }
  15. else // 若此时为低则为 0
  16. {
  17. return 0;
  18. }
  19. }

5.1.5 读取一个字节

  1. 循环读入一个字节的数据,并将每一步新加入的数据放置在最低位。
  1. /**
  2. * @brief 读取一个字节数据 1byte / 8bit
  3. * @param void
  4. * @retval temp
  5. */
  6. unsigned char DHT11_READ_BYTE(void)
  7. {
  8. uint8_t i,temp = 0; // 暂时存储数据
  9. for(i=0; i<8 ;i++)
  10. {
  11. temp <<= 1;
  12. if(DHT11_READ_BIT()) // 1byte -> 8bit
  13. {
  14. temp |= 1; // 0000 0001
  15. }
  16. }
  17. return temp;
  18. }

5.1.6 读取显示温湿度传感器数据

  1. 读取数据将数据存入数组,这里仅保留了温度数据的整数位,注意数据较验方法,**校验和数据等于“8bit湿度整数数据+8bit湿度小数数据 +8bi温度整数数据+8bit温度小数数据”所得结果的末8位**。
  1. /**
  2. * @brief 读取温湿度传感器数据 5byte / 40bit
  3. * @param void
  4. * @retval 0/1/2
  5. */
  6. unsigned char DHT11_READ_DATA(void)
  7. {
  8. uint8_t i;
  9. uint8_t data[5] = {0};
  10. DHT11_START(); // 主机发送启动信号
  11. if(DHT11_Check()) // 如果DHT11应答
  12. {
  13. while(!DHT11_READ_IO); // 过度DHT11答复信号的低电平
  14. while(DHT11_READ_IO); // 过度DHT11答复信号的高电平
  15. for(i=0; i<5; i++)
  16. {
  17. data[i] = DHT11_READ_BYTE(); // 读取 5byte
  18. }
  19. if(data[0] + data[1] + data[2] + data[3] == data[4])
  20. {
  21. //显示温度
  22. OLED_ShowCN_STR(0,4,0,2);
  23. OLED_ShowStr(32,4,":",2);
  24. OLED_ShowNum(40,4,data[2],2,16);
  25. OLED_ShowCN_STR(59,4,4,1);
  26. //显示湿度
  27. OLED_ShowCN_STR(0,6,2,2);
  28. OLED_ShowStr(32,6,":",2);
  29. OLED_ShowNum(40,6,data[0],2,16);
  30. OLED_ShowStr(59,6,"HR",2);
  31. return 1; // 数据校验通过
  32. }
  33. else
  34. {
  35. return 0; // 数据校验失败
  36. }
  37. }
  38. else // 如果DHT11不应答
  39. {
  40. return 2;
  41. }
  42. }

DHT11.C总代码:

  1. #include "dht11.h"
  2. #include "oled.h"
  3. /**
  4. * @brief 温湿度传感器主函数
  5. * @param void
  6. * @retval None
  7. */
  8. void DHT11(void)
  9. {
  10. DHT11_READ_DATA();
  11. HAL_Delay(50); // 预设一定缓冲
  12. }
  13. /**
  14. * @brief 温湿度传感器启动信号发送
  15. * @param void
  16. * @retval None
  17. */
  18. void DHT11_START(void)
  19. {
  20. DHT11_GPIO_MODE_SET(0); // 主机设置为输出模式
  21. DHT11_PIN_RESET; // 主机拉低电平
  22. HAL_Delay(20); // 主机等待 18 < ms > 30
  23. DHT11_GPIO_MODE_SET(1); // 主机设置为输入模式,等待DHT11答应
  24. } // 因为设置了上拉输入,GPIO -> 1
  25. /**
  26. * @brief 读取一位数据 1bit
  27. * @param void
  28. * @retval 0/1
  29. */
  30. unsigned char DHT11_READ_BIT(void)
  31. {
  32. while(!DHT11_READ_IO); // 过度数据的低电平
  33. Tims_delay_us(40); // 过度数据的高电平
  34. if(DHT11_READ_IO) // 此时如果还为高电平则数据为 1
  35. {
  36. while(DHT11_READ_IO); // 过度数据的高电平
  37. return 1;
  38. }
  39. else // 若此时为低则为 0
  40. {
  41. return 0;
  42. }
  43. }
  44. /**
  45. * @brief 读取一个字节数据 1byte / 8bit
  46. * @param void
  47. * @retval temp
  48. */
  49. unsigned char DHT11_READ_BYTE(void)
  50. {
  51. uint8_t i,temp = 0; // 暂时存储数据
  52. for(i=0; i<8 ;i++)
  53. {
  54. temp <<= 1;
  55. if(DHT11_READ_BIT()) // 1byte -> 8bit
  56. {
  57. temp |= 1; // 0000 0001
  58. }
  59. }
  60. return temp;
  61. }
  62. /**
  63. * @brief 读取温湿度传感器数据 5byte / 40bit
  64. * @param void
  65. * @retval 0/1/2
  66. */
  67. unsigned char DHT11_READ_DATA(void)
  68. {
  69. uint8_t i;
  70. uint8_t data[5] = {0};
  71. DHT11_START(); // 主机发送启动信号
  72. if(DHT11_Check()) // 如果DHT11应答
  73. {
  74. while(!DHT11_READ_IO); // 过度DHT11答复信号的低电平
  75. while(DHT11_READ_IO); // 过度DHT11答复信号的高电平
  76. for(i=0; i<5; i++)
  77. {
  78. data[i] = DHT11_READ_BYTE(); // 读取 5byte
  79. }
  80. if(data[0] + data[1] + data[2] + data[3] == data[4])
  81. {
  82. //显示温度
  83. OLED_ShowCN_STR(0,4,0,2);
  84. OLED_ShowStr(32,4,":",2);
  85. OLED_ShowNum(40,4,data[2],2,16);
  86. OLED_ShowCN_STR(59,4,4,1);
  87. //显示湿度
  88. OLED_ShowCN_STR(0,6,2,2);
  89. OLED_ShowStr(32,6,":",2);
  90. OLED_ShowNum(40,6,data[0],2,16);
  91. OLED_ShowStr(59,6,"HR",2);
  92. return 1; // 数据校验通过
  93. }
  94. else
  95. {
  96. return 0; // 数据校验失败
  97. }
  98. }
  99. else // 如果DHT11不应答
  100. {
  101. return 2;
  102. }
  103. }
  104. /**
  105. * @brief 检测温湿度传感器是否存在(检测DHT11的应答信号)
  106. * @param void
  107. * @retval 0/1
  108. */
  109. unsigned char DHT11_Check(void)
  110. {
  111. Tims_delay_us(40);
  112. if(DHT11_READ_IO == 0) // 检测到DHT11应答
  113. {
  114. return 1;
  115. }
  116. else // 检测到DHT11不应答
  117. {
  118. return 0;
  119. }
  120. }
  121. /**
  122. * @brief 设置引脚模式
  123. * @param mode: 0->out, 1->in
  124. * @retval None
  125. */
  126. static void DHT11_GPIO_MODE_SET(uint8_t mode)
  127. {
  128. if(mode)
  129. {
  130. /* 输入 */
  131. GPIO_InitTypeDef GPIO_InitStruct;
  132. GPIO_InitStruct.Pin = GPIO_PIN_9; // 9号引脚
  133. GPIO_InitStruct.Mode = GPIO_MODE_INPUT; // 输入模式
  134. GPIO_InitStruct.Pull = GPIO_PULLUP; // 上拉输入
  135. HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  136. }
  137. else
  138. {
  139. /* 输出 */
  140. GPIO_InitTypeDef GPIO_InitStructure;
  141. GPIO_InitStructure.Pin = GPIO_PIN_9; // 9号引脚
  142. GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; // Push Pull 推挽输出模式
  143. GPIO_InitStructure.Pull = GPIO_PULLUP; // 上拉输出
  144. GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; // 高速
  145. HAL_GPIO_Init(GPIOB,&GPIO_InitStructure);
  146. }
  147. }
  148. /**
  149. * @brief 定时器延时us,Prescaler -> 32-1
  150. * @param us: <= 65535
  151. * @retval None
  152. */
  153. void Tims_delay_us(uint16_t nus)
  154. {
  155. __HAL_TIM_SET_COUNTER(DLY_TIM_Handle, 0);
  156. __HAL_TIM_ENABLE(DLY_TIM_Handle);
  157. while (__HAL_TIM_GET_COUNTER(DLY_TIM_Handle) < nus)
  158. {
  159. }
  160. __HAL_TIM_DISABLE(DLY_TIM_Handle);
  161. }

DTH11.H代码:

  1. #ifndef __DHT11_H__
  2. #define __DHT11_H__
  3. /* Private includes ----------------------------------------------------------*/
  4. #include "main.h"
  5. #include "gpio.h"
  6. #include "stdio.h"
  7. #include "tim.h"
  8. #include "stm32f1xx.h"
  9. /* Private define ------------------------------------------------------------*/
  10. #define DHT11_PIN_SET HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_SET) // ??GPIO??
  11. #define DHT11_PIN_RESET HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET) // ??GPIO??
  12. #define DHT11_READ_IO HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_9) // DHT11 GPIO??
  13. #define DLY_TIM_Handle (&htim2) // ?????
  14. /* Private variables ---------------------------------------------------------*/
  15. /* Private typedef -----------------------------------------------------------*/
  16. /* Private function prototypes -----------------------------------------------*/
  17. void DHT11(void);
  18. void DHT11_START(void);
  19. unsigned char DHT11_READ_BIT(void);
  20. unsigned char DHT11_READ_BYTE(void);
  21. unsigned char DHT11_READ_DATA(void);
  22. unsigned char DHT11_Check(void);
  23. static void DHT11_GPIO_MODE_SET(uint8_t mode);
  24. void Tims_delay_us(uint16_t nus);
  25. void delay_us(uint16_t nus);
  26. #endif

5.2 RTC代码:

  1. void RTC_display() //RTC显示函数
  2. /* Get the RTC current Time */
  3. HAL_RTC_GetTime(&hrtc, &GetTime, RTC_FORMAT_BIN);
  4. /* Get the RTC current Date */
  5. HAL_RTC_GetDate(&hrtc, &GetData, RTC_FORMAT_BIN);
  6. /* Display date Format : yy/mm/dd */
  7. OLED_ShowNum(0,0,2000+GetData.Year,4,16); //year
  8. OLED_ShowStr(35,30,".",2);
  9. OLED_ShowNum(45,0,GetData.Month,2,16); //month
  10. OLED_ShowStr(60,30,".",2);
  11. OLED_ShowNum(70,0,GetData.Date,2,16); //date
  12. /* Display time Format : hh:mm:ss */
  13. OLED_ShowNum(0,2,GetTime.Hours,2,16); //hour
  14. OLED_ShowStr(20,2,":",2);
  15. OLED_ShowNum(30,2,GetTime.Minutes,2,16); //min
  16. OLED_ShowStr(47,2,":",2);
  17. OLED_ShowNum(58,2,GetTime.Seconds,2,16); //seconds
  18. }

5.3 OLED代码:

  1. 篇幅有限如果大家不熟悉,这里推荐大家取看一下本人另一篇文章【强烈推荐】基于stm32OLED各种显示实现(含动态图)_混分巨兽龙某某的博客-CSDN博客

5.4 main函数代码:

  1. /* Configure the system clock */
  2. SystemClock_Config();
  3. /* USER CODE BEGIN SysInit */
  4. /* USER CODE END SysInit */
  5. /* Initialize all configured peripherals */
  6. MX_GPIO_Init();
  7. MX_I2C2_Init();
  8. MX_RTC_Init();
  9. MX_TIM2_Init();
  10. /* USER CODE BEGIN 2 */
  11. OLED_Init();
  12. OLED_CLS();
  13. HAL_Delay(1000); //★这里的延迟务必加上,这是为了等待DHT11信号稳定,一定要加!!!
  14. /* USER CODE END 2 */
  15. /* Infinite loop */
  16. /* USER CODE BEGIN WHILE */
  17. while (1)
  18. {
  19. /* USER CODE END WHILE */
  20. /* USER CODE BEGIN 3 */
  21. RTC_display(); //RTC显示函数
  22. DHT11();
  23. OLED_DrawGIF(75,2,127,8,36,370,BMP2);
  24. }

六、项目效果

太空人RTC与温湿度DTH11显示

代码开源:

** 链接:https://pan.baidu.com/s/192-91-wpF6vWSILJJerf2w 提取码:8uyc**

  1. 如果读者对本文有所疑问可以留言评论笔者看到会进行回复,如果本文对您有所帮助请您点个赞吧!!!

本文转载自: https://blog.csdn.net/black_sneak/article/details/125472822
版权归原作者 混分巨兽龙某某 所有, 如有侵权,请联系我们删除。

“基于stm32的太空人温湿度时钟项目——DHT11(HAL库)”的评论:

还没有评论