STM32 与 E18-D80NK:红外光电开关的实验手记

嵌入式实验里有一类元器件不起眼却极其常见——光电开关。它没有复杂协议,一根信号线就能告诉单片机"前面有没有东西"。这篇博客记录我用 STM32L431 驱动 E18-D80NK 红外光电开关的完整过程:从数据手册里的接线和电平逻辑,到代码里的轮询与状态打印,再到实验中那些值得记住的细节。

01 认识 E18-D80NK:一根黑线输出的"开关"
E18-D80NK 是一款 NPN 常开型红外光电开关,外壳是黑色圆柱,前端带透明透镜,尾部引出三根线:棕色接电源正极(+5V)、蓝色接地、黑色是输出端(OUT)。它内部集成了红外发射管、接收管和信号处理电路,检测距离 3~80cm,可以通过后盖电位器旋钮调节。

它的输出本质是一个集电极开路(Open Collector)信号,相当于一个开关管:要么导通把输出拉低,要么截止让输出悬空。要让单片机读到稳定的电平,输出端必须接一个上拉电阻。本实验没有外接电阻,而是直接使用单片机 GPIO 的内部上拉,同样等效。

02 先看数据手册:三根线怎么接
实验前先核对数据手册,接线方式一目了然:Brown=5VDC,Blue=GND,Black=OUT,输出为 TTL 电平,0 对应 GND、1 对应 5V。手册还特别提示,Open Collector 输出需要接 10K 上拉电阻才能正常读取。

未能显示图片

图1:数据手册第1页——三线制接线方式、Open Collector 需 10K 上拉、TTL 电平定义

对照本实验的电路,传感器黑色输出线接在 PB0 引脚,代码里把 PB0 配置为输入模式并打开内部上拉,就满足了手册对上拉的要求。

03 距离与电平:什么时候输出 0,什么时候输出 1
数据手册第2页给出了最关键的判定逻辑:当障碍物距离小于等于探测距离时,输出为 0(指示灯亮);当障碍物距离大于等于探测距离时,输出为 1(指示灯灭)。这意味着我们只要读一次电平,就能判断"前方是否有物体遮挡"。

未能显示图片

图2:数据手册第2页——距离≤探测距离时 OUTPUT=0、LED 亮;距离≥探测距离时 OUTPUT=1、LED 灭

实验时用手在传感器前晃动,就能看到指示灯随遮挡与否亮灭,输出电平也随之在 0 和 1 之间切换。

04 代码实现:轮询、上拉与"状态变化才打印"
程序分两步:先初始化 GPIO,再在主循环里周期性地读取电平。GPIO 配置的关键是把 PB0 设为输入并打开内部上拉:

C
复制
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
检测逻辑放在 Infrared_Switch_Handle() 函数里,每 1000ms 轮询一次。为了串口输出更直观,我改成了"状态变化才打印中文",而不是一直输出 0/1:有遮挡时打印"有遮挡"、点亮彩色图标并让蜂鸣器响,无遮挡时打印"无遮挡"、恢复灰色图标并关闭蜂鸣器,同时 LED1 每秒翻转一次作为系统心跳。

C
复制
void Infrared_Switch_Handle(void)
{
static uint32_t last_tick = 0;
static uint8_t last_state = 0xFF;
if (HAL_GetTick() - last_tick < 1000) return;
last_tick = HAL_GetTick();

uint8_t cur = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0);
if (cur != last_state) {            // 状态变化才打印一次
    if (cur == 0) {                 // 低电平 = 有遮挡
        printf("有遮挡\r\n");
        LCD_Show_Icon(COLORED);
        Buzzer_On();
    } else {                        // 高电平 = 无遮挡
        printf("无遮挡\r\n");
        LCD_Show_Icon(GRAY);
        Buzzer_Off();
    }
    last_state = cur;
}
LED1_Toggle();                      // 每秒翻转,系统心跳

}
串口配置在 uart2、波特率 115200,打开串口助手就能实时看到"有遮挡/无遮挡"的状态切换,比看一串 0/1 直观得多。

05 实验现象:看得见、听得见的变化
上电后传感器指示灯常亮或常灭取决于初始遮挡情况。手靠近传感器(小于探测距离)时:指示灯亮起、LCD 显示"有遮挡"彩色图标、蜂鸣器鸣叫、串口打印一次"有遮挡";手移开(大于探测距离)时:指示灯熄灭、LCD 恢复灰色图标、蜂鸣器停止、串口打印一次"无遮挡"。整个过程响应及时,没有误触发。

把电位器从最小往大调,可以明显感受到探测距离变远;这也验证了"3~80cm 可调"的手册说明。

06 总结与踩坑
这次实验有三点收获:第一,读手册比猜接线靠谱,Open Collector 输出必须配合上拉才能被 GPIO 正确识别;第二,电平逻辑要对应传感器型号,NPN 常开型是"有遮挡输出 0、无遮挡输出 1",与"常闭/高有效"器件正好相反;第三,调试输出要为人服务,串口打印中文状态比打印 0/1 更容易观察。

可以继续扩展的方向也不少:把遮挡次数统计成计数,用于流水线计数或停车位检测;把状态通过串口上报给上位机或云平台,做成远程告警;也可以换成对射型光电开关,体验不同的安装方式。光电开关虽然简单,却是很多物联网应用里最可靠的那一环。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