STM32 学习笔记:GPIO 输出原理与硬件设计

STM32 学习笔记:GPIO 输出原理与硬件设计

对应课程:[3-1] GPIO 输出(本次录音为理论与硬件设计部分)

课堂录音:2026-08-30 12_59 GPIO输出_原文.docx

整理日期:2026-08-30

芯片:STM32F103C8T6

资料补全:老师 PPT、师兄笔记、STM32F10xxx 参考手册、STM32F103x8/B 数据手册

本节边界:老师在本段录音中讲到面包板原理,实际接线和程序放在下一小节

1. 先抓住老师的整条思路

老师没有一上来就写代码,而是先展示三个程序现象,再从芯片内部一路讲到外部电路:
#mermaid-svg-E7JKNea9xJi5AZxm{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-E7JKNea9xJi5AZxm .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-E7JKNea9xJi5AZxm .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-E7JKNea9xJi5AZxm .error-icon{fill:#552222;}#mermaid-svg-E7JKNea9xJi5AZxm .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-E7JKNea9xJi5AZxm .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-E7JKNea9xJi5AZxm .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-E7JKNea9xJi5AZxm .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-E7JKNea9xJi5AZxm .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-E7JKNea9xJi5AZxm .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-E7JKNea9xJi5AZxm .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-E7JKNea9xJi5AZxm .marker{fill:#333333;stroke:#333333;}#mermaid-svg-E7JKNea9xJi5AZxm .marker.cross{stroke:#333333;}#mermaid-svg-E7JKNea9xJi5AZxm svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-E7JKNea9xJi5AZxm p{margin:0;}#mermaid-svg-E7JKNea9xJi5AZxm .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-E7JKNea9xJi5AZxm .cluster-label text{fill:#333;}#mermaid-svg-E7JKNea9xJi5AZxm .cluster-label span{color:#333;}#mermaid-svg-E7JKNea9xJi5AZxm .cluster-label span p{background-color:transparent;}#mermaid-svg-E7JKNea9xJi5AZxm .label text,#mermaid-svg-E7JKNea9xJi5AZxm span{fill:#333;color:#333;}#mermaid-svg-E7JKNea9xJi5AZxm .node rect,#mermaid-svg-E7JKNea9xJi5AZxm .node circle,#mermaid-svg-E7JKNea9xJi5AZxm .node ellipse,#mermaid-svg-E7JKNea9xJi5AZxm .node polygon,#mermaid-svg-E7JKNea9xJi5AZxm .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-E7JKNea9xJi5AZxm .rough-node .label text,#mermaid-svg-E7JKNea9xJi5AZxm .node .label text,#mermaid-svg-E7JKNea9xJi5AZxm .image-shape .label,#mermaid-svg-E7JKNea9xJi5AZxm .icon-shape .label{text-anchor:middle;}#mermaid-svg-E7JKNea9xJi5AZxm .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-E7JKNea9xJi5AZxm .rough-node .label,#mermaid-svg-E7JKNea9xJi5AZxm .node .label,#mermaid-svg-E7JKNea9xJi5AZxm .image-shape .label,#mermaid-svg-E7JKNea9xJi5AZxm .icon-shape .label{text-align:center;}#mermaid-svg-E7JKNea9xJi5AZxm .node.clickable{cursor:pointer;}#mermaid-svg-E7JKNea9xJi5AZxm .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-E7JKNea9xJi5AZxm .arrowheadPath{fill:#333333;}#mermaid-svg-E7JKNea9xJi5AZxm .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-E7JKNea9xJi5AZxm .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-E7JKNea9xJi5AZxm .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-E7JKNea9xJi5AZxm .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-E7JKNea9xJi5AZxm .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-E7JKNea9xJi5AZxm .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-E7JKNea9xJi5AZxm .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-E7JKNea9xJi5AZxm .cluster text{fill:#333;}#mermaid-svg-E7JKNea9xJi5AZxm .cluster span{color:#333;}#mermaid-svg-E7JKNea9xJi5AZxm div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-E7JKNea9xJi5AZxm .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-E7JKNea9xJi5AZxm rect.text{fill:none;stroke-width:0;}#mermaid-svg-E7JKNea9xJi5AZxm .icon-shape,#mermaid-svg-E7JKNea9xJi5AZxm .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-E7JKNea9xJi5AZxm .icon-shape p,#mermaid-svg-E7JKNea9xJi5AZxm .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-E7JKNea9xJi5AZxm .icon-shape .label rect,#mermaid-svg-E7JKNea9xJi5AZxm .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-E7JKNea9xJi5AZxm .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-E7JKNea9xJi5AZxm .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-E7JKNea9xJi5AZxm :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 观察现象

LED闪烁、流水灯、蜂鸣器
认识GPIO

能输入也能输出
看整体结构

端口、寄存器、驱动器
看单个引脚结构

输入通道与输出通道
理解8种模式
去参考手册定位

配置位和数据寄存器
设计外部电路

LED、蜂鸣器、三极管
理解面包板连接
下一小节

接线、初始化、控制输出

这套顺序很重要。以后遇到任何 GPIO 输出任务,都可以沿着同一条链路思考:

想让什么器件产生什么现象 → 选哪个引脚 → 选择哪种输出电路 → 配置哪种 GPIO 模式 → 通过哪个寄存器或库函数改变电平。


2. 开场演示:三个程序分别在证明什么

老师先演示了三个程序:

程序 现象 本质
LED 闪烁 一个 LED 周期性亮灭 单个 GPIO 周期性输出高、低电平
LED 流水灯 8 个 LED 依次点亮 多个 GPIO 按顺序改变电平
蜂鸣器 蜂鸣器按节奏鸣响 GPIO 通过驱动电路控制负载通断

三个现象虽然不同,核心动作完全一样:程序改变 GPIO 引脚的输出电平,外部电路把电平变化转换成光或声音。

课堂位置:录音 00:06--01:13;老师 PPT 第 18 页为本章入口。


3. GPIO 是什么

GPIOGeneral Purpose Input/Output 的缩写,即通用输入输出口。

"通用"表示它不是只能完成一种固定功能。通过配置,同一个引脚可以承担数字输入、数字输出、模拟输入或片上外设的复用功能。

3.1 输出时可以做什么

  • 控制 LED、蜂鸣器等小负载;
  • 控制三极管、MOS 管、继电器驱动模块,再间接控制较大负载;
  • 输出片选、使能、复位等控制信号;
  • 用软件翻转 GPIO,模拟 I²C、SPI 等协议时序。

3.2 输入时可以做什么

  • 读取按键和数字传感器模块的高低电平;
  • 接收串口、I²C、SPI 等通信信号;
  • 配置为模拟输入,把模拟电压送入 ADC。

3.3 电压概念

在本课程使用的 STM32F103C8T6 中:

  • GPIO 输出低电平接近 0 V
  • GPIO 输出高电平接近 3.3 V
  • 部分引脚在数据手册中标记为 FT,表示其输入端具有 5 V 容忍能力;
  • 没有 FT 标记的普通引脚,输入电压不能随意超过 VDD + 0.3 V
  • STM32 由 3.3 V 供电,普通推挽输出不能主动输出 5 V。

