上一站:嵌入式转型的五个阶段(总览) 这一篇:只做 S0 —— 硬件零基础破冰。 写给谁:能 SSH 登录、能改配置文件、能看日志,但从没接过一根杜邦线的人。 耗时:一周,每天 1–2 小时。


为什么 S0 不能跳

先说结论:没有硬件的嵌入式学习,100% 会半途而废。

不是意志力问题,是反馈回路断了。写 C 语言,编译过了没有报错,你并不知道自己写对没有;但灯亮了,这一下大脑立刻给多巴胺。学 C 的痛苦,只有被"灯亮了"抵消掉才扛得住。

S0 只干一件事:建立这条因果链的第一个闭环。

你敲一条命令 ──▶ 引脚电平变 ──▶ 电路通 ──▶ 灯亮

这条链一旦通了,后面所有的协议、并发、多节点,都只是在这条链上加点东西。


一、先买对东西(别一次买全)

最小起步约 ¥620–1,100。清单:

#器件规格参考价作用能不能省
1树莓派Pi 5 4GB / Pi 4B 2GB¥500–850主角不能
2microSD32GB Class10 A1/A2¥30–45系统盘不能
3读卡器microSD 读卡器¥10–15烧系统不能
4电源Pi 5 官方 27W USB-C / Pi 4B 5V3A¥40–90供电别省
5面包板830 孔¥5–10免焊接线不能
6LED + 电阻红/绿 LED 各 5 个、220Ω×10¥5–10你的第一个负载不能
7杜邦线公对母 20 根¥8–15连接不能
8继电器模块5V 单路,低电平触发 + 光耦隔离¥8–15S1 才用这次可以不买

⚠️ 省钱的唯一正确姿势:先买 1–7,灯亮了再买 8。 ⚠️ 最不该省的是第 4 项。供电不足会表现成各种玄学故障——随机重启、USB 掉线、Wi-Fi 断流,你会花三天以为是系统问题。

选 Pi 5 还是 Pi 4B

Pi 5Pi 4B
GPIO 电流能力一样(3.3V / 单脚 16mA)一样
性能强很多(编译 C 快一倍以上)够用
发热热,必须带主动散热温
价格高低

只做 S0/S1 的网关,Pi 4B 2GB 完全够。 但如果打算后面做交叉编译、跑 Docker,Pi 5 省下来的等待时间值这个钱。


二、只用一条公式:欧姆定律

V = I × R,变形:

R = (V电源 − V负载) / I目标

LED 为什么要串电阻?因为LED 不是电阻,它的伏安特性几乎是垂直的——电压稍微高一点,电流就暴涨,然后烧掉。电阻的作用是把电流摁住。

算一遍(红灯):

  • 电源:GPIO 输出 3.3V
  • 红灯正向压降:约 1.8–2.0V
  • 想让它亮得舒服又不伤引脚:6mA 左右
R = (3.3 − 2.0) / 0.006 ≈ 217Ω

取标准值 220Ω,实际电流约 5.9mA —— 安全(单脚上限 16mA)。

换颜色要不要换电阻

要。 正向压降不一样:

颜色正向压降220Ω 下电流结论
红≈1.8–2.0V≈6mA合适
黄/绿≈2.0–2.2V≈5mA合适
蓝/白≈3.0–3.2V≈1mA偏暗,要换 100Ω

⚠️ 蓝白 LED 用 220Ω 会觉得"是不是没接对",其实是电流太小。

这条是 S0 唯一必须真正理解的物理。后面所有"为什么带不动电机"“为什么要继电器”,都是同一件事的不同规模。


三、接线:三个连接,别接错

树莓派 40 针脚(Pi 5 与 Pi 4 物理完全一致,BCM 编号也一致)。这次只用三个:

物理引脚名称接到哪
Pin 11GPIO17220Ω 电阻一端
Pin 6GNDLED 负极(短脚)
—Pin 1 / 173.3V(这次不用)
   Pin 11 (GPIO17) ──[ 220Ω ]──▶|── Pin 6 (GND)
                                LED
                            (长脚进,短脚出)

要点:

  1. LED 有极性:长脚是正极(阳极),短脚是负极。反接不亮,但不会烧,翻过来就行。
  2. 电阻串在任意一端都行(正极侧或负极侧),效果一样。
  3. 别用 5V 引脚(Pin 2 / 4)。GPIO 是 3.3V 器件,5V 灌进 GPIO 会烧 SoC。
  4. 接线前先断电(拔掉电源)。这条规矩从今天开始,一辈子有效。

面包板怎么通电

面包板中间那条凹槽把上下两半分开了,两边不导通。上下各有一条带红蓝标记的"电源轨":

  • 红线整条连通,蓝线整条连通
  • 但上半区的红线和下半区的红线不连通
  • 每个"孔列"(5 个孔一排)内部连通,跨凹槽不连通

本次只用杜邦线直连,可以完全不碰电源轨——初学最省事的做法就是少用面包板。

🔴 安全红线(贯穿整个嵌入式路线):只碰 5V / 12V 低压直流。 市电(220V)设备一律用成品智能插座替代。断电再接线。大功率负载必须经继电器或 MOSFET,GPIO 绝不直接驱动任何电机/灯泡/加热丝。


四、点亮它:三种方式,从最低层到最省事

方式 A:命令行 pinctrl(最快,一行搞定)

树莓派 OS(Bookworm 及以后)自带 pinctrl:

pinctrl get 17          # 看当前状态
# 17: ip    -- | lo // GPIO17 = input

pinctrl set 17 op dh    # 设为输出,驱动高电平 → 灯亮
pinctrl set 17 op dl    # 驱动低电平 → 灯灭

看到 pinctrl get 17 变成 17: op -- -- | hi 就是成功了。

先确认 header 在哪个 chip 上:gpiodetect Pi 5 新内核(6.6.45 之后)的 40 针脚在 gpiochip0(pinctrl-rp1);早期 Pi 5 镜像在 gpiochip4,现在 gpiochip4 只作兼容别名保留。

方式 B:Python gpiozero(最直观,适合先跑通)

from gpiozero import LED
from time import sleep

led = LED(17)
for _ in range(5):
    led.on();  sleep(0.5)
    led.off(); sleep(0.5)
sudo apt install -y python3-gpiozero
python3 blink.py

方式 C:C + libgpiod(你最终要用的)

// blink.c — 编译: gcc -O2 -Wall -o blink blink.c -lgpiod
#include <gpiod.h>
#include <stdio.h>
#include <unistd.h>

int main(void)
{
    struct gpiod_chip *chip = gpiod_chip_open_by_name("gpiochip0");
    if (!chip) { perror("open chip"); return 1; }

    struct gpiod_line *line = gpiod_chip_get_line(chip, 17);
    if (!line) { perror("get line"); gpiod_chip_close(chip); return 1; }

    if (gpiod_line_request_output(line, "blink", 0) < 0) {
        perror("request output"); gpiod_chip_close(chip); return 1;
    }

    for (int i = 0; i < 5; i++) {
        gpiod_line_set_value(line, 1);
        printf("LED ON\n");
        fflush(stdout);
        sleep(1);
        gpiod_line_set_value(line, 0);
        printf("LED OFF\n");
        fflush(stdout);
        sleep(1);
    }

    gpiod_line_release(line);      /* 归还引脚 */
    gpiod_chip_close(chip);
    return 0;
}
sudo apt install -y libgpiod-dev
gcc -O2 -Wall -o blink blink.c -lgpiod && ./blink

三个 API 版本差异:libgpiod 1.x 用 gpiod_chip_open_by_name / gpiod_line_request_output;2.x 改成了 gpiod_chip_open + gpiod_line_request 结构体风格。上面是 1.x(Raspberry Pi OS 当前仓库版本)。如果编译报 implicit declaration,先 pkg-config --modversion libgpiod 看版本。

为什么必须走一遍 C:pinctrl 和 gpiozero 都是别人包装好的,你不知道底下发生了什么。用 C 写一次 open chip → get line → request output → set value → release,你就明白了:GPIO 在 Linux 里就是一个可以被"申请"的资源,和打开一个文件没本质区别。

这句话是整条嵌入式路线的地基。


五、SSH 远程点灯(这一步才算真的"控制")

把上面任何一个程序放到树莓派上,从你的笔记本执行:

ssh pi@raspberrypi.local 'pinctrl set 17 op dh'    # 灯亮
ssh pi@raspberrypi.local 'pinctrl set 17 op dl'    # 灯灭

这一刻的意义:你人在另一个房间,通过一条网络连接,让一个物理器件状态改变了。

这就是"物联网"的全部本质。 后面 S1 的网页开关灯、S3 的多节点协同,都是这一条命令的包装。


六、五个必踩的坑

症状原因怎么修
灯完全不亮LED 反接 / 电阻没插实翻 LED;把元件按到底
灯很暗蓝/白 LED + 220Ω,电流不够换 100Ω,或换红色 LED
pinctrl: command not found老系统(Bullseye 之前)用 raspi-gpio set 17 op dh,或升级系统
gpiod_chip_open: No such filechip 名不对gpiodetect 看实际名字,Pi 5 早期镜像是 gpiochip4
程序退出后灯还亮着没 gpiod_line_release这是 RAII 要解决的问题,S1 会讲
树莓派随机重启供电不足换官方电源,别用手机充电器

七、过门标准(四条,缺一条不算过)

  1. ✅ 独立烧录系统(不让别人帮你点鼠标)
  2. ✅ 点亮一个 LED
  3. ✅ SSH 登录,用命令行控制它亮灭
  4. ✅ 能回答这两个问题:
    • 为什么 LED 要串 220Ω,不能直接接 3.3V?
    • 换成蓝色 LED,电阻要变大还是变小?为什么?

第 4 项是重点。能算出来,说明你懂了;只会照抄接线图,等于没学。


八、下一步

S0 通过之后,S1 是「用 C 重写一个网关」,周期 4–6 周,最终产出网页点按钮 → 继电器"咔"一声。

到那时你会用到今天买的继电器模块(所以它列在清单里但可以先不买)。

同时补两块地基:

  • 电学基础:先回看本篇第二节的欧姆定律,再找一本直流电路入门书放在手边——只查不读,遇到"这个电阻多大"才去翻
  • C 语言:指针、结构体内存布局、snprintf、函数指针。函数指针是 C 里唯一的"多态",MCU 的驱动框架全靠它

附:这次的最小行动清单

今天:下单 1–7 项
第 1 天:烧系统 → 能 SSH 登录
第 2 天:接 LED + 电阻 → pinctrl 点亮
第 3 天:算电阻 → 换三种颜色验证
第 4 天:gpiozero 跑 blink.py
第 5 天:用 C + libgpiod 重写 blink.c
第 6 天:SSH 从笔记本点灯
第 7 天:回答过门问题,拍照存档

七天之后,你就不是"没碰过硬件的人"了。


最后更新:2026-10-24 · 下一篇:S1 用 C 重写网关(预告)