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 是什么
GPIO 是 General 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 按 GPIOA、GPIOB、GPIOC 等端口分组。每个端口最多有 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. 输出通道:谁决定电平,怎样把电平送到引脚
输出部分要回答两个问题:
- 输出数据从哪里来?
- 内部驱动器怎样把逻辑
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() 也利用了这类位设置/清除寄存器。
参考手册:
ODR、BSRR、BRR在 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 时先问的三件事:
- 是输入还是输出?
- 普通 GPIO 控制还是片上外设控制?
- 输出要推挽还是开漏?
课堂位置:录音
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)":
- PDF 第 105--110 页:先读功能说明和结构图;
- PDF 第 106 页表 17:查 8 种模式的
MODE/CNF编码; - PDF 第 110--113 页:使用某个片上外设时,查推荐 GPIO 配置;
- 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 读寄存器描述的固定方法
看到一个寄存器,不要先背十六进制数,按下面顺序读:
- 寄存器名称和用途;
- 地址偏移;
- 复位值;
- 目标位在第几位;
- 每种位组合表示什么;
- 该位可读、可写,还是只写;
- 写
0和写1分别有什么副作用。
这种读法比记住某个固定常数更可靠,因为换引脚、换端口后,目标位位置会变,但逻辑不变。
课堂位置:录音
14:52--17:07。
9. 从芯片内部走到外部:LED 与蜂鸣器电路

图 5 老师 PPT 第 27 页:LED 的高/低电平驱动,以及 PNP/NPN 三极管蜂鸣器驱动。
9.1 LED 的方向和限流电阻
LED 是发光二极管,只有正向导通时才发光:
- 普通直插 LED 通常长脚为正极、短脚为负极;
- 也可观察内部金属片,较大的一侧通常是负极;
- 最可靠的方式是看器件规格书或用万用表二极管挡确认。
LED 串联限流电阻有两个目的:
- 防止电流过大烧坏 LED 或 GPIO;
- 调节亮度,电阻越大,通常电流越小、亮度越低。
估算公式:
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) |
| "位设置寄存器、位清除寄存器" | 对应 BSRR 和 BRR;BSRR 同时包含置位区和复位区 |
| "FT 引脚可以接 5 V" | 仅表示规定条件下的输入 5 V 容忍,不代表能输出 5 V 或可忽略注入电流 |
| "输出速度直接选 50 MHz" | 教学实验可这样简化;工程中应选满足需求的最低速度,特殊引脚另查数据手册 |
13. 本节课与下一小节的边界
本段录音主要完成了原理和硬件设计准备,还没有正式展开接线后的初始化代码。下一小节才会把本节逻辑落到程序中:
- 打开 GPIOA 时钟;
- 把 PA0 配置为通用推挽输出;
- 选择合适输出速度;
- 通过
GPIO_SetBits()、GPIO_ResetBits()或对应寄存器输出高低电平; - 加入延时形成 LED 闪烁;
- 扩展到 8 路流水灯和蜂鸣器节奏。
因此复习时不要急着背代码。先保证自己能从原理图推导出"哪个电平会亮",再把这个结论写进程序。
14. 复习自测
- GPIOA 和 GPIOB 各最多有多少个引脚?
PA0的名称如何拆解? - GPIO 为什么要先打开 RCC 时钟?GPIO 挂在哪条总线上?
- 寄存器和输出驱动器分别负责什么?
- 上拉输入、下拉输入和浮空输入的默认状态有何区别?
- 施密特触发器为什么使用两个阈值?
ODR、BSRR、BRR的作用分别是什么?为什么BSRR更适合改单个位?- 推挽输出与开漏输出的 P-MOS、N-MOS 工作方式有何不同?
- 为什么开漏输出必须配上拉电阻才能得到高电平?
- "通用输出"和"复用输出"的控制者分别是谁?
- 看到 LED 电路后,怎样判断它是高电平点亮还是低电平点亮?
- 为什么 LED 必须串限流电阻?
- 为什么蜂鸣器或电机通常要加入三极管/MOS 管驱动?
- 参考手册、数据手册、原理图分别应该查什么?
- 为什么 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_CRL、GPIOx_CRH、GPIOx_IDR |
| 第 115--116 页 | GPIOx_ODR、GPIOx_BSRR、GPIOx_BRR、GPIOx_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 输出状态驱动外部电路。