!IMPORTANT

FT 不是"这个引脚可以随便接 5 V",更不是"能够输出 5 V"。必须同时满足数据手册规定的输入电压和注入电流限制。数据手册 PDF 第 17--20 页给出引脚的 FT 标记,第 24 页给出电压与注入电流的绝对最大额定值。


4. GPIO 的整体结构:端口、寄存器、驱动器

图 1 老师 PPT 第 19 页:GPIO 基本结构。

4.1 GPIO 按端口分组

STM32F103 的 GPIO 按 GPIOAGPIOBGPIOC 等端口分组。每个端口最多有 16 个引脚,编号为 0--15

  • GPIOA 的第 0 个引脚叫 PA0
  • GPIOA 的第 15 个引脚叫 PA15
  • GPIOB 的第 12 个引脚叫 PB12

PA0 可以拆成两部分理解:

text 复制代码
P A 0
│ │ └─ 端口内编号 0
│ └─── GPIOA 端口
└───── Port(端口)

4.2 GPIO 为什么要挂在总线上

CPU 不能直接"伸手"去改变引脚,它实际访问的是 GPIO 外设中的寄存器。寄存器再控制内部电路,最后改变引脚状态。

STM32F1 的 GPIOA、GPIOB、GPIOC 等 GPIO 外设挂在 APB2 总线上。使用某个 GPIO 前,要先在 RCC 中打开对应端口的 APB2 时钟;否则寄存器电路没有工作时钟,配置不会正常生效。
#mermaid-svg-PGz5HCqKCZn1i1JE{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-PGz5HCqKCZn1i1JE .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-PGz5HCqKCZn1i1JE .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-PGz5HCqKCZn1i1JE .error-icon{fill:#552222;}#mermaid-svg-PGz5HCqKCZn1i1JE .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-PGz5HCqKCZn1i1JE .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-PGz5HCqKCZn1i1JE .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-PGz5HCqKCZn1i1JE .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-PGz5HCqKCZn1i1JE .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-PGz5HCqKCZn1i1JE .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-PGz5HCqKCZn1i1JE .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-PGz5HCqKCZn1i1JE .marker{fill:#333333;stroke:#333333;}#mermaid-svg-PGz5HCqKCZn1i1JE .marker.cross{stroke:#333333;}#mermaid-svg-PGz5HCqKCZn1i1JE svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-PGz5HCqKCZn1i1JE p{margin:0;}#mermaid-svg-PGz5HCqKCZn1i1JE .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-PGz5HCqKCZn1i1JE .cluster-label text{fill:#333;}#mermaid-svg-PGz5HCqKCZn1i1JE .cluster-label span{color:#333;}#mermaid-svg-PGz5HCqKCZn1i1JE .cluster-label span p{background-color:transparent;}#mermaid-svg-PGz5HCqKCZn1i1JE .label text,#mermaid-svg-PGz5HCqKCZn1i1JE span{fill:#333;color:#333;}#mermaid-svg-PGz5HCqKCZn1i1JE .node rect,#mermaid-svg-PGz5HCqKCZn1i1JE .node circle,#mermaid-svg-PGz5HCqKCZn1i1JE .node ellipse,#mermaid-svg-PGz5HCqKCZn1i1JE .node polygon,#mermaid-svg-PGz5HCqKCZn1i1JE .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-PGz5HCqKCZn1i1JE .rough-node .label text,#mermaid-svg-PGz5HCqKCZn1i1JE .node .label text,#mermaid-svg-PGz5HCqKCZn1i1JE .image-shape .label,#mermaid-svg-PGz5HCqKCZn1i1JE .icon-shape .label{text-anchor:middle;}#mermaid-svg-PGz5HCqKCZn1i1JE .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-PGz5HCqKCZn1i1JE .rough-node .label,#mermaid-svg-PGz5HCqKCZn1i1JE .node .label,#mermaid-svg-PGz5HCqKCZn1i1JE .image-shape .label,#mermaid-svg-PGz5HCqKCZn1i1JE .icon-shape .label{text-align:center;}#mermaid-svg-PGz5HCqKCZn1i1JE .node.clickable{cursor:pointer;}#mermaid-svg-PGz5HCqKCZn1i1JE .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-PGz5HCqKCZn1i1JE .arrowheadPath{fill:#333333;}#mermaid-svg-PGz5HCqKCZn1i1JE .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-PGz5HCqKCZn1i1JE .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-PGz5HCqKCZn1i1JE .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-PGz5HCqKCZn1i1JE .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-PGz5HCqKCZn1i1JE .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-PGz5HCqKCZn1i1JE .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-PGz5HCqKCZn1i1JE .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-PGz5HCqKCZn1i1JE .cluster text{fill:#333;}#mermaid-svg-PGz5HCqKCZn1i1JE .cluster span{color:#333;}#mermaid-svg-PGz5HCqKCZn1i1JE div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-PGz5HCqKCZn1i1JE .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-PGz5HCqKCZn1i1JE rect.text{fill:none;stroke-width:0;}#mermaid-svg-PGz5HCqKCZn1i1JE .icon-shape,#mermaid-svg-PGz5HCqKCZn1i1JE .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-PGz5HCqKCZn1i1JE .icon-shape p,#mermaid-svg-PGz5HCqKCZn1i1JE .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-PGz5HCqKCZn1i1JE .icon-shape .label rect,#mermaid-svg-PGz5HCqKCZn1i1JE .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-PGz5HCqKCZn1i1JE .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-PGz5HCqKCZn1i1JE .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-PGz5HCqKCZn1i1JE :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} CPU执行程序
APB2总线
GPIO寄存器
输出驱动器
物理引脚
LED或蜂鸣器电路

参考手册:RCC 的 RCC_APB2ENR 在 PDF 第 70--71 页;GPIOA~GPIOG 的时钟使能位位于该寄存器低位。

4.3 寄存器和驱动器各负责什么

  • 寄存器负责保存配置和数据,相当于 GPIO 的"控制面板";
  • 驱动器使用内部晶体管提高带负载能力,把寄存器中的逻辑状态变成引脚上的实际电压;
  • 引脚是芯片与外部电路连接的物理端点。

例如,向输出数据寄存器的第 0 位写 1,会影响当前端口的 0 号引脚;读取输入数据寄存器第 0 位,则能知道该引脚当前被采样为高还是低。

由于一个端口只有 16 个引脚,输入、输出数据寄存器只使用低 16 位;高 16 位保留或另作特殊用途。

课堂位置:录音 02:54--04:06;师兄笔记 PDF 第 15 页。


5. 单个 GPIO 引脚内部是怎样工作的

图 2 老师 PPT 第 20 页:一个 GPIO 位的内部结构,源自参考手册"5 V 兼容 I/O 端口位的基本结构"。

