一、前言
在前面的文章中,我们使用雨滴传感器的 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 这类资源有限的单片机来说,通过任务划分组织应用程序,可以让程序结构更加清晰,也方便后续继续加入更多传感器、执行器和通信功能。
后续还可以在这个基础上扩展雨滴报警、继电器控制、串口上传以及多传感器协同等功能。