☰
HRTOS实战:8051使用雨滴传感器DO检测雨滴并通过数码管显示
2026/9/27 7:34:55 网站建设 项目流程

一、前言

在前面的文章中,我们使用雨滴传感器的 AO 模拟量输出,通过 ADC 获取雨滴传感器的模拟数据,并使用4位数码管显示 ADC 转换结果。

除了 AO 模拟输出之外,常见的雨滴传感器模块还提供 DO 数字输出,可以直接根据传感器的阈值判断当前是否检测到雨滴。

本文使用 HRTOS 在 8051 单片机上实现一个简单的雨滴检测应用:

  • 读取雨滴传感器 DO 数字量

  • 判断当前是否检测到雨滴

  • 使用4位数码管显示检测状态

  • 将传感器读取和显示分别设计为独立任务

最终显示效果:

0000:检测到雨滴 0001:未检测到雨滴

通过这个简单的实例,可以进一步了解 HRTOS 在 8051 传感器检测类应用中的基本使用方法。


二、雨滴传感器 DO 输出

雨滴传感器模块通常可以提供 AO 和 DO 两种输出。

其中:

  • AO:模拟量输出,可以反映传感器检测到的雨滴变化程度

  • DO:数字量输出,根据模块上的比较器阈值输出高低电平

本文使用的是 DO 数字量输出。

程序中约定:

DO = 0:检测到雨滴 DO = 1:未检测到雨滴

因此,应用程序并不需要进行 ADC 转换,只需要读取一个数字状态即可。

这种方式比较适合实现简单的开关量检测,例如:

是否下雨 是否有人 是否有障碍物 是否触发传感器

如果需要获得更加连续、精确的雨滴变化数据,则可以使用前面介绍的 AO 模拟量方式。


三、程序结构

本实例仍然采用 HRTOS 的多任务方式组织程序。

整个应用划分为两个任务:

┌──────────────────────────┐ │ HRTOS 应用程序 │ ├──────────────────────────┤ │ │ │ task_raindrop_read │ │ 雨滴传感器DO读取任务 │ │ │ │ │ ▼ │ │ raindrop_do │ │ │ │ │ ▼ │ │ task_seg_display │ │ 数码管显示任务 │ │ │ └──────────────────────────┘

其中:

任务1:雨滴传感器读取

负责周期性调用:

drv_raindrop_read_do();

读取传感器当前的 DO 状态。

任务2:数码管显示

负责不断刷新4位数码管,并根据raindrop_do的状态显示:

0000

或者:

0001

这样可以将传感器采集和数据显示分开,使程序结构更加清晰。


四、定义雨滴传感器状态

首先定义一个变量保存雨滴传感器的 DO 状态:

unsigned char raindrop_do = 1;

初始化为1,表示默认状态为:

未检测到雨滴

传感器读取任务运行后,会不断更新这个变量。


五、创建雨滴传感器读取任务

传感器读取任务如下:

void task_raindrop_read(void) { while(1) { /* 读取雨滴传感器数字量 */ raindrop_do = drv_raindrop_read_do(); /* * 周期读取传感器状态 */ os_delay(50); } }

任务首先调用:

drv_raindrop_read_do();

获得当前雨滴传感器的 DO 状态。

然后保存到:

raindrop_do

变量中。

读取完成之后调用:

os_delay(50);

让当前任务延时一段时间,然后再次读取。

这样就形成了一个周期性的传感器采集任务:

读取DO ↓ 保存状态 ↓ 延时 ↓ 再次读取 ↓ 循环

对于这种变化速度比较慢的传感器,没有必要让任务一直高速读取,因此使用周期性任务即可。


六、创建数码管显示任务

数码管显示任务如下:

void task_seg_display(void) { while(1) { /* * 显示雨滴传感器状态 * * 0000:检测到雨滴 * 0001:未检测到雨滴 */ drv_seg_display(0, 0); drv_seg_display(1, 0); drv_seg_display(2, 0); drv_seg_display(3, raindrop_do); } }

这里前三位固定显示:

000

最后一位显示raindrop_do。

因此:

当:

raindrop_do = 0;

数码管显示:

0000

表示检测到雨滴。

当:

raindrop_do = 1;

数码管显示:

0001

表示未检测到雨滴。

这里没有在显示任务中调用os_delay(),而是持续执行数码管刷新操作。

这样可以保持动态数码管正常显示。


七、初始化 HRTOS 应用

系统入口函数:

void hrtos_main(void) { /* 初始化雨滴传感器 */ drv_raindrop_init(); /* 初始化数码管 */ drv_seg_init(); /* 创建雨滴传感器读取任务 */ os_task_create( task_raindrop_read, 2, 2, 4 ); /* 创建数码管显示任务 */ os_task_create( task_seg_display, 3, 2, 4 ); }

