HRTOS 4.0 Driver Library:03_Sensor 传感器驱动
在 51 单片机项目中,传感器是连接软件系统与真实物理世界的重要接口。
温度、湿度、距离、人体感应、土壤湿度、雨滴以及模拟量等数据,最终都需要通过单片机的 GPIO、ADC、定时器以及各种通信时序转换为应用程序能够处理的数据。
因此,在 51 单片机驱动开发 中,传感器驱动也是非常重要的一部分。
HRTOS 4.0 Driver Library 继续完善面向 8051/51 单片机的设备驱动体系。
本篇介绍:
03_Sensor —— 传感器驱动模块
当前模块包含:
-
ADC
-
DHT11 温湿度传感器
-
DS1302 实时时钟
-
DS18B20 温度传感器
-
HC-SR04 超声波测距
-
HC-SR501 人体红外
-
土壤湿度传感器
-
红外避障传感器
-
YL-83 雨滴传感器
一、模块概述
03_Sensor 模块通过:
#include "HRTOS_Sensor.h"
向应用程序提供传感器驱动接口。
所有主要驱动函数均采用:
drv_
作为统一前缀。
例如:
drv_adc_get_value();
drv_dht11_read();
drv_ds18b20_read();
drv_ultrasonic_read();
drv_human_read();
drv_soil_read_ao();
drv_ir_read();
drv_raindrop_read_do();
底层驱动统一依赖:
#include "hrtos_hal.h"
通过这种方式,将具体硬件操作与上层应用程序进行一定程度的分离。
二、当前支持的传感器
| 驱动 | 设备 | 类型 |
|---|---|---|
| ADC | STC12C5A60S2 内置 ADC | 模拟量 |
| DHT11 | 温湿度传感器 | 数字量 |
| DS1302 | 实时时钟芯片 | 三线串行 |
| DS18B20 | 温度传感器 | 1-Wire |
| HC-SR04 | 超声波测距 | 脉冲计时 |
| HC-SR501 | 人体红外 | 数字量 |
| Soil | 土壤湿度 | 模拟/数字 |
| IR | 红外避障 | 数字量 |
| YL-83 | 雨滴传感器 | 模拟/数字 |
从接口类型来看,这个模块覆盖了 51 单片机开发中比较典型的几种传感器接入方式:
ADC
GPIO
软件时序
1-Wire
三线串行通信
定时器测量
三、硬件验证说明
这里需要特别说明一个情况。
03_Sensor 模块目前的源码、接口和文档已经完成整理,但并不是其中所有传感器都已经完成实物硬件验证。
其中:
DHT11 和 HC-SR04 当前未完成硬件验证。
原因并不是驱动开发流程没有进行,而是当前用于测试的相关硬件存在问题。
因此,本版本对这两个驱动采用:
源码实现:已完成
接口整理:已完成
文档整理:已完成
硬件验证:暂未完成
的状态进行说明。
这一区分非常重要。
对于底层驱动开发而言:
代码能够编译,并不等于驱动已经完成硬件验证。
尤其是 DHT11 和 HC-SR04 这种高度依赖精确时序以及实际硬件响应的设备,仅通过代码检查无法完全证明驱动在真实硬件上的工作状态。
因此,后续在获得正常工作的测试硬件后,还需要继续进行实物验证。
四、ADC 驱动
4.1 功能简介
ADC 驱动提供 STC12C5A60S2 内置 10 位 ADC 的读取功能。
支持:
P1.0 ~ P1.7
共 8 个 ADC 通道。
转换结果范围:
0 ~ 1023
适用于各种模拟信号采集。
4.2 文件结构
ADC/
├── adc_init.c
├── adc_get_value.c
└── adc_isr.c
其中 adc_isr.c 为 ADC 中断服务相关内部实现。
4.3 ADC 通道
| 通道 | 引脚 |
|---|---|
| ADC_CH0 | P1.0 |
| ADC_CH1 | P1.1 |
| ADC_CH2 | P1.2 |
| ADC_CH3 | P1.3 |
| ADC_CH4 | P1.4 |
| ADC_CH5 | P1.5 |
| ADC_CH6 | P1.6 |
| ADC_CH7 | P1.7 |
4.4 ADC 控制
使用的主要特殊功能寄存器包括:
sfr ADC_CONTR = 0xBC;
sfr ADC_RES = 0xBD;
sfr ADC_LOW2 = 0xBE;
sfr P1ASF = 0x9D;
ADC 控制位:
DRV_ADC_POWER 0x80
DRV_ADC_FLAG 0x10
DRV_ADC_START 0x08
转换速度:
DRV_ADC_SPEEDLL 540 时钟周期
DRV_ADC_SPEEDL 360 时钟周期
DRV_ADC_SPEEDH 180 时钟周期
DRV_ADC_SPEEDHH 90 时钟周期
当前驱动使用:
DRV_ADC_SPEEDL
即 360 个时钟周期。
五、ADC API
核心接口:
u16 drv_adc_get_value(u8 channel);
参数:
channel:0~7
返回:
0~1023
例如:
#include "HRTOS_Sensor.h"
void main(void)
{
u16 value;
value = drv_adc_get_value(ADC_CH0);
while(1)
{
value = drv_adc_get_value(ADC_CH0);
// 处理 ADC 数据
}
}
如果通道号大于 7,则返回:
0
需要注意,当前 ADC 接口返回的是 10 位原始 ADC 数据,没有进一步转换为电压值。
六、DHT11 温湿度传感器
6.1 功能简介
DHT11 是典型的数字温湿度传感器。
HRTOS 4.0 为其提供:
-
初始化
-
温湿度读取
-
40 位数据接收
-
校验和处理
6.2 文件结构
DHT11/
├── dht11_init.c
├── dht11_read.c
├── dht11_read_byte.c
├── dht11_delay.c
└── dht11_delay_10us.c
6.3 硬件连接
当前数据引脚:
sbit DHT11_DATA = P3^7;
即:
DHT11 DATA → P3.7
DHT11 使用单总线方式通信。
6.4 通信过程
主机首先发送起始信号:
拉低 DATA
↓
保持至少 18ms
↓
释放总线
↓
等待 DHT11 响应
随后 DHT11 返回:
80us 低电平
+
80us 高电平
然后发送 40 位数据:
湿度高8位
湿度低8位
温度高8位
温度低8位
校验和
七、DHT11 API
初始化:
void drv_dht11_init(void);
读取:
unsigned char drv_dht11_read(unsigned char *humidity,
unsigned char *temperature);
典型使用:
#include "HRTOS_Sensor.h"
void main(void)
{
unsigned char humidity;
unsigned char temperature;
drv_dht11_init();
while(1)
{
drv_dht11_read(&humidity, &temperature);
// 处理温湿度数据
os_delay_ms(2000);
}
}
当前返回的数据主要为整数部分:
humidity → 湿度整数部分
temperature → 温度整数部分
采样间隔建议不小于:
2 秒
八、DHT11 硬件验证状态
这里特别记录当前版本的验证状态:
DHT11 当前暂未完成硬件验证。
原因是目前测试使用的 DHT11 硬件存在问题,因此暂时无法将当前结果作为可靠的实物验证结论。
DHT11 本身属于典型的时序敏感设备。
驱动中需要进行:
18ms 起始信号
80us 响应检测
微秒级位时序判断
40 位数据读取
校验和验证
同时为了保证通信时序,读取过程中会:
EA = 0;
关闭中断。
因此,即使程序能够正常编译,也不能仅凭代码检查判断 DHT11 驱动已经在真实硬件上完全可靠。
后续获得正常硬件后,将继续进行实物测试。
九、DS1302 实时时钟
9.1 功能简介
DS1302 是经典的实时时钟芯片。
当前驱动支持:
-
初始化
-
设置时间
-
读取时间
9.2 文件结构
DS1302/
├── ds1302_init.c
├── ds1302_set_time.c
├── ds1302_read_time.c
├── ds1302_read_byte.c
└── ds1302_write_byte.c
9.3 硬件连接
sbit DS1302_IO = P3^0;
sbit DS1302_RST = P3^1;
sbit DS1302_SCLK = P3^2;
对应:
| DS1302 | 8051 |
|---|---|
| IO | P3.0 |
| RST | P3.1 |
| SCLK | P3.2 |
采用三线串行通信。
十、DS1302 时间数据
DS1302 使用 BCD 格式保存时间。
时间数组:
time[0] → 秒
time[1] → 分
time[2] → 时
time[3] → 日
time[4] → 月
time[5] → 星期
time[6] → 年
例如:
time[0] = 0x45;
time[1] = 0x30;
time[2] = 0x12;
表示:
12:30:45
十一、DS1302 API
初始化:
void drv_ds1302_init(void);
设置时间:
void drv_ds1302_set_time(unsigned char *time);
读取时间:
void drv_ds1302_read_time(unsigned char *time);
例如:
unsigned char time[7];
drv_ds1302_init();
time[0] = 0x45;
time[1] = 0x30;
time[2] = 0x12;
time[3] = 0x15;
time[4] = 0x01;
time[5] = 0x01;
time[6] = 0x24;
drv_ds1302_set_time(time);
drv_ds1302_read_time(time);
需要注意,驱动返回的数据为 BCD 格式,应用层如果需要十进制数据,需要自行进行转换。
十二、DS18B20 温度传感器
12.1 功能简介
DS18B20 使用 1-Wire 总线进行通信。
当前驱动支持:
-
初始化
-
启动温度转换
-
读取温度
12.2 文件结构
DS18B20/
├── ds18b20_init.c
├── ds18b20_start.c
├── ds18b20_read.c
├── ds18b20_reset.c
├── ds18b20_read_bit.c
├── ds18b20_read_byte.c
└── ds18b20_write_byte.c
12.3 硬件连接
sbit DS18B20_DATA = P3^7;
即:
DS18B20 DATA → P3.7
十三、DS18B20 1-Wire 通信
驱动内部完成:
复位
↓
Presence 检测
↓
Skip ROM
↓
Convert T
↓
读取 Scratchpad
↓
获得温度数据
1-Wire 对时序要求比较严格,因此通信过程中同样需要关闭中断。
十四、DS18B20 API
初始化:
void drv_ds18b20_init(void);
启动转换:
void drv_ds18b20_start(void);
读取温度:
signed int drv_ds18b20_read(void);
返回单位:
0.01°C
例如:
2525 → 25.25°C
-1050 → -10.50°C
典型使用:
#include "HRTOS_Sensor.h"
void main(void)
{
signed int temperature;
drv_ds18b20_init();
while(1)
{
drv_ds18b20_start();
os_delay_ms(750);
temperature = drv_ds18b20_read();
os_delay_ms(1000);
}
}
12 位分辨率下,温度转换时间约为:
750ms
十五、HC-SR04 超声波测距
15.1 功能简介
HC-SR04 通过测量超声波发送与接收之间的时间差实现距离测量。
基本流程:
TRIG
↓
发送超声波
↓
ECHO
↓
测量高电平时间
↓
计算距离
15.2 文件结构
HC-SR04/
├── ultrasonic_init.c
├── ultrasonic_read.c
├── ultrasonic_measure.c
└── ultrasonic_sort.c
15.3 硬件连接
sbit ULTRASONIC_RX = P1^1;
sbit ULTRASONIC_TX = P1^2;
对应:
TRIG → P1.2
ECHO → P1.1
十六、HC-SR04 测距原理
测量过程:
-
TRIG 发送触发脉冲
-
HC-SR04 发射超声波
-
等待 ECHO
-
测量 ECHO 高电平持续时间
-
根据声速计算距离
当前计算基于:
系统时钟:11.0592MHz
8051:12T
一个机器周期约:
1.085us
距离计算采用:
distance = count × 0.1953925
单位:
mm
十七、HC-SR04 API
初始化:
void drv_ultrasonic_init(void);
读取距离:
unsigned int drv_ultrasonic_read(void);
例如:
#include "HRTOS_Sensor.h"
void main(void)
{
unsigned int distance;
drv_ultrasonic_init();
while(1)
{
distance = drv_ultrasonic_read();
// distance 单位:mm
os_delay_ms(100);
}
}
当前一次读取包含:
8 次采样
↓
排序
↓
计算平均值
当前:
DRV_ULTRASONIC_SAMPLE_MAX = 8
DRV_ULTRASONIC_FILTER_COUNT = 0
因此目前实际采用的是 8 次采样平均,并没有删除两端异常数据。
十八、HC-SR04 硬件验证状态
需要特别说明:
HC-SR04 当前暂未完成硬件验证。
当前使用的超声波模块存在硬件问题,因此无法将当前测试现象直接归因于驱动程序。
HC-SR04 驱动对硬件状态比较敏感。
特别是:
TRIG
ECHO
Timer1
三者需要正确配合。
如果 ECHO 信号本身不能正常产生,即使软件测量程序逻辑正确,也无法获得正常距离数据。
因此,本版本不将当前 HC-SR04 标记为“硬件验证通过”。
后续更换正常模块后,再进行完整的:
触发测试
ECHO 波形测试
距离测试
多次采样测试
误差测试
十九、HC-SR501 人体红外
HC-SR501 用于检测人体活动。
当前输入:
sbit DRV_HUMAN_IN = P3^3;
即:
HC-SR501 OUT → P3.3
初始化:
void drv_human_init(void);
读取:
unsigned char drv_human_read(void);
返回:
1 → 检测到人体
0 → 未检测到人体
使用示例:
#include "HRTOS_Sensor.h"
void main(void)
{
drv_human_init();
while(1)
{
if(drv_human_read() == 1)
{
// 检测到人体
}
os_delay_ms(100);
}
}
HC-SR501 本身还具有灵敏度以及延时时间等硬件调节功能。
二十、土壤湿度传感器
土壤湿度模块提供:
AO
DO
两种输出。
其中:
AO → 模拟量
DO → 数字量
当前连接:
AO → P1.0 / ADC_CH0
DO → P1.1
二十一、土壤湿度 API
初始化:
void drv_soil_init(void);
读取模拟量:
unsigned int drv_soil_read_ao(void);
读取数字量:
unsigned char drv_soil_read_do(void);
模拟量返回:
0~1023
数字量由 LM393 比较器输出决定。
阈值可以通过模块上的电位器调节。
需要注意:
当前 AO 返回的是 ADC 原始值,并不是直接的“湿度百分比”。
实际湿度与 ADC 数值之间的对应关系需要根据具体传感器和实际硬件进行标定。
二十二、红外避障传感器
红外避障模块用于检测前方障碍物。
当前引脚:
sbit DRV_IR_IN = P3^2;
API:
void drv_ir_init(void);
unsigned char drv_ir_read(void);
返回:
0 → 检测到障碍物
1 → 未检测到障碍物
典型使用:
#include "HRTOS_Sensor.h"
void main(void)
{
drv_ir_init();
while(1)
{
if(drv_ir_read() == 0)
{
// 检测到障碍物
}
os_delay_ms(100);
}
}
二十三、雨滴传感器 YL-83
YL-83 提供:
AO
DO
两种输出方式。
当前:
sbit DRV_RAINDROP_DO = P3^2;
AO 可以使用 STC12C5A60S2 的 ADC 通道读取。
二十四、雨滴传感器 API
初始化:
void drv_raindrop_init(void);
读取 AO:
unsigned int drv_raindrop_read_ao(unsigned char channel);
读取 DO:
unsigned char drv_raindrop_read_do(void);
ADC 通道:
0~7
返回:
0~1023
DO:
0 → 检测到雨滴
1 → 未检测到雨滴
例如:
unsigned int adc_value;
unsigned char state;
drv_raindrop_init();
adc_value = drv_raindrop_read_ao(0);
state = drv_raindrop_read_do();
需要注意,AO 返回的是 ADC 原始值,并没有转换成实际雨量。
二十五、03_Sensor API 汇总
| 模块 | API | 功能 |
|---|---|---|
| ADC | drv_adc_get_value() | 读取 ADC |
| DHT11 | drv_dht11_init() | 初始化 |
| DHT11 | drv_dht11_read() | 读取温湿度 |
| DS1302 | drv_ds1302_init() | 初始化 |
| DS1302 | drv_ds1302_set_time() | 设置时间 |
| DS1302 | drv_ds1302_read_time() | 读取时间 |
| DS18B20 | drv_ds18b20_init() | 初始化 |
| DS18B20 | drv_ds18b20_start() | 启动温度转换 |
| DS18B20 | drv_ds18b20_read() | 读取温度 |
| HC-SR04 | drv_ultrasonic_init() | 初始化 |
| HC-SR04 | drv_ultrasonic_read() | 读取距离 |
| HC-SR501 | drv_human_init() | 初始化 |
| HC-SR501 | drv_human_read() | 读取人体状态 |
| 土壤湿度 | drv_soil_init() | 初始化 |
| 土壤湿度 | drv_soil_read_ao() | 读取模拟量 |
| 土壤湿度 | drv_soil_read_do() | 读取数字量 |
| 红外 | drv_ir_init() | 初始化 |
| 红外 | drv_ir_read() | 读取避障状态 |
| YL-83 | drv_raindrop_init() | 初始化 |
| YL-83 | drv_raindrop_read_ao() | 读取模拟量 |
| YL-83 | drv_raindrop_read_do() | 读取数字量 |
当前公开接口清单共:
21 个公开 API
此外还有 ADC、DHT11、DS1302、DS18B20、HC-SR04 等模块的内部实现函数。
二十六、驱动开发中的时序与实时性
03_Sensor 与普通 GPIO 驱动相比,一个比较明显的特点就是:
很多传感器驱动对时间非常敏感。
例如:
DHT11
DS18B20
DS1302
HC-SR04
都涉及比较严格的时序控制。
因此部分驱动在执行关键通信过程时会关闭中断。
例如:
DHT11
DS1302
DS18B20
HC-SR04
这也是在 8051 + RTOS 环境中进行驱动开发时需要特别注意的问题。
实时操作系统并不是意味着所有底层操作都可以完全不考虑中断。
对于微秒级时序敏感设备,必要时仍然需要保证通信过程不被其他中断打断。
二十七、源码与接口一致性
当前 03_Sensor 模块已经完成源码整理和接口检查。
主要确认内容包括:
-
HRTOS_Sensor.h中公开 API 与实现文件对应 -
函数名称一致
-
参数类型一致
-
返回值类型一致
-
引脚定义与源码一致
-
相关寄存器定义与实现对应
-
示例代码使用公开 API
-
内部函数已经进行区分
当前各驱动文件覆盖情况:
ADC 3 个文件
DHT11 5 个文件
DS1302 5 个文件
DS18B20 7 个文件
HC-SR04 4 个文件
HC-SR501 2 个文件
土壤湿度 3 个文件
红外 2 个文件
雨滴 YL-83 3 个文件
整个 03_Sensor 模块已经形成了比较完整的源码结构。
二十八、当前需要继续关注的问题
在源码整理过程中,也发现了一些需要后续继续处理或者人工确认的问题。
ADC
当前存在:
drv_adc_init()
实现但没有作为公开 API 声明的问题。
同时 ADC 低位寄存器存在:
ADC_LOW2
ADC_RESL
名称不统一的问题。
DHT11
目前需要进一步完善:
校验失败返回值
错误状态定义
微秒级延时精度
尤其是校验失败后是否应该向应用层明确返回错误状态,需要后续进一步调整。
DS1302
当前初始化主要完成写保护控制。
初始化本身并不会自动设置一个新的默认时间。
因此第一次使用时,需要应用程序主动设置时间。
DS18B20
启动温度转换:
drv_ds18b20_start();
不会一直等待转换完成。
因此应用层需要根据实际分辨率等待转换结束。
12 位分辨率下通常需要约:
750ms
HC-SR04
目前需要重点关注:
ECHO 等待超时
系统时钟适配
滤波参数
当前没有完善的 ECHO 超时机制。
如果传感器没有正常返回 ECHO,测量过程可能长时间等待。
土壤湿度
当前 AO 固定使用:
ADC_CH0
后续如果需要更高的通用性,可以考虑增加 ADC 通道配置。
引脚资源
当前部分传感器存在潜在引脚复用问题。
例如:
红外避障 → P3.2
雨滴 DO → P3.2
因此如果实际项目同时使用两者,需要根据具体硬件修改连接或者重新定义引脚。
二十九、硬件验证与软件验证必须区分
这也是本次 03_Sensor 发布中特别值得说明的一点。
一个驱动模块至少可以从几个层面进行检查:
① 源码检查
② 编译检查
③ 接口检查
④ 逻辑检查
⑤ 实物硬件验证
前面的检查可以证明:
代码结构基本正确
接口基本正确
工程能够编译
但是最终的:
硬件验证
仍然需要真实的传感器和真实的单片机硬件。
特别是:
DHT11
HC-SR04
DS18B20
这种依赖实际波形和通信时序的设备,不能单纯通过代码静态分析替代硬件测试。
所以 HRTOS 4.0 的 03_Sensor 模块会如实记录验证状态。
当前:
DHT11 → 暂未完成硬件验证
HC-SR04 → 暂未完成硬件验证
原因:
当前测试硬件存在问题
后续更换正常硬件后继续验证。
这并不影响当前驱动源码的整理和发布,但在正式标注“硬件验证通过”之前,仍需要完成真实设备测试。
三十、HRTOS 4.0 与 51 单片机传感器开发
对于传统 51 单片机开发来说,一个传感器往往对应一份独立的实验程序。
而在 HRTOS 环境下,可以进一步将这些设备抽象为独立驱动。
例如:
DHT11
↓
drv_dht11_read()
DS18B20
↓
drv_ds18b20_read()
HC-SR04
↓
drv_ultrasonic_read()
HC-SR501
↓
drv_human_read()
土壤湿度
↓
drv_soil_read_ao()
应用程序不需要反复处理底层通信细节。
最终可以形成:
HRTOS Application
↓
Sensor Driver
↓
Hardware / GPIO
↓
51 MCU
这就是从传统的:
51 单片机实验程序
向:
模块化驱动开发
再向:
实时操作系统应用
逐步发展的过程。
三十一、HRTOS Driver Library
03_Sensor 是 HRTOS 4.0 Driver Library 中非常重要的一部分。
它覆盖的设备类型比较多,而且不同设备采用了完全不同的通信方式:
ADC
GPIO
软件时序
1-Wire
三线串行
Timer1
这也使它成为非常典型的 8051 驱动开发实例集合。
对于学习 51 单片机的人来说,可以通过这些驱动看到不同硬件接口的实际实现。
对于已经使用 RTOS 的开发者来说,则可以进一步观察:
驱动
+
任务
+
延时
+
中断
+
硬件资源
之间是如何配合的。
三十二、HRTOS 官方网站
HRTOS 项目的完整资料、开发文档、API、示例以及相关资源,可以通过官方网站查看。
HRTOS 官方网站:
如果你正在学习:
51单片机
8051
嵌入式开发
驱动开发
实时操作系统
RTOS
可以通过官网进一步了解 HRTOS。
三十三、总结
HRTOS 4.0 Driver Library 03_Sensor 目前已经完成了多个典型传感器驱动的源码整理和接口统一。
当前包含:
ADC
DHT11
DS1302
DS18B20
HC-SR04
HC-SR501
土壤湿度
红外避障
YL-83
这些驱动覆盖了模拟采集、数字输入、单总线、串行通信以及定时器测量等多种典型场景。
同时,本版本特别区分:
源码完成
与:
硬件验证完成
这两个不同概念。
其中:
DHT11 和 HC-SR04 由于当前测试硬件存在问题,暂未完成硬件验证。
后续获得正常测试硬件后,将继续进行实物验证。
对于一个长期维护的 51 单片机实时操作系统 项目而言,驱动数量并不是唯一重要的指标。
更加重要的是:
接口是否清晰
代码是否可维护
硬件资源是否明确
时序是否可靠
文档是否完整
测试状态是否真实
HRTOS 4.0 正在沿着这个方向继续完善。
HRTOS —— 面向 8051/51 单片机的实时操作系统。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)