STM32 · Ultrasonic · OLED · Switch LED

STM32F103C8T6 + HC-SR04 + OLED 开关 LED 版本2

这页是第二条 B 站视频对应的新版本:重新分配脚位后,加入开关和三颗 LED。当前代码使用 PA12/PA15 测距,PB6/PB7 给 OLED 模拟小电流供电,PB8/PB9 做 OLED I2C。

SKU O31C8T6 开发板
国产/兼容版本以实物为准
SKU I410.96 寸 I2C OLED
常见 SSD1306 0x3C
SKU H0611HC-SR04 老版本
5V 模块,Echo 要分压
SKU H43HC-SR04 新版本
宽电压 3.3-5V

本页结论

  • 基础版:PA0/PA1 + OLED PB6/PB7,适合先理解原理
  • 视频版:PA12/PA15 + OLED PB8/PB9,另加 PC14 开关和 3 颗 LED
  • OLED:视频版 PB6/PB7 是模拟供电,PB8/PB9 才是 I2C
  • 下载:使用 ST-Link,PlatformIO/STM32duino 工程
  • 串口:CP2102 接 PA9/PA10 看调试信息

SKU Map

这页对应的四个产品

客户买不同套餐时,可能只买其中一部分。排查时先问清楚手里是哪一款 HC-SR04,以及 OLED 是否为 I2C 4 针款。

SKU产品本页用途注意点
O31C8T6 开发板 国产ST主控板按 STM32F103C8T6 兼容开发板处理,具体芯片批次以实物丝印为准。
I410.96 OLED显示测距结果基础版可用 PB6/PB7;视频优化版用 PB8/PB9 做 I2C,PB6/PB7 只模拟小电流供电。
H0611HC-SR04 老版本 5V超声波测距VCC 接 5V;Echo 输出可能是 5V,接 STM32 前要分压到 3.3V 附近。
H43HC-SR04 新版本 宽电压3.3-5V超声波测距可以按宽电压版本处理,3.3V 主控更方便;仍以当前批次丝印/说明为准。

Overview

三样东西总览

这套资料按本地完整说明书重新整理:STM32 负责控制和计算距离,HC-SR04 负责发射/接收超声波,0.96 OLED 只负责显示结果。

STM32F103C8T6

3.3V 主控,常用 BluePill/C8T6 开发板。下载建议用 ST-Link,调试信息可用 CP2102 串口查看。

HC-SR04

Trig 触发,Echo 返回脉宽。老版 5V 模块接 STM32 时,Echo 要先分压,不能直接硬怼 3.3V IO。

SSD1306 OLED

0.96 寸 I2C 屏,常见地址 0x3C。本项目只用它显示距离,OLED 不影响 HC-SR04 本身测距。

Specs

关键参数先看这里

下面保留本地说明书里的核心参数,去掉太长的芯片手册细节,客户排查时先看这些就够用。

STM32F103C8T6

内核ARM Cortex-M3,常见主频 72MHz。
供电/IO芯片工作电压约 2.0-3.6V,开发板 IO 按 3.3V 逻辑处理。
下载本资料使用 ST-Link / SWD 下载,不走串口下载。
串口调试PA9=TX,PA10=RX,接 CP2102 时 TX/RX 要交叉。

HC-SR04

测距范围常见 2cm-400cm,实际受反射面、角度和供电影响。
触发Trig 给 10us 左右高电平脉冲。
回波Echo 高电平宽度对应距离,老版 5V 模块 Echo 要分压。
周期建议 60ms 左右测一次,太快会受上一次回波影响。

0.96 寸 OLED

驱动常见 SSD1306。
接口I2C,只用 SCL/SDA 两根信号线。
地址常见 0x3C,少数为 0x3D。
Adafruit SSD1306 + Adafruit GFX。

Version

H0611 老版和 H43 新版不要混接

H0611:老版本 5V HC-SR04