首先初始化雨滴传感器:

drv_raindrop_init();

然后初始化4位数码管:

drv_seg_init();

最后创建两个任务:

os_task_create(task_raindrop_read, 2, 2, 4); os_task_create(task_seg_display, 3, 2, 4);

这样 HRTOS 启动后,就可以同时运行传感器读取任务和数码管显示任务。


八、完整程序

完整示例代码如下:

#include "hrtos.h" #include "hrtos_hal.h" /* * ========================================================= * 雨滴传感器DO + 4位数码管显示示例 * --------------------------------------------------------- * 功能: * 1. 初始化雨滴传感器 * 2. 读取雨滴传感器数字量DO * 3. 使用4位数码管显示检测状态 * * DO状态: * 0:检测到雨滴 * 1:未检测到雨滴 * * 数码管显示: * 0000:检测到雨滴 * 0001:未检测到雨滴 * ========================================================= */ unsigned char raindrop_do = 1; /*------------------------------------------------ * 雨滴传感器DO读取任务 *------------------------------------------------*/ void task_raindrop_read(void) { while(1) { /* 读取雨滴传感器数字量 */ raindrop_do = drv_raindrop_read_do(); /* * 周期读取传感器状态 */ os_delay(50); } } /*------------------------------------------------ * 数码管显示任务 *------------------------------------------------*/ void task_seg_display(void) { while(1) { /* * 显示雨滴传感器状态 * * 0000:检测到雨滴 * 0001:未检测到雨滴 */ drv_seg_display(0, 0); drv_seg_display(1, 0); drv_seg_display(2, 0); drv_seg_display(3, raindrop_do); } } /** * @brief 雨滴传感器DO示例初始化 */ void hrtos_main(void) { /* 初始化雨滴传感器 */ drv_raindrop_init(); /* 初始化数码管 */ drv_seg_init(); /* 创建雨滴传感器读取任务 */ os_task_create( task_raindrop_read, 2, 2, 4 ); /* 创建数码管显示任务 */ os_task_create( task_seg_display, 3, 2, 4 ); }

九、HRTOS任务划分的意义

这个例子虽然非常简单,但它体现了一个比较典型的嵌入式任务划分方式。

传统的单循环程序可能会写成:

while(1) { raindrop_do = drv_raindrop_read_do(); drv_seg_display(0, 0); drv_seg_display(1, 0); drv_seg_display(2, 0); drv_seg_display(3, raindrop_do); }

当功能继续增加以后,所有功能都会堆积在一个循环中。

使用 HRTOS 后,可以按照功能拆分:

传感器任务 ↓ 负责数据采集 显示任务 ↓ 负责数据显示

以后如果继续增加蜂鸣器、继电器、串口通信等功能,还可以继续创建对应任务,而不需要把所有代码都集中在一个while(1)中。

例如可以进一步扩展为:

task_raindrop_read │ ├── 获取雨滴状态 │ ▼ raindrop_do │ ├───────────────┐ ▼ ▼ 显示任务 报警任务 数码管显示 蜂鸣器控制

这也是 HRTOS 在实际 8051 项目中的一个重要作用:将不同功能按照任务进行组织。


十、DO与AO的区别

雨滴传感器的 AO 和 DO 适合不同的应用场景。

输出方式数据类型典型用途
AO模拟量获取雨滴变化程度
DO数字量判断是否达到检测阈值

如果只是需要判断:

有没有雨

那么 DO 就已经足够。

如果需要进一步分析:

雨滴变化大小 雨量变化趋势 传感器输出曲线

则可以使用 AO,并通过 ADC 获取更加详细的数据。

因此,这两个接口并不是相互替代,而是针对不同应用需求提供不同的数据形式。


十一、总结

本文使用 HRTOS 在 8051 单片机上实现了一个简单的雨滴传感器数字量检测实例。

整个程序主要包含两个任务:

task_raindrop_read

负责周期读取雨滴传感器 DO 状态;

task_seg_display

负责实时刷新4位数码管。

最终通过:

0000

表示检测到雨滴,通过:

0001

表示未检测到雨滴。

虽然这个实例功能比较简单,但它完整体现了传感器采集任务 + 显示任务的基本 HRTOS 应用结构。

对于 8051 这类资源有限的单片机来说,通过任务划分组织应用程序,可以让程序结构更加清晰,也方便后续继续加入更多传感器、执行器和通信功能。

后续还可以在这个基础上扩展雨滴报警、继电器控制、串口上传以及多传感器协同等功能。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询