ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
>[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) (非商务合作**勿扰**,此处**非**技术支持)