老版 HC-SR04 一般按 5V 模块使用。STM32F103 是 3.3V 主控,Trig 从 STM32 输出到模块通常没问题,但 Echo 从模块回到 STM32 可能是 5V,高于 STM32 IO 安全电压。

建议:Echo 线加 1k/2k 或类似比例分压,再接 PA1。

H43:新版本宽电压 3.3-5V

新版本按宽电压模块整理,适合 3.3V 主控测试。若客户手上是 H43,可优先尝试 3.3V 供电,Echo 电平更容易和 STM32 匹配。

建议:仍要先看模块丝印和当前批次说明,不要把所有 HC-SR04 都当宽电压。

Wiring

STM32 接线:基础版和视频版不要混用

前面的基础图用于理解 HC-SR04 + OLED 测距;后面 B 站视频和当前下载包对应“优化实录版”,脚位已经改成 PA12/PA15、PB6/PB7 模拟 OLED 供电、PB8/PB9 做 OLED I2C,并增加 PC14 开关和 PA1/PA3/PA4 三颗 LED。

STM32F103C8T6 HC-SR04 OLED 开关 LED 版本2接线图
模块引脚视频版 STM32F103C8T6说明
HC-SR04 VCC5V 或 3.3VH0611 老版按 5V;H43 宽电压可按 3.3V/5V 说明测试。
HC-SR04 GNDGND必须共地。
HC-SR04 TrigPA12视频版代码输出 10us 触发脉冲。
HC-SR04 EchoPA15H0611 老版建议分压后再接 PA15。
OLED GNDPB6GPIO 拉低,当 OLED 地线用;只适合小电流 OLED。
OLED VCCPB7GPIO 拉高,当 OLED 3.3V 用;不能给电机、继电器等大电流外设供电。
OLED SCLPB8代码里使用 Wire.setSCL(PB8)。
OLED SDAPB9代码里使用 Wire.setSDA(PB9),OLED 地址常见 0x3C。
开关PC14 + 3.3V另一端接 3.3V,代码用 INPUT_PULLDOWN,按下为高电平。
LED1 负极PA1LED 正极接 3.3V,GPIO 拉低点亮。
LED2 负极PA3LED 正极接 3.3V,GPIO 拉低点亮。
LED3 负极PA4PA4 没有 PWM 硬件通道,只能全亮/全灭。
CP2102 TXDPA10 / RX串口交叉接线。
CP2102 RXDPA9 / TX串口监视器 115200。
步骤 1:先接电源共地STM32、HC-SR04、OLED、CP2102 的 GND 必须共地。很多“不显示、不测距”其实是地线没接好。
步骤 2:HC-SR04 接 PA12/PA15Trig 接 PA12,Echo 接 PA15。H0611 老版 5V 输出要先用电阻分压后再进 PA15。
步骤 3:OLED 接 PB6-PB9PB6 当 GND,PB7 当 3.3V,PB8 接 SCL,PB9 接 SDA。屏不亮先重插,再扫地址。
步骤 4:开关和 LED 按视频版开关接 PC14 和 3.3V;三颗 LED 正极接 3.3V,负极分别接 PA1、PA3、PA4。
步骤 5:串口只用于看日志CP2102 TX 接 PA10,RX 接 PA9,GND 共地,波特率 115200。

Download

下载 STM32 OLED 开关 LED 版本2程序

这个包是 PlatformIO + STM32duino 工程,包含 `platformio.ini` 和 `src/main.cpp`。客户下载后解压整个文件夹,不要只复制单个 cpp。

STM32 + OLED + 开关 LED 优化工程

适合后面 B 站视频对应的优化版:Trig=PA12,Echo=PA15,OLED PB6/PB7 模拟供电,PB8/PB9 是 I2C,PC14 接开关,PA1/PA3/PA4 接三颗 LED。

下载版本2工程 ZIP

