数字量输入传感器 · STM32F103C8T6 演示

本演示基于 STM32F103C8T6 实现 PB0 数字量读取与 OLED 显示。 介绍 8 种常见数字量传感器的原理与功能,并对示例工程的关键代码与运行流程进行分析。

MCU:STM32F103C8T6 主频:72 MHz 输入引脚:PB0 OLED:SSD1306 · 软件 I²C 底板芯片:LM393 轮询周期:50 ms
传感器数量
8 种
输出类型
数字量 0 / 1
底板核心
LM393
轮询周期
50 ms

数字量传感器通用架构

大多数数字量传感器采用「传感器探头 + 底板(转接板)」设计,底板上的 LM393 电压比较器是核心——将模拟信号转换为干净的 0/1 数字电平。

传感器探头 PIR / Hall IR / 光敏… 输出模拟信号 (电压随物理量变化) 模拟 底板(转接板) LM393 双电压比较器 电位器 阈值调节 上拉电阻 电源 LED 输出 LED Vref OUT (0/1) VCC · GND · OUT STM32 PB0

LM393 双电压比较器

底板上的 LM393 是一颗内含两个独立比较器的芯片。它将传感器探头输出的模拟信号与电位器设定的参考电压 (Vref) 进行比较:

• 传感器信号 > Vref → 比较器输出一种电平
• 传感器信号 < Vref → 比较器输出另一种电平

输出为开漏 (OC) 结构,经上拉电阻后得到干净的 0/1 数字信号。

底板上的其他元件

电位器 — 调节比较阈值,即灵敏度旋钮
LED 指示灯 — 电源指示 + 输出状态指示
上拉电阻 — 确保 OC 输出有确定高电平
3-pin 接口 — VCC / GND / OUT,即插即用

VCC 3.3~5VGNDOUT (DO)AO (可选)

为什么这种架构如此常见?

无论探头是热释电 (PIR)、霍尔 (Hall)、红外 (IR)、光敏还是电容式,底板都能统一输出 0/1 数字信号。 MCU 只需读取一个 GPIO 引脚即可获取检测结果,极大简化了硬件设计与软件开发。

系统框架图

本演示工程仅启用 PB0 一个 GPIO 输入与 0.96 寸 OLED(软件 I²C)显示;8 种数字量传感器作为原理讲解,并不同时接入。PB0 的电平由外接传感器的 OUT/SIGNAL 引脚提供,0/1 经 OLED 实时显示。

8 种数字量传感器 (任选其一接入) 人体红外 D203S 霍尔开关 3144E 红外循迹 TCRT5000 火焰传感器 Flyming 红外对射 FC-33 红外避障 TCRT5000 震动传感器 SW-420 非接触水位 DICS-D STM32F103C8T6 Cortex-M3 · 72 MHz · LQFP48 PB0 GPIO_IN ← 传感器 OUT PB14 SDA → OLED PB15 SCL → OLED 轮询读取 · 50 ms 周期 OLED_CenterPrintf(24,"输入:%d",Read) 0.96" OLED (SSD1306) 128×64 · 软件 I²C · 0x78 输入:0 SDA ← PB14 SCL ← PB15 地址 0x78 · 8 位写模式 OUT (0/1) SDA SCL 传感器 OUT → PB0 → GPIO_ReadPin → OLED_Printf → 软件 I²C 写显存

八种数字量传感器 · 原理 & 功能

每张卡片包含实物图、工作原理、输出逻辑、典型应用。8 种传感器均采用上述底板+LM393 架构,输出统一的 0/1 数字信号。

原理图 & PCB 封装

演示工程的电路原理图设计与 PCB 封装展示。

● 原理图
原理图
原理图
● PCB 封装
PCB封装
PCB 封装

程序分析

核心代码位于 main.c 与 OLED.c,使用 STM32CubeMX 生成工程骨架,Keil MDK-ARM 编译。

main.c · main loop
int main(void)
{
  HAL_Init();                // 1. 初始化、配置 SysTick 1ms
  SystemClock_Config();      // 2. HSE 8MHz ×9 PLL → 72MHz
  MX_GPIO_Init();            // 3. 配置 PB0 为浮空输入
  OLED_Init();              // 4. 软件 I²C 初始化 + SSD1306

  while (1)                 // 5. 主循环
  {
    if (HAL_GetTick() - Time_Now >= 50)  // 每 50ms 刷新
    {
      OLED_Clear();                            // 清显存
      OLED_CenterPrintf(24, "输入:%d",
        HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0));    // 读 PB0
      OLED_Update();                           // I²C 推送显存
      Time_Now = HAL_GetTick();                      // 记录时间戳
    }
  }
}
关键点:程序只使用了 1 个 GPIO 输入(PB0)和 1 个软件 I²C 总线(PB14/PB15)。 之所以选用"软件 I²C"是因为 OLED 仅作为低速显示外设,不占用硬件 I²C 外设。
PB0 输入模式:GPIO_NOPULL, 表示不启用内部上/下拉,由外部传感器驱动电平:OUT 推挽 → 直接读;OC/OD 输出 → 必须外接上拉电阻。 实际很多模块(霍尔、循迹、避障等)板载已上拉。
HAL_GPIO_ReadPin 返回值:GPIO_PIN_SET=1 / GPIO_PIN_RESET=0, 通过 %d 格式化为 0 或 1 显示在 OLED 上。

系统流程图

从系统启动到主循环的完整数据流。初始化阶段(1~5)播放一次后,while(1) 循环(6→7→8)会持续播放,体现程序的无限循环逻辑。点击「重新播放」可从头开始。

上电 / Reset HAL_Init() SysTick = 1 ms SystemClock_Config() HSE 8M ×9 → SYSCLK 72 MHz MX_GPIO_Init() PB0 浮空输入 OLED_Init() PB14/15 软件 I²C · SSD1306 while(1) 主循环 Δt ≥ 50ms ? HAL_GetTick 差值 Read PB0 + OLED 更新 Clear → Printf → Update 是 否
当前激活 未激活 顺序流 分支/条件

总结 & 扩展方向

本演示以最简方式展示了 8 种传感器的"是/否"信号如何被 STM32 采集并显示。要扩展成实际项目,可以从下面几个方向入手。

中断

改用外部中断

信号源
EXTI0 → PB0
优点
不轮询、响应快
典型场景
人体红外/震动报警
多路

多路传感器轮询

信号源
PB0~PB7 8 路
显示
OLED 列表 0/1
典型场景
安防状态面板
通信

上报上位机

协议
USART / 蓝牙
优点
远程监控
典型场景
无线报警节点
动作

联动控制

输入
任意传感器
输出
继电器/电机/蜂鸣器
典型场景
循迹/避障/计数小车
数字量输入传感器演示 · STM32F103C8T6 · 仅用于教学说明