老师把结构图分成上下两部分:

  • 上半部分是输入通道
  • 下半部分是输出通道

即使本节主题是输出,也先讲输入通道,是因为同一个物理引脚同时连接着输入与输出电路。理解完整结构后,8 种模式才不会变成死记硬背。

5.1 输入端的保护二极管

引脚附近画有通向电源端和地端的保护结构,用于限制异常电压并保护内部电路。

课堂上可以先理解为"电压过高或过低时,保护通道可能导通";工程上还必须记住:保护结构只能应对受限的异常电流,不能把它当稳压器使用。 超出数据手册的引脚电压或注入电流,仍可能损坏芯片或干扰其他模块。

5.2 上拉、下拉与浮空

输入通道中有两个可由程序控制的弱电阻:

  • 接通上拉:引脚没有外部驱动时,默认被拉向高电平;
  • 接通下拉:引脚没有外部驱动时,默认被拉向低电平;
  • 两个都不接:浮空输入,电平容易受干扰而不确定。

数据手册给出的内部弱上拉、弱下拉等效电阻典型值约为 40 kΩ,范围约 30--50 kΩ(PDF 第 40 页)。它们是"弱"电阻,不会代替外部信号强行控制引脚。

5.3 施密特触发器为什么能抗干扰

课堂转写中的"肖特基触发器"应校正为施密特触发器(Schmitt trigger)

普通比较器只有一个阈值,输入电压在阈值附近抖动时,数字输出可能反复跳变。施密特触发器使用高、低两个阈值:

  • 输入上升并超过上阈值,输出才变为 1
  • 输入下降并低于下阈值,输出才变为 0
  • 输入处于两个阈值之间时,保持之前状态。

#mermaid-svg-zugcbGET5up9AVM3{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-zugcbGET5up9AVM3 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-zugcbGET5up9AVM3 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-zugcbGET5up9AVM3 .error-icon{fill:#552222;}#mermaid-svg-zugcbGET5up9AVM3 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-zugcbGET5up9AVM3 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-zugcbGET5up9AVM3 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-zugcbGET5up9AVM3 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-zugcbGET5up9AVM3 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-zugcbGET5up9AVM3 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-zugcbGET5up9AVM3 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-zugcbGET5up9AVM3 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-zugcbGET5up9AVM3 .marker.cross{stroke:#333333;}#mermaid-svg-zugcbGET5up9AVM3 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-zugcbGET5up9AVM3 p{margin:0;}#mermaid-svg-zugcbGET5up9AVM3 defs #statediagram-barbEnd{fill:#333333;stroke:#333333;}#mermaid-svg-zugcbGET5up9AVM3 g.stateGroup text{fill:#9370DB;stroke:none;font-size:10px;}#mermaid-svg-zugcbGET5up9AVM3 g.stateGroup text{fill:#333;stroke:none;font-size:10px;}#mermaid-svg-zugcbGET5up9AVM3 g.stateGroup .state-title{font-weight:bolder;fill:#131300;}#mermaid-svg-zugcbGET5up9AVM3 g.stateGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-zugcbGET5up9AVM3 g.stateGroup line{stroke:#333333;stroke-width:1;}#mermaid-svg-zugcbGET5up9AVM3 .transition{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-zugcbGET5up9AVM3 .stateGroup .composit{fill:white;border-bottom:1px;}#mermaid-svg-zugcbGET5up9AVM3 .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px;}#mermaid-svg-zugcbGET5up9AVM3 .state-note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-zugcbGET5up9AVM3 .state-note text{fill:black;stroke:none;font-size:10px;}#mermaid-svg-zugcbGET5up9AVM3 .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-zugcbGET5up9AVM3 .edgeLabel .label rect{fill:#ECECFF;opacity:0.5;}#mermaid-svg-zugcbGET5up9AVM3 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-zugcbGET5up9AVM3 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-zugcbGET5up9AVM3 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-zugcbGET5up9AVM3 .edgeLabel .label text{fill:#333;}#mermaid-svg-zugcbGET5up9AVM3 .label div .edgeLabel{color:#333;}#mermaid-svg-zugcbGET5up9AVM3 .stateLabel text{fill:#131300;font-size:10px;font-weight:bold;}#mermaid-svg-zugcbGET5up9AVM3 .node circle.state-start{fill:#333333;stroke:#333333;}#mermaid-svg-zugcbGET5up9AVM3 .node .fork-join{fill:#333333;stroke:#333333;}#mermaid-svg-zugcbGET5up9AVM3 .node circle.state-end{fill:#9370DB;stroke:white;stroke-width:1.5;}#mermaid-svg-zugcbGET5up9AVM3 .end-state-inner{fill:white;stroke-width:1.5;}#mermaid-svg-zugcbGET5up9AVM3 .node rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-zugcbGET5up9AVM3 .node polygon{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-zugcbGET5up9AVM3 #statediagram-barbEnd{fill:#333333;}#mermaid-svg-zugcbGET5up9AVM3 .statediagram-cluster rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-zugcbGET5up9AVM3 .cluster-label,#mermaid-svg-zugcbGET5up9AVM3 .nodeLabel{color:#131300;}#mermaid-svg-zugcbGET5up9AVM3 .statediagram-cluster rect.outer{rx:5px;ry:5px;}#mermaid-svg-zugcbGET5up9AVM3 .statediagram-state .divider{stroke:#9370DB;}#mermaid-svg-zugcbGET5up9AVM3 .statediagram-state .title-state{rx:5px;ry:5px;}#mermaid-svg-zugcbGET5up9AVM3 .statediagram-cluster.statediagram-cluster .inner{fill:white;}#mermaid-svg-zugcbGET5up9AVM3 .statediagram-cluster.statediagram-cluster-alt .inner{fill:#f0f0f0;}#mermaid-svg-zugcbGET5up9AVM3 .statediagram-cluster .inner{rx:0;ry:0;}#mermaid-svg-zugcbGET5up9AVM3 .statediagram-state rect.basic{rx:5px;ry:5px;}#mermaid-svg-zugcbGET5up9AVM3 .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#f0f0f0;}#mermaid-svg-zugcbGET5up9AVM3 .note-edge{stroke-dasharray:5;}#mermaid-svg-zugcbGET5up9AVM3 .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-zugcbGET5up9AVM3 .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-zugcbGET5up9AVM3 .statediagram-note text{fill:black;}#mermaid-svg-zugcbGET5up9AVM3 .statediagram-note .nodeLabel{color:black;}#mermaid-svg-zugcbGET5up9AVM3 .statediagram .edgeLabel{color:red;}#mermaid-svg-zugcbGET5up9AVM3 #dependencyStart,#mermaid-svg-zugcbGET5up9AVM3 #dependencyEnd{fill:#333333;stroke:#333333;stroke-width:1;}#mermaid-svg-zugcbGET5up9AVM3 .statediagramTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-zugcbGET5up9AVM3 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 输入高于上阈值
输入低于下阈值
中间区域保持低
中间区域保持高
Low
High