下载后怎么用

  1. 解压 ZIP,保留整个工程文件夹。
  2. 用 VS Code 打开文件夹,安装 PlatformIO 插件。
  3. 接好 ST-Link,确认 BOOT0=0。
  4. 点击 PlatformIO Upload 下载程序。
  5. 打开串口监视器,波特率 115200,看距离输出。

工程文件结构

hcsr04_stm32_bluepill_oled/
├─ platformio.ini
└─ src/
   └─ main.cpp

客户最容易错在只复制 main.cpp。PlatformIO 工程要整个文件夹一起打开,库依赖和开发板配置都在 platformio.ini 里。

Demo

实拍 OLED 测距演示

Debug Record

开关和 3 颗 LED 调试实录

这段是实际调试录像整理版,对应当前下载包的优化实录版脚位:PA12/PA15 测距,PB6/PB7 给 OLED 模拟供电,PB8/PB9 做 OLED I2C,PC14 接开关,PA1/PA3/PA4 接 LED。

这段视频适合看什么

  • 看真实改线、改代码、复测的流程。
  • 看 OLED、开关和 LED 挤在同一排排针时,为什么要重新分配引脚。
  • 看问题不是直接判断模块坏,而是先查接线、极性和程序引脚。

实际遇到的坑

  • OLED 黑屏:最后发现是模块没有插紧,先重插再怀疑程序。
  • LED 只亮一颗:其中一颗 LED 极性接反,调试时要看正负极。
  • PA4 不带硬件 PWM:这类引脚不能直接拿来做亮度渐变。

给客户的判断方法

如果客户说“屏不亮、灯不亮、没有反应”,先让客户发清晰接线图和串口输出。按供电共地、模块是否插紧、LED 极性、代码引脚是否一致这几个点排查,比直接换模块更快。

Code

关键代码说明

下面保留完整工程里的关键文件内容,客户如果不会改代码,可以先不要改引脚,按图接线测试。

#define TRIG_PIN PA12
#define ECHO_PIN PA15
#define CAL_FACTOR (20.0 / 18.2)

#define OLED_FAKE_GND_PIN PB6
#define OLED_FAKE_VCC_PIN PB7
#define OLED_SCL_PIN PB8
#define OLED_SDA_PIN PB9

#define SWITCH_PIN PC14
#define LED1_PIN PA1
#define LED2_PIN PA3
#define LED3_PIN PA4

HardwareSerial DebugSerial(PA10, PA9); // RX, TX
Adafruit_SSD1306 display(128, 64, &Wire, -1);

// OLED I2C: SCL=PB8, SDA=PB9
// PB6/PB7 只是给 OLED 模拟小电流供电
[env:bluepill_f103c8]
platform = ststm32
board = bluepill_f103c8
framework = arduino
upload_protocol = stlink
monitor_speed = 115200
lib_deps =
    adafruit/Adafruit SSD1306@^2.5.13
    adafruit/Adafruit GFX Library@^1.11.11

main.cpp 关键片段

// 当前下载包和 B 站视频对应:优化实录版
// Trig=PA12, Echo=PA15
// OLED: PB6=模拟GND, PB7=模拟3.3V, SCL=PB8, SDA=PB9
// Switch=PC14, LED=PA1/PA3/PA4
// Serial monitor: CP2102 TX->PA10, RX->PA9, 115200

#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define TRIG_PIN PA12
#define ECHO_PIN PA15
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define CAL_FACTOR (20.0 / 18.2)

#define OLED_FAKE_GND_PIN PB6
#define OLED_FAKE_VCC_PIN PB7
#define OLED_SCL_PIN PB8
#define OLED_SDA_PIN PB9

#define SWITCH_PIN PC14
#define LED1_PIN PA1
#define LED2_PIN PA3
#define LED3_PIN PA4

HardwareSerial DebugSerial(PA10, PA9); // RX, TX
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

float getDistanceCM() {
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);

  unsigned long duration = pulseIn(ECHO_PIN, HIGH, 30000);
  if (duration == 0) return -1;
  return (duration / 58.0) * CAL_FACTOR;
}

void setup() {
  DebugSerial.begin(115200);
  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);
  digitalWrite(TRIG_PIN, LOW);

  pinMode(SWITCH_PIN, INPUT_PULLDOWN);
  pinMode(LED1_PIN, OUTPUT);
  pinMode(LED2_PIN, OUTPUT);
  pinMode(LED3_PIN, OUTPUT);
  digitalWrite(LED1_PIN, HIGH); // LED 正极接 3.3V,GPIO 高电平=灭
  digitalWrite(LED2_PIN, HIGH);
  digitalWrite(LED3_PIN, HIGH);

  pinMode(OLED_FAKE_GND_PIN, OUTPUT);
  digitalWrite(OLED_FAKE_GND_PIN, LOW);
  pinMode(OLED_FAKE_VCC_PIN, OUTPUT);
  digitalWrite(OLED_FAKE_VCC_PIN, HIGH);
  delay(10);

  Wire.setSCL(OLED_SCL_PIN);
  Wire.setSDA(OLED_SDA_PIN);
  Wire.begin();
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
}

void loop() {
  static bool lastSwitchOn = false;
  static int activeLed = 0;

  bool switchOn = digitalRead(SWITCH_PIN) == HIGH;
  if (switchOn && !lastSwitchOn) {
    activeLed = (activeLed + 1) % 3;
  }
  lastSwitchOn = switchOn;

  digitalWrite(LED1_PIN, activeLed == 0 ? LOW : HIGH);
  digitalWrite(LED2_PIN, activeLed == 1 ? LOW : HIGH);
  digitalWrite(LED3_PIN, activeLed == 2 ? LOW : HIGH); // PA4 只能全亮/全灭

  float cm = getDistanceCM();
  DebugSerial.println(cm);

  // 完整 OLED 显示、小猫动画和 LED 调暗逻辑请下载 ZIP 工程查看。
  delay(300);
}

FAQ

常见问题

H0611 老版 HC-SR04 能不能直接接 STM32?

VCC 可以按老版 5V 模块供电,但 Echo 不建议直接进 STM32。老版 Echo 可能输出 5V,STM32F103 IO 是 3.3V 电平,基础版建议分压后接 PA1;当前视频优化版建议分压后接 PA15。

H43 宽电压新版为什么更适合 3.3V 主控?

H43 按宽电压 3.3-5V 版本整理,客户使用 STM32、ESP32 等 3.3V 主控时更方便,供电和 Echo 电平更容易匹配。但仍要以实际批次丝印和说明为准。

OLED 不显示怎么办?

先扫 I2C 地址,常见是 0x3C。基础版确认 PB6=SCL、PB7=SDA;当前视频优化版确认 PB6 拉低当 GND、PB7 拉高当 3.3V、PB8=SCL、PB9=SDA,并确认 OLED 模块插紧。

下载不进去怎么办?

先看 ST-Link 接线:3.3V、GND、SWDIO、SWCLK。BOOT0 正常运行用 0。若芯片识别不到,先确认开发板供电和 ST-Link 驱动。

串口没有输出怎么办?

CP2102 TXD 接 STM32 PA10,CP2102 RXD 接 STM32 PA9,GND 共地,串口监视器波特率 115200。

Customer Reply

淘宝客户简短话术

您好,这套 STM32F103C8T6 + HC-SR04 + 0.96 OLED 测距资料已经整理好。页面里分了基础版和视频优化版:基础版用于理解原理;当前下载包/视频版是 Trig=PA12、Echo=PA15,OLED 的 PB6/PB7 是模拟供电,PB8/PB9 才是 I2C,PC14 接开关,PA1/PA3/PA4 接三颗 LED。老版 H0611 的 Echo 建议分压后再接 STM32;程序请下载完整 ZIP 工程,不要只复制单个 cpp 文件。