在 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"

通过这种方式,将具体硬件操作与上层应用程序进行一定程度的分离。


二、当前支持的传感器

驱动设备类型
ADCSTC12C5A60S2 内置 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_CH0P1.0
ADC_CH1P1.1
ADC_CH2P1.2
ADC_CH3P1.3
ADC_CH4P1.4
ADC_CH5P1.5
ADC_CH6P1.6
ADC_CH7P1.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;

对应:

DS13028051
IOP3.0
RSTP3.1
SCLKP3.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 测距原理

测量过程:

  1. TRIG 发送触发脉冲

  2. HC-SR04 发射超声波

  3. 等待 ECHO

  4. 测量 ECHO 高电平持续时间

  5. 根据声速计算距离

当前计算基于:

系统时钟: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功能
ADCdrv_adc_get_value()读取 ADC
DHT11drv_dht11_init()初始化
DHT11drv_dht11_read()读取温湿度
DS1302drv_ds1302_init()初始化
DS1302drv_ds1302_set_time()设置时间
DS1302drv_ds1302_read_time()读取时间
DS18B20drv_ds18b20_init()初始化
DS18B20drv_ds18b20_start()启动温度转换
DS18B20drv_ds18b20_read()读取温度
HC-SR04drv_ultrasonic_init()初始化
HC-SR04drv_ultrasonic_read()读取距离
HC-SR501drv_human_init()初始化
HC-SR501drv_human_read()读取人体状态
土壤湿度drv_soil_init()初始化
土壤湿度drv_soil_read_ao()读取模拟量
土壤湿度drv_soil_read_do()读取数字量
红外drv_ir_init()初始化
红外drv_ir_read()读取避障状态
YL-83drv_raindrop_init()初始化
YL-83drv_raindrop_read_ao()读取模拟量
YL-83drv_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 官方网站:

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 单片机的实时操作系统。

访问 HRTOS 官方网站

 

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