这段"迟滞区"能过滤阈值附近的小幅噪声。整形后的数字状态进入输入数据寄存器 IDR

5.4 模拟输入与复用功能输入

引脚还有两条通向片上外设的输入路径:

  • 模拟输入:直接把模拟电压送往 ADC,数字输入路径关闭;
  • 复用功能输入:把数字电平送往 USART、定时器、I²C、SPI 等片上外设。

课堂位置:录音 04:06--08:17;参考手册 PDF 第 106 页为位结构,第 108--110 页为输入、输出、复用和模拟配置;师兄笔记 PDF 第 16--17 页。


6. 输出通道:谁决定电平,怎样把电平送到引脚

输出部分要回答两个问题:

  1. 输出数据从哪里来?
  2. 内部驱动器怎样把逻辑 0/1 变成引脚电压?

6.1 输出数据的两种来源

输出通道前有一个选择器:

  • 选择输出数据寄存器 :普通 GPIO 输出,CPU 写 ODR/BSRR/BRR 控制;
  • 选择片上外设输出:复用功能输出,例如 USART 的 TX、SPI 的 SCK/MOSI、定时器 PWM。

"复用"就是把引脚的输出控制权从普通 GPIO 数据寄存器交给某个片上外设。

6.2 ODR、BSRR、BRR 到底是什么关系

这三个寄存器不是每次都要依次"配置一遍"。它们是控制同一份输出状态的不同入口:

寄存器 作用 写入效果 适合场景
GPIOx_ODR 输出数据寄存器 直接保存端口 16 个输出位 一次写整个端口,或读改写
GPIOx_BSRR 位设置/清除寄存器 低 16 位写 1 置位;高 16 位写 1 清零 单步、原子地改一个或多个位,首选
GPIOx_BRR 位清除寄存器 低 16 位写 1 清零 只需要清零时使用
为什么不总是直接写 ODR

假设同一端口的 16 个引脚分别连接了不同设备,只想把 PA0 置高而保持其他位不变。如果先读 ODR、修改其中一位、再写回,这个过程叫读---改---写

c 复制代码
GPIOA->ODR |= (1U << 0);      // PA0 置 1,其他位尽量保持原值
GPIOA->ODR &= ~(1U << 0);     // PA0 清 0,其他位尽量保持原值

这需要多个操作;如果中断也在修改同一个 ODR,就可能出现竞争。

BSRR 是专门为单个位操作设计的写入接口:

c 复制代码
GPIOA->BSRR = (1U << 0);          // BSRR低16位:PA0置1
GPIOA->BSRR = (1U << (0 + 16));   // BSRR高16位:PA0清0

一次写操作即可完成,不需要先读出旧值,而且不会无意改变其他位,所以称为原子位操作 。标准外设库的 GPIO_SetBits()GPIO_ResetBits() 也利用了这类位设置/清除寄存器。

参考手册:ODRBSRRBRR 在 PDF 第 115--116 页;老师在录音 08:17--10:03 还提到了位带操作,本课程暂不使用。

6.3 推挽输出

图 3 老师 PPT 第 24 页:开漏输出与推挽输出。

推挽输出同时使用上方 P-MOS 和下方 N-MOS:

输出数据 P-MOS N-MOS 引脚状态
1 导通 截止 主动接近 VDD,输出高电平
0 截止 导通 主动接近 VSS,输出低电平

高、低电平都由芯片主动驱动,因此边沿清晰、驱动能力较强。普通 LED、控制信号、时钟信号等,通常使用推挽输出。

6.4 开漏输出

开漏输出关闭上方 P-MOS,只保留下方 N-MOS:

输出数据 N-MOS 引脚状态
0 导通 主动拉低到 VSS
1 截止 高阻态,本身不能主动拉高

因此开漏输出若要得到高电平,必须有上拉电阻。它的优势是:

  • 多个器件可以共用一根线,任何一个器件都只能把总线拉低,不会出现一边强推高、一边强拉低的直接冲突;
  • 适合 I²C 等"线与"总线;
  • 在满足器件数据手册条件时,可通过外部上拉适配不同的逻辑电压。

#mermaid-svg-MTq7PPMFC2v8m9uX{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-MTq7PPMFC2v8m9uX .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-MTq7PPMFC2v8m9uX .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-MTq7PPMFC2v8m9uX .error-icon{fill:#552222;}#mermaid-svg-MTq7PPMFC2v8m9uX .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-MTq7PPMFC2v8m9uX .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-MTq7PPMFC2v8m9uX .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-MTq7PPMFC2v8m9uX .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-MTq7PPMFC2v8m9uX .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-MTq7PPMFC2v8m9uX .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-MTq7PPMFC2v8m9uX .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-MTq7PPMFC2v8m9uX .marker{fill:#333333;stroke:#333333;}#mermaid-svg-MTq7PPMFC2v8m9uX .marker.cross{stroke:#333333;}#mermaid-svg-MTq7PPMFC2v8m9uX svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-MTq7PPMFC2v8m9uX p{margin:0;}#mermaid-svg-MTq7PPMFC2v8m9uX .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-MTq7PPMFC2v8m9uX .cluster-label text{fill:#333;}#mermaid-svg-MTq7PPMFC2v8m9uX .cluster-label span{color:#333;}#mermaid-svg-MTq7PPMFC2v8m9uX .cluster-label span p{background-color:transparent;}#mermaid-svg-MTq7PPMFC2v8m9uX .label text,#mermaid-svg-MTq7PPMFC2v8m9uX span{fill:#333;color:#333;}#mermaid-svg-MTq7PPMFC2v8m9uX .node rect,#mermaid-svg-MTq7PPMFC2v8m9uX .node circle,#mermaid-svg-MTq7PPMFC2v8m9uX .node ellipse,#mermaid-svg-MTq7PPMFC2v8m9uX .node polygon,#mermaid-svg-MTq7PPMFC2v8m9uX .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-MTq7PPMFC2v8m9uX .rough-node .label text,#mermaid-svg-MTq7PPMFC2v8m9uX .node .label text,#mermaid-svg-MTq7PPMFC2v8m9uX .image-shape .label,#mermaid-svg-MTq7PPMFC2v8m9uX .icon-shape .label{text-anchor:middle;}#mermaid-svg-MTq7PPMFC2v8m9uX .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-MTq7PPMFC2v8m9uX .rough-node .label,#mermaid-svg-MTq7PPMFC2v8m9uX .node .label,#mermaid-svg-MTq7PPMFC2v8m9uX .image-shape .label,#mermaid-svg-MTq7PPMFC2v8m9uX .icon-shape .label{text-align:center;}#mermaid-svg-MTq7PPMFC2v8m9uX .node.clickable{cursor:pointer;}#mermaid-svg-MTq7PPMFC2v8m9uX .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-MTq7PPMFC2v8m9uX .arrowheadPath{fill:#333333;}#mermaid-svg-MTq7PPMFC2v8m9uX .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-MTq7PPMFC2v8m9uX .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-MTq7PPMFC2v8m9uX .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-MTq7PPMFC2v8m9uX .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-MTq7PPMFC2v8m9uX .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-MTq7PPMFC2v8m9uX .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-MTq7PPMFC2v8m9uX .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-MTq7PPMFC2v8m9uX .cluster text{fill:#333;}#mermaid-svg-MTq7PPMFC2v8m9uX .cluster span{color:#333;}#mermaid-svg-MTq7PPMFC2v8m9uX div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-MTq7PPMFC2v8m9uX .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-MTq7PPMFC2v8m9uX rect.text{fill:none;stroke-width:0;}#mermaid-svg-MTq7PPMFC2v8m9uX .icon-shape,#mermaid-svg-MTq7PPMFC2v8m9uX .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-MTq7PPMFC2v8m9uX .icon-shape p,#mermaid-svg-MTq7PPMFC2v8m9uX .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-MTq7PPMFC2v8m9uX .icon-shape .label rect,#mermaid-svg-MTq7PPMFC2v8m9uX .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-MTq7PPMFC2v8m9uX .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-MTq7PPMFC2v8m9uX .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-MTq7PPMFC2v8m9uX :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 上拉电阻
共享总线
设备1:只会拉低或释放
设备2:只会拉低或释放
设备3:只会拉低或释放

!WARNING

老师用"开漏加 5 V 上拉"说明电平兼容原理。实际设计时,只有标记 FT 且满足相应工作条件的引脚才可考虑接入 5 V 上拉;还要检查外设是否允许 5 V、上拉电阻带来的灌电流,以及数据手册的注入电流限制。不要在普通非 FT 引脚上照搬。

6.5 输出模式下为什么还能读取 IDR

一个引脚不能同时被两个不同输出源主动驱动,但它的输入采样通道可以继续观察引脚上的实际电平。因此,除模拟输入模式外,很多模式下仍能从 IDR 读取引脚当前状态。

这对检查开漏总线、发现外部短路或验证实际引脚状态很有用。ODR 代表"希望输出什么",IDR 更接近"引脚上实际读到什么"。

课堂位置:录音 08:17--11:43;师兄笔记 PDF 第 16 页。


7. GPIO 的 8 种工作模式

图 4 老师 PPT 第 21 页:GPIO 8 种工作模式总表。

7.1 先按"数据方向"和"控制者"分类

模式 方向 默认/驱动特征 典型用途
浮空输入 数字输入 无内部上下拉,悬空时不确定 外部已有可靠驱动或外部上下拉
上拉输入 数字输入 悬空默认高 低电平有效按键、开漏信号
下拉输入 数字输入 悬空默认低 高电平有效信号
模拟输入 模拟输入 关闭数字输入路径,直达 ADC ADC 电压采样
通用开漏输出 数字输出 CPU 控制,只能主动拉低 软件模拟 I²C、共享线
通用推挽输出 数字输出 CPU 控制,高低都主动驱动 LED、蜂鸣器控制、普通控制线
复用开漏输出 数字输出 片上外设控制,只能主动拉低 硬件 I²C
复用推挽输出 数字输出 片上外设控制,高低都主动驱动 USART TX、SPI、PWM

7.2 STM32F1 中 MODE 与 CNF 的关系

每个 GPIO 引脚由 4 个配置位控制:CNF[1:0] + MODE[1:0]

MODE = 00:输入类模式
MODE CNF 模式
00 00 模拟输入
00 01 浮空输入
00 10 上拉/下拉输入,具体方向由对应 ODR 位选择
00 11 保留
MODE ≠ 00:输出类模式

MODE 决定输出速度等级,CNF 决定输出电路及控制来源:

MODE 标称最大输出速度 CNF 输出类型
10 2 MHz 00 通用推挽
10 2 MHz 01 通用开漏
10 2 MHz 10 复用推挽
10 2 MHz 11 复用开漏
01 10 MHz 同上 由 CNF 选择同类四种输出
11 50 MHz 同上 由 CNF 选择同类四种输出

"输出速度"主要影响输出边沿速度和可支持的切换频率,并不是配置为 50 MHz 后引脚会自动以 50 MHz 翻转。输出越快,通常电磁干扰与动态功耗也越大,应选择满足需求的最低速度。

!NOTE

老师为简化入门操作,说一般可直接选 50 MHz;这对 PA0 等普通引脚的低速教学实验能工作。但工程设计应选择够用的最低速度。PC13、PC14、PC15 还有特殊限制,只能配置为 2 MHz,详见数据手册 PDF 第 20 页。

7.3 为什么 LED 用通用推挽输出

LED 只需要 CPU 明确输出高或低,不需要外设接管,也不需要多设备共享一条线,因此:

  • "通用"比"复用"合适;
  • "推挽"能主动输出高、低电平,比开漏更直接;
  • 速度选择只要满足闪烁或流水灯即可,LED 本身是很慢的负载。

这就是配置 GPIO 时先问的三件事:

  1. 是输入还是输出?
  2. 普通 GPIO 控制还是片上外设控制?
  3. 输出要推挽还是开漏?

课堂位置:录音 11:43--14:52;参考手册 PDF 第 106 页表 17、图 14;师兄笔记 PDF 第 16--17 页。


8. 老师是怎样查手册的

本节课实际用到三类资料,各自解决不同问题:

资料 主要回答什么 本节示例
原理图 外部器件接在哪个引脚,电路高有效还是低有效 LED 的正负极、限流电阻、蜂鸣器三极管
数据手册 某个具体芯片/封装有哪些引脚,电气极限是多少 FT、PC13 特殊限制、I/O 电流、速度
参考手册 外设内部如何工作,寄存器每一位怎样配置 GPIO 8 种模式、CRL/CRH、IDR/ODR/BSRR

8.1 参考手册的查阅路径

打开《STM32F10xxx参考手册(中文)》第 8 章"通用和复用功能 I/O(GPIO 和 AFIO)":

  1. PDF 第 105--110 页:先读功能说明和结构图;
  2. PDF 第 106 页表 17:查 8 种模式的 MODE/CNF 编码;
  3. PDF 第 110--113 页:使用某个片上外设时,查推荐 GPIO 配置;
  4. PDF 第 113--116 页:查每个 GPIO 寄存器的地址、复位值和位定义。

8.2 为什么有 CRL 和 CRH 两个配置寄存器

一个引脚需要 4 个配置位,一个端口有 16 个引脚,总共需要:

text 复制代码
16 × 4 bit = 64 bit

而 STM32F1 的寄存器宽度是 32 位,所以拆成两个:

寄存器 管理引脚 PDF 位置
GPIOx_CRL Px0~Px7 参考手册第 113--114 页
GPIOx_CRH Px8~Px15 参考手册第 114 页

例如:

  • 配置 PA0,看 GPIOA_CRL 的第 3~0 位;
  • 配置 PB12,看 GPIOB_CRH 中对应 PB12 的 4 位;
  • 配置 PC13,看 GPIOC_CRH 中对应 PC13 的 4 位。

8.3 读寄存器描述的固定方法

看到一个寄存器,不要先背十六进制数,按下面顺序读:

  1. 寄存器名称和用途;
  2. 地址偏移;
  3. 复位值;
  4. 目标位在第几位;
  5. 每种位组合表示什么;
  6. 该位可读、可写,还是只写;
  7. 0 和写 1 分别有什么副作用。

这种读法比记住某个固定常数更可靠,因为换引脚、换端口后,目标位位置会变,但逻辑不变。

课堂位置:录音 14:52--17:07


9. 从芯片内部走到外部:LED 与蜂鸣器电路

图 5 老师 PPT 第 27 页:LED 的高/低电平驱动,以及 PNP/NPN 三极管蜂鸣器驱动。

9.1 LED 的方向和限流电阻

LED 是发光二极管,只有正向导通时才发光:

  • 普通直插 LED 通常长脚为正极、短脚为负极;
  • 也可观察内部金属片,较大的一侧通常是负极;
  • 最可靠的方式是看器件规格书或用万用表二极管挡确认。

LED 串联限流电阻有两个目的:

  1. 防止电流过大烧坏 LED 或 GPIO;
  2. 调节亮度,电阻越大,通常电流越小、亮度越低。

估算公式:

text 复制代码
R ≈ (电源电压 - LED正向压降) / 目标电流

例如 3.3 V 供电、红色 LED 正向压降约 2.0 V、希望约 2 mA:

text 复制代码
R ≈ (3.3 V - 2.0 V) / 0.002 A ≈ 650 Ω

可选择附近标准值 680 Ω 或更保守的 1 kΩ。老师示意图采用 1 kΩ

9.2 低电平点亮

连接关系:

text 复制代码
3.3V ── LED ── 限流电阻 ── PA0
  • PA0 = 0:电流从 3.3 V 流经 LED 和电阻,再由 PA0 灌入地,LED 亮;
  • PA0 = 1:LED 两端电位接近,电流很小,LED 灭。

这叫低电平有效低电平点亮

9.3 高电平点亮

连接关系:

text 复制代码
PA0 ── 限流电阻 ── LED ── GND
  • PA0 = 1:PA0 向外提供电流,LED 亮;
  • PA0 = 0:两端接近地电位,LED 灭。

这叫高电平有效高电平点亮

普通 GPIO 推挽模式下两种接法都可行,但必须核算电流。许多单片机电路偏好低电平灌电流方式,所以不能只看代码中的 SetBits/ResetBits 判断亮灭,必须先看原理图。

9.4 有源蜂鸣器与无源蜂鸣器

类型 内部是否自带振荡 控制方式 本课程
有源蜂鸣器 给直流通断信号即可发出固定音调 使用
无源蜂鸣器 需要 PWM/方波,频率决定音调 本节不使用

老师使用的蜂鸣器模块带三极管驱动,控制端为低电平时导通并鸣响,高电平时关闭。

9.5 为什么蜂鸣器要加三极管

GPIO 适合输出逻辑信号和较小电流。蜂鸣器、继电器、电机等负载电流较大时,不应让 GPIO 直接承担全部电流,应使用三极管、MOS 管或专用驱动芯片。
#mermaid-svg-YmcIjk05dJX6arPx{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-YmcIjk05dJX6arPx .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-YmcIjk05dJX6arPx .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-YmcIjk05dJX6arPx .error-icon{fill:#552222;}#mermaid-svg-YmcIjk05dJX6arPx .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-YmcIjk05dJX6arPx .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-YmcIjk05dJX6arPx .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-YmcIjk05dJX6arPx .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-YmcIjk05dJX6arPx .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-YmcIjk05dJX6arPx .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-YmcIjk05dJX6arPx .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-YmcIjk05dJX6arPx .marker{fill:#333333;stroke:#333333;}#mermaid-svg-YmcIjk05dJX6arPx .marker.cross{stroke:#333333;}#mermaid-svg-YmcIjk05dJX6arPx svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-YmcIjk05dJX6arPx p{margin:0;}#mermaid-svg-YmcIjk05dJX6arPx .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-YmcIjk05dJX6arPx .cluster-label text{fill:#333;}#mermaid-svg-YmcIjk05dJX6arPx .cluster-label span{color:#333;}#mermaid-svg-YmcIjk05dJX6arPx .cluster-label span p{background-color:transparent;}#mermaid-svg-YmcIjk05dJX6arPx .label text,#mermaid-svg-YmcIjk05dJX6arPx span{fill:#333;color:#333;}#mermaid-svg-YmcIjk05dJX6arPx .node rect,#mermaid-svg-YmcIjk05dJX6arPx .node circle,#mermaid-svg-YmcIjk05dJX6arPx .node ellipse,#mermaid-svg-YmcIjk05dJX6arPx .node polygon,#mermaid-svg-YmcIjk05dJX6arPx .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-YmcIjk05dJX6arPx .rough-node .label text,#mermaid-svg-YmcIjk05dJX6arPx .node .label text,#mermaid-svg-YmcIjk05dJX6arPx .image-shape .label,#mermaid-svg-YmcIjk05dJX6arPx .icon-shape .label{text-anchor:middle;}#mermaid-svg-YmcIjk05dJX6arPx .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-YmcIjk05dJX6arPx .rough-node .label,#mermaid-svg-YmcIjk05dJX6arPx .node .label,#mermaid-svg-YmcIjk05dJX6arPx .image-shape .label,#mermaid-svg-YmcIjk05dJX6arPx .icon-shape .label{text-align:center;}#mermaid-svg-YmcIjk05dJX6arPx .node.clickable{cursor:pointer;}#mermaid-svg-YmcIjk05dJX6arPx .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-YmcIjk05dJX6arPx .arrowheadPath{fill:#333333;}#mermaid-svg-YmcIjk05dJX6arPx .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-YmcIjk05dJX6arPx .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-YmcIjk05dJX6arPx .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-YmcIjk05dJX6arPx .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-YmcIjk05dJX6arPx .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-YmcIjk05dJX6arPx .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-YmcIjk05dJX6arPx .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-YmcIjk05dJX6arPx .cluster text{fill:#333;}#mermaid-svg-YmcIjk05dJX6arPx .cluster span{color:#333;}#mermaid-svg-YmcIjk05dJX6arPx div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-YmcIjk05dJX6arPx .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-YmcIjk05dJX6arPx rect.text{fill:none;stroke-width:0;}#mermaid-svg-YmcIjk05dJX6arPx .icon-shape,#mermaid-svg-YmcIjk05dJX6arPx .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-YmcIjk05dJX6arPx .icon-shape p,#mermaid-svg-YmcIjk05dJX6arPx .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-YmcIjk05dJX6arPx .icon-shape .label rect,#mermaid-svg-YmcIjk05dJX6arPx .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-YmcIjk05dJX6arPx .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-YmcIjk05dJX6arPx .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-YmcIjk05dJX6arPx :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} GPIO输出小电流控制信号
基极/栅极电阻
三极管或MOS管开关
外部电源
蜂鸣器或其他负载

GPIO 只负责控制开关,负载电流由电源和驱动管回路承担。

9.6 PNP 与 NPN 驱动的逻辑

驱动方式 典型位置 GPIO 有效电平 说明
PNP 高边开关 负载上方、靠近电源 低电平导通 发射极接高电位,给基极较低电位开启
NPN 低边开关 负载下方、靠近地 高电平导通 发射极接地,给基极较高电位开启

PNP 通常放在高边,NPN 通常放在低边,是为了让基极---发射极获得正确的开启电压。实际设计还要选择合适的基极电阻;若负载含电感,还要考虑续流二极管。

课堂位置:录音 17:07--20:14;师兄笔记 PDF 第 18--19 页;数据手册 PDF 第 40--41 页给出 I/O 驱动与输出电压条件。


10. 面包板为什么能免焊接连接电路

图 6 老师 PPT 第 28 页:面包板内部金属夹片与孔位连接关系。

面包板的孔不是全部相通,而是由背面的金属夹片分组连接:

  • 中间区域通常每 5 个孔为一组纵向相通;
  • 中央沟槽两侧互不相通,适合跨沟槽插入 DIP 芯片;
  • 两侧或上下的红、蓝电源轨通常横向相通;
  • 有些面包板的电源轨在中间断开,使用前应观察标线或用万用表通断挡确认;
  • 电源轨若断开,应使用跳线把两段连接起来。

10.1 下一小节接线前先检查

  • STM32、外部模块与外部电源是否共地
  • 3.3 V 和 GND 是否接反;
  • LED 正负极是否正确;
  • LED 是否串有限流电阻;
  • 面包板电源轨是否中间断开;
  • PA0 是否确实接到预期那一组孔;
  • 蜂鸣器模块的 VCC/GND/IO 是否对应正确;
  • 负载是否超过 GPIO 可承受能力,是否需要驱动管。

课堂位置:录音 20:14--21:04;师兄笔记 PDF 第 19 页。


11. 把本节知识压缩成一次完整设计推理

以"用 PA0 控制低电平点亮的 LED"为例:
#mermaid-svg-qvUGveCvO4lNnW7Y{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-qvUGveCvO4lNnW7Y .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-qvUGveCvO4lNnW7Y .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-qvUGveCvO4lNnW7Y .error-icon{fill:#552222;}#mermaid-svg-qvUGveCvO4lNnW7Y .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-qvUGveCvO4lNnW7Y .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-qvUGveCvO4lNnW7Y .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-qvUGveCvO4lNnW7Y .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-qvUGveCvO4lNnW7Y .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-qvUGveCvO4lNnW7Y .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-qvUGveCvO4lNnW7Y .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-qvUGveCvO4lNnW7Y .marker{fill:#333333;stroke:#333333;}#mermaid-svg-qvUGveCvO4lNnW7Y .marker.cross{stroke:#333333;}#mermaid-svg-qvUGveCvO4lNnW7Y svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-qvUGveCvO4lNnW7Y p{margin:0;}#mermaid-svg-qvUGveCvO4lNnW7Y .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-qvUGveCvO4lNnW7Y .cluster-label text{fill:#333;}#mermaid-svg-qvUGveCvO4lNnW7Y .cluster-label span{color:#333;}#mermaid-svg-qvUGveCvO4lNnW7Y .cluster-label span p{background-color:transparent;}#mermaid-svg-qvUGveCvO4lNnW7Y .label text,#mermaid-svg-qvUGveCvO4lNnW7Y span{fill:#333;color:#333;}#mermaid-svg-qvUGveCvO4lNnW7Y .node rect,#mermaid-svg-qvUGveCvO4lNnW7Y .node circle,#mermaid-svg-qvUGveCvO4lNnW7Y .node ellipse,#mermaid-svg-qvUGveCvO4lNnW7Y .node polygon,#mermaid-svg-qvUGveCvO4lNnW7Y .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-qvUGveCvO4lNnW7Y .rough-node .label text,#mermaid-svg-qvUGveCvO4lNnW7Y .node .label text,#mermaid-svg-qvUGveCvO4lNnW7Y .image-shape .label,#mermaid-svg-qvUGveCvO4lNnW7Y .icon-shape .label{text-anchor:middle;}#mermaid-svg-qvUGveCvO4lNnW7Y .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-qvUGveCvO4lNnW7Y .rough-node .label,#mermaid-svg-qvUGveCvO4lNnW7Y .node .label,#mermaid-svg-qvUGveCvO4lNnW7Y .image-shape .label,#mermaid-svg-qvUGveCvO4lNnW7Y .icon-shape .label{text-align:center;}#mermaid-svg-qvUGveCvO4lNnW7Y .node.clickable{cursor:pointer;}#mermaid-svg-qvUGveCvO4lNnW7Y .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-qvUGveCvO4lNnW7Y .arrowheadPath{fill:#333333;}#mermaid-svg-qvUGveCvO4lNnW7Y .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-qvUGveCvO4lNnW7Y .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-qvUGveCvO4lNnW7Y .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-qvUGveCvO4lNnW7Y .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-qvUGveCvO4lNnW7Y .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-qvUGveCvO4lNnW7Y .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-qvUGveCvO4lNnW7Y .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-qvUGveCvO4lNnW7Y .cluster text{fill:#333;}#mermaid-svg-qvUGveCvO4lNnW7Y .cluster span{color:#333;}#mermaid-svg-qvUGveCvO4lNnW7Y div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-qvUGveCvO4lNnW7Y .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-qvUGveCvO4lNnW7Y rect.text{fill:none;stroke-width:0;}#mermaid-svg-qvUGveCvO4lNnW7Y .icon-shape,#mermaid-svg-qvUGveCvO4lNnW7Y .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-qvUGveCvO4lNnW7Y .icon-shape p,#mermaid-svg-qvUGveCvO4lNnW7Y .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-qvUGveCvO4lNnW7Y .icon-shape .label rect,#mermaid-svg-qvUGveCvO4lNnW7Y .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-qvUGveCvO4lNnW7Y .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-qvUGveCvO4lNnW7Y .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-qvUGveCvO4lNnW7Y :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 目标:控制LED亮灭
看原理图:LED接在3.3V与PA0之间
得出逻辑:PA0低电平亮,高电平灭
看数据手册:PA0引脚位置与电气条件
选模式:通用推挽输出
开GPIOA的APB2时钟
配置PA0的CRL/MODE与CNF
用BSRR/BRR或库函数改变输出位
电流流过LED与限流电阻,产生亮灭

这条链路同时回答了几个常见疑问:

  • 为什么要看原理图? 因为它决定引脚、负载连接方式和高低有效逻辑。
  • 为什么要看数据手册? 因为它决定引脚是否存在、是否 FT、能承受多大电压电流以及有无特殊限制。
  • 为什么要看参考手册? 因为它告诉你 GPIO 内部机制、配置编码和寄存器位定义。
  • 为什么选择推挽? 因为 LED 需要明确的高低电平,不需要共享总线。
  • 为什么先开时钟? 因为 GPIO 外设挂在 APB2 上,时钟关闭时外设寄存器不工作。
  • 为什么还要写 BSRR/BRR? 配置寄存器只决定引脚"怎样工作",数据寄存器才决定它"此刻输出 0 还是 1"。

12. 本节容易混淆的转写与表述校正

录音转写/课堂简化 正确理解
"8 种输入模式" 应为 8 种 GPIO 工作模式,其中包含输入和输出
"APP2 / APPI" 应为 APB2;GPIOA~GPIOG 挂在 APB2
"L 口、银角"等 语音转写错误,均指 I/O 口或引脚
"肖特基触发器" 此处应为施密特触发器
"开路输出" STM32 手册标准名称为开漏输出(Open-drain)
"位设置寄存器、位清除寄存器" 对应 BSRRBRRBSRR 同时包含置位区和复位区
"FT 引脚可以接 5 V" 仅表示规定条件下的输入 5 V 容忍,不代表能输出 5 V 或可忽略注入电流
"输出速度直接选 50 MHz" 教学实验可这样简化;工程中应选满足需求的最低速度,特殊引脚另查数据手册

13. 本节课与下一小节的边界

本段录音主要完成了原理和硬件设计准备,还没有正式展开接线后的初始化代码。下一小节才会把本节逻辑落到程序中:

  1. 打开 GPIOA 时钟;
  2. 把 PA0 配置为通用推挽输出;
  3. 选择合适输出速度;
  4. 通过 GPIO_SetBits()GPIO_ResetBits() 或对应寄存器输出高低电平;
  5. 加入延时形成 LED 闪烁;
  6. 扩展到 8 路流水灯和蜂鸣器节奏。

因此复习时不要急着背代码。先保证自己能从原理图推导出"哪个电平会亮",再把这个结论写进程序。


14. 复习自测

  1. GPIOA 和 GPIOB 各最多有多少个引脚?PA0 的名称如何拆解?
  2. GPIO 为什么要先打开 RCC 时钟?GPIO 挂在哪条总线上?
  3. 寄存器和输出驱动器分别负责什么?
  4. 上拉输入、下拉输入和浮空输入的默认状态有何区别?
  5. 施密特触发器为什么使用两个阈值?
  6. ODRBSRRBRR 的作用分别是什么?为什么 BSRR 更适合改单个位?
  7. 推挽输出与开漏输出的 P-MOS、N-MOS 工作方式有何不同?
  8. 为什么开漏输出必须配上拉电阻才能得到高电平?
  9. "通用输出"和"复用输出"的控制者分别是谁?
  10. 看到 LED 电路后,怎样判断它是高电平点亮还是低电平点亮?
  11. 为什么 LED 必须串限流电阻?
  12. 为什么蜂鸣器或电机通常要加入三极管/MOS 管驱动?
  13. 参考手册、数据手册、原理图分别应该查什么?
  14. 为什么 PC13 不能机械照搬普通 PA0 的 50 MHz、直接源电流驱动方案?

15. 参考资料与页码索引

15.1 老师课堂资料

资料 本笔记采用范围
D:/2026-08-30 12_59 GPIO输出_原文.docx 全文,重点时间 00:06--21:04
课件PPT/STM32入门教程.pptx 第 18--28 页;本文引用第 19、20、21、24、27、28 页配图

15.2 师兄笔记

PDF 页码 内容
第 15 页 GPIO 用途、端口分组、APB2、寄存器与驱动器
第 16 页 GPIO 位结构、推挽/开漏、8 种模式总表
第 17 页 输入、模拟输入、输出与复用配置结构图
第 18 页 外设 GPIO 配置示例、有源蜂鸣器模块
第 19 页 LED 高/低电平驱动、PNP/NPN 驱动、面包板

文件:../STM32笔记.pdf

15.3 《STM32F10xxx参考手册(中文)》

PDF 页码 章节/内容
第 70--71 页 RCC_APB2ENR,GPIO 端口时钟使能
第 105 页 第 8 章 GPIO/AFIO 功能说明入口
第 106 页 5 V 兼容 I/O 位结构、端口配置表(MODE/CNF)
第 107 页 通用 I/O、单个位设置/清除
第 108 页 输入配置、输出配置
第 109--110 页 复用功能、模拟输入
第 110--113 页 外设的 GPIO 推荐配置
第 113--114 页 GPIOx_CRLGPIOx_CRHGPIOx_IDR
第 115--116 页 GPIOx_ODRGPIOx_BSRRGPIOx_BRRGPIOx_LCKR

文件:../参考文档/STM32F10xxx参考手册(中文).pdf

15.4 《STM32F103x8/B数据手册(中文)》

PDF 页码 章节/内容
第 17--20 页 引脚定义、FT 标记、PC13/PC14/PC15 特殊限制
第 24 页 电压、电流和注入电流的绝对最大额定值
第 40 页 I/O 输入阈值、施密特迟滞、上拉/下拉电阻、驱动电流说明
第 41 页 输出电压特性和 2/10/50 MHz 输出交流特性

文件:../参考文档/STM32F103x8B数据手册(中文).pdf


16. 一句话总结

GPIO 输出不是"写一行点灯代码",而是一条完整链路:原理图决定接法和有效电平,数据手册限定引脚能力,参考手册给出模式与寄存器,程序再通过 GPIO 输出状态驱动外部电路。

相关推荐
andrsted17 分钟前
作业发布、课堂检测和错题讲评,用一个小程序完成
学习·微信小程序·小程序·学习方法
摇滚侠37 分钟前
《SpringBoot 3:入门与应用实战》第 9 章 使用 WebMvc 开发进阶 阅读笔记 24
spring boot·笔记·后端
摇滚侠1 小时前
《SpringBoot 3:入门与应用实战》第 9 章 使用 WebMvc 开发应用 阅读笔记 22
javascript·spring boot·笔记
单片机仿真设计1 小时前
【proteus仿真设计】基于 STM32 单片机火灾监测报警系统设计(仿真图+程序)
stm32·单片机·嵌入式硬件·proteus·毕设
Titan20241 小时前
HTTPS基础知识梳理
服务器·网络·c++·网络协议·学习·http·https
艾莉丝努力练剑1 小时前
【AI大模型接入SDK】SSE协议
c++·学习·面试·大模型·sdk
一条破秋裤1 小时前
STM32 学习笔记:OLED 调试工具与 Keil 在线调试
笔记·stm32·学习
EthanChou20201 小时前
AES67协议笔记
前端·笔记·es6
prog_61031 小时前
【笔记】cllama:搜罗万象当LLM api server测qwen3.8:flash-next
笔记·大语言模型·agent·vibe-coding·qwen3.8-flash