>[success] **技术支持说明:**
>**1**.一般以自主学习为主
> **2**.可到官方问答社区中提问:[**去提问**](https://bbs.csdn.net/forums/nb-iot)
> **3**.工程师**会尽快**解答社区问题,但他们是一线开发,【**难以保证**】解答时效,解答辛苦,感谢理解!
<br/>
STM32主板中内置了一个奥松 DHT20温湿度传感器,如图所示。
![](https://img.kancloud.cn/40/ca/40ca91744487159d79af83a451192c94_1084x1168.png =300x)
本节课将讲解如何使用DHT20温湿度传感器来感知环境温湿度,并且把数据在屏幕中显示出来。许多传感器的使用方法都是类似的,通过学习使用DHT20,相信读者可以做到举一反三,能够使用更多种类的传感器。
<br/>
## **DHT20 简介**
DHT20是奥松电子精心打造的一款温湿度传感器,是DHT11的全新升级版本。传感器内配置一颗全新设计的专用芯片、经过改进的半导体电容式湿度传感元件和一个温度传感元件。全面改良后,DHT20在降低功耗、降低成本的同时,在测量精度、测量范围、响应时间、稳定性等方面的性能都有大幅提升,其主要技术参数如图所示。
![](https://img.kancloud.cn/51/1c/511ce64c1563d6a8e4481d32c2e78f36_1440x655.png =500x)
<br/>
## **项目架构设计**
基于前述的SDK设计思想,笔者把使用温湿度传感器的代码分为3个部分,分别是HAL的DHT20驱动程序、服务层的传感器服务和任务层的传感器任务,如图所示。
![](https://img.kancloud.cn/fb/54/fb5406453de55a909d010ec2b773377e_341x551.png =300x)
###
打开本节课配套的工程可以找到与这3个部分对应的文件,如图所示。
![](https://img.kancloud.cn/63/e3/63e301f8e2f44f44e80f88990a3cbb21_692x1758.png =200x)
###
其中的hal\_dht11.h/c是DHT20驱动程序,svc\_sensor.h/c是传感器服务,task\_sensor.h/c是传感器任务。
<br/>
## **DHT20驱动程序**
hal\_dht20.h文件中有两个重要的函数,代码如下:
###
```
/**
* @fn halDht20Init
*
* @brief 初始化函数,使用DHT20前必须先调用此函数
*/
#define halDht20Init() AHT20_Init()
/**
* @fn halDht20GetData
*
* @brief 获取DHT20的温湿度数据
*
* @return 温湿度数据值
*/
#define halDht20GetData() AHT20GetData()
```
halDht20GetData()函数的返回值是一个结构体,定义代码如下:
```
/** @brief 用于表示DHT20温湿度数据 */
typedef struct {
unsigned char ok;//ok的值非0时温湿度数据才有效
float temp;//温度值
float humi;//湿度值
} AHT20Data_t;
```
<br/>
## **传感器服务**
传感器服务的作用是抽象各种传感器驱动程序,为上层提供统一的接口。
打开svc\_sensor.h文件,代码如下:
```
#ifndef __SVC_SENSOR_H__
#define __SVC_SENSOR_H__
/**
* 初始化温湿度传感器
*/
void svcSensorInit(void);
/**
* 获取温度值
* @param value用于存放温度值
* @return 0表示获取成功,非0表示获取失败
*/
int svcSensorGetTemp(float *value);
/**
* 获取湿度值
* @param value用于存放湿度值
* @return 0表示获取成功,非0表示获取失败
*/
int svcSensorGetHumi(float *value);
#endif /* __SVC_SENSOR_H__ */
```
###
打开svc\_sensor.c文件,代码如下:
```
#include "svc_sensor.h"
#include "hal_dht20.h"
/**
* 初始化温湿度传感器
*/
void svcSensorInit()
{
}
/**
* 获取温度值
* @param value用于存放温度值
* @return 0表示获取成功,非0表示获取失败
*/
int svcSensorGetTemp(float *value)
{
/* 调用DHT20驱动程序获取数据 */
AHT20Data_t data = halDht20GetData();
if (!data.ok) return -1;
*value = data.temp;
return 0;
}
/**
* 获取湿度值
* @param value用于存放湿度值
* @return 0表示获取成功,非0表示获取失败
*/
int svcSensorGetHumi(float *value)
{
/* 调用DHT20驱动程序获取数据 */
AHT20Data_t data = halDht20GetData();
if (!data.ok) return -1;
*value = data.humi;
return 0;
}
```
<br/>
## **传感器任务:task_sensor**
传感器任务实现了每隔1.5秒获取温湿度,并在显示屏上显示。打开task\_sensor.c文件,代码如下:
###
```
#include "task_sensor.h"
#include "svc_plugins.h"
#include "svc_sensor.h"
#include "svc_task.h"
#include "svc_log.h"
#include <stdio.h>
static void taskSensorRunner(uint8_t, void *);
/*
* 传感器任务初始化
*/
void taskSensorInit()
{
/* 启动一个1.5秒的周期性任务 */
svcTaskAdd(
1500,//1.5秒
1,//重复执行
taskSensorRunner,//任务内容
0);//任务参数
}
/*
* 任务内容
*/
void taskSensorRunner(uint8_t id, void *args)
{
char str[32];
float temp, humi;
/* 获取温度,显示在第三行 */
if (svcSensorGetTemp(&temp) == 0) {
sprintf(str, "temp: %.1f C", temp);
svcPluginsLcdWrite(0, 0, (uint8_t *)str, 0);
}
/* 获取湿度,显示在第四行 */
if (svcSensorGetHumi(&humi) == 0) {
sprintf(str, "humi: %.1f %%", humi);
svcPluginsLcdWrite(0, 0, 0, (uint8_t *)str);
}
}
```
<br/>
## **编写Main函数**
打开main.c文件,代码如下:
```
#include "main.h"
#include "task_sensor.h"
#include "task_input.h"
#include "task_lcd.h"
#include "task_uart.h"
#include "task_led.h"
#include "task_test.h"
#include "svc_sensor.h"
#include "svc_button.h"
#include "svc_plugins.h"
#include "svc_log.h"
#include "svc_task.h"
#include "hal_dht20.h"
#include "hal_button.h"
#include "hal_oled12864.h"
#include "hal_led.h"
#include "hal_uart.h"
#include "hal_system.h"
static void halInit(void);
static void svcInit(void);
static void taskInit(void);
int main(void)
{
halInit();//HAL初始化
svcInit();//服务层初始化
taskInit();//任务层初始化
/* 每隔1毫秒查看有没有任务需要执行*/
while (1) {
halSystemDelayUs(1000);//延时1毫秒
svcTaskPoll(1);//查看有没有任务需要执行
}
}
/* HAL初始化 */
void halInit()
{
halSystemInit();//系统初始化
halUartInit(115200);//串口初始化
halLedInit();//LED初始化
halOLED12864Init();//显示器初始化
halButtonInit(0);//按钮初始化
halDht20Init();//DHT20温湿度传感器初始化
}
/* Services层初始化*/
void svcInit()
{
svcTaskInit();//任务管理服务初始化
svcLogInit();//日志服务初始化
svcPluginsInit();//插件服务初始化
svcButtonInit();//按钮服务初始化
svcSensorInit();//传感器服务初始化
}
/* Tasks */
void taskInit()
{
taskTestInit();//测试任务初始化
taskLedInit();//LED任务初始化
taskLcdInit();//显示器任务初始化
taskUartInit();//串口任务初始化
taskInputInit();//输入任务初始化
taskSensorInit();//传感器任务初始化
}
```
<br/>
## **代码测试**
* 把开发板的第1、2、3和4打到右边,第5和6位打到左边,如图所示。
![](https://img.kancloud.cn/58/9a/589a66f16f8ca111d36b54fac452805c_1076x1045.png =250x)
###
* 编译链接工程代码,把生成的Hex文件烧录到开发板中。
###
* 程序运行后,可以在屏幕上看到温湿度,如图所示。
![](https://img.kancloud.cn/5a/06/5a06e7d2f75f85a0139ad57baa5714a9_476x677.png =300x)
<br/>
<br/>
## **商务合作**
如有以下需求,可扫码添加管理员好友,注明“**商务合作**”
* 项目定制开发,技术范围:**NB-IoT**、**CATn(4G)**、**WiFi**、**ZigBee**、**BLE Mesh**以及**STM32**、**嵌入式Linux**等;
* 入驻平台,成为讲师;
* 接项目赚外快;
* 善学坊官网:[www.sxf-iot.com](https://www.sxf-iot.com/)
![](https://img.kancloud.cn/b7/5a/b75ac8c3da945f20568771f5935c388f_430x430.png =150x)
(非商务合作**勿扰**,此处**非**技术支持)
- 课程简介
- 配套资源下载
- 配套开发套件简介
- 简介
- 硬件组成 & 技术参数
- STM32 Pro 主板 原理图 & PCB图
- STM32 Std 主板 原理图 & PCB图
- 板载设备使用说明
- STM32开发指南
- 1. 搭建开发环境
- 1.1 Keil MDK简介与安装
- 1.2 STM32 Pack 简介与安装
- 1.3 CH34x 驱动简介与安装
- 1.4 ISP 串口下载工具
- 1.5 串口调试工具
- 2. STM32 开发基础
- 2.1 新建工程
- 2.2 实现第1个程序
- 2.3 Hex 文件烧录详解
- 3. 移植官方标准工程模板
- 4. GPIO实验:LED
- 5. 系统延时应用
- 6. GPIO实验:按键
- 7. GPIO中断实验——按键触发实验
- 8. 使用定时器TIM3
- 9. 串口通信实验
- 10. ADC 实验
- 11. OLED显示器实验
- 12. SDK 设计思想
- 13. SDK 架构解析
- 14. 多任务应用实验
- 15. 输入型任务:按键输入实验
- 16. 输入型任务:串口接收实验
- 17. 高精度温湿度传感器实验
- 进阶课程