树莓派GPIO编程入门:用RPi.GPIO库控制LED亮灭

发布时间:2026/10/17 6:04:50
树莓派GPIO编程入门:用RPi.GPIO库控制LED亮灭 树莓派到手之后很多人的第一反应是折腾桌面、装软件包、跑点脚本。我自己也是这么过来的但玩了一两个月后真正让我觉得“这板子没白买”的其实是那块40针的GPIO排针。只要接上几根杜邦线、一颗电阻、一枚LED再用RPi.GPIO库写几行Python让某个引脚输出高电平或低电平灯的亮灭就完全由代码说了算。这种能直接控制真实硬件的感觉和写网页、跑数据分析是完全不同的体验。这篇是树莓派硬件编程系列的第一篇目标很明确把“用RPi.GPIO库输出信号”这件事从原理到实操讲透。你会学到GPIO引脚的两种编号方式、RPi.GPIO库的核心API、怎么安全接线和计算限流电阻最后用一个按键控制LED的实战例子把输入检测和信号输出串起来。适合刚拿到板子、只会用桌面系统的的新手也适合想快速回忆GPIO基础、准备做硬件项目的朋友。不需要太多前置知识懂一点Python语法就够了哪怕几个英文单词不认识也不影响跟着敲一遍就通了。1. 整体思路为什么用RPi.GPIO库做信号输出1.1 RPi.GPIO、gpiozero、wiringPi怎么选处理树莓派GPIO的库不止一个最常见的三个是RPi.GPIO、gpiozero和wiringPi。很多人一开始会纠结“我应该学哪个”其实不用太纠结先看它们分别是什么。RPi.GPIO是树莓派生态里出现比较早的Python库接口风格非常直接设置模式叫setmode设置引脚叫setup输出电平叫output。API少语义贴近硬件几乎没有封装很适合理解GPIO的工作原理。gpiozero是官方后来推的面向对象库写起来更简洁比如led LED(17)一行就创建了一个LED对象还能直接led.on()、led.off()。它对传感器、电机、屏幕等常见硬件做了更高层的抽象适合快速开发。但正因为封装得多它对底层原理的展示就弱一些。wiringPi是C语言起家的库早期教程特别多后来维护已经收尾了在新系统上编译经常报错。除非你有历史项目要维护否则新项目不建议再碰。我在这个系列里选择RPi.GPIO不是因为它的功能最强而是因为它最“裸”。你要理解GPIO的高电平和低电平、输入和输出、拉高和拉低用RPi.GPIO是最直观的。等这个系列把基础打牢固你再去看gpiozero会发现它的很多抽象概念对应到硬件层面到底是什么理解起来一马平川。提示RPi.GPIO官方后来进入了维护模式更新的频率不高。如果你用的是比较新的板子和内核碰到个别新功能支持不好可以换gpiozero或者内核自带的libgpiod。本篇覆盖的是最通用的40Pin GPIO用RPi.GPIO完全胜任。1.2 输出信号到底输出了什么很多新手对“输出信号”这四个字有些误解以为GPIO引脚就像家里的插座一样能输出源源不断的电能。其实GPIO输出的是逻辑电平不是功率。当代码执行GPIO.output(pin, GPIO.HIGH)时引脚内部相当于被接通到3.3V电源引脚上能测到约3.3V的电压。执行GPIO.output(pin, GPIO.LOW)时引脚内部相当于被接通到地电压接近0V。听起来简单但关键在于这个引脚能提供的电流非常有限。树莓派的GPIO单引脚最大电流安全值一般在16mA左右不同型号略有差异所有引脚加起来的电流上限也只有几十毫安。这个特性决定了你能直接控制什么、不能控制什么。点亮一个十几毫安的LED没问题但直接驱动一个12V的直流电机或者一个220V的继电器想都不要想硬件层面的需求根本不匹配。后面到了扩展应用的部分你会看到怎么通过三极管、MOS管、继电器模块来“借力”用GPIO这个小小的信号去撬动大功率设备。先把“信号”和“功率”这两个概念分开后面的电路理解就会顺畅很多。2. 硬件准备从引脚编号到最小电路2.1 BOARD与BCM两种编号到底该用哪个树莓派的GPIO引脚有两种编号方式这是新手遇到的第一道坎。BOARD模式按照排针的物理位置编号从靠近网口或者USB口的一侧开始左边第1针就是1号右边第2针是2号一路排到40号。它的优点是接线时数一下第几针就行跟芯片型号无关。BCM模式按照处理器芯片内部的GPIO编号来命名比如BCM17、BCM18、BCM27。这个编号与物理位置没有固定规律需要对照引脚图才能知道它对应排针上的哪一针。写代码的时候我推荐用BCM模式原因有两个一是BCM编号直接对上芯片的GPIO功能你在查数据手册、看复用功能表时用的是同一个编号不容易产生歧义二是很多新出的扩展板、HAT模块的资料也都是按BCM编号描述交流起来更方便。接线时看着引脚图操作其实也不会麻烦太多。熟悉一下常用的映射这几个是新手期最常用的BCM编号物理引脚位置常见用途17第11针普通GPIO做LED输出很顺手18第12针普通GPIO也支持PWM27第13针普通GPIO22第15针普通GPIO23第16针普通GPIO24第18针普通GPIO25第22针普通GPIO另一点要特别注意树莓派除了GPIO引脚之外还有3.3V电源引脚和5V电源引脚。如果你不小心把5V引脚接到GPIO输入上或者在BOARD模式下把物理引脚号当成BCM号来用轻则读取结果不对重则可能直接把引脚烧了。所以每次接线之前建议先查一下最新的引脚对照表不要凭记忆硬来。常见的操作是在终端执行pinout命令命令行直接就会输出一张引脚图一目了然。2.2 最小点亮电路与限流电阻计算控制GPIO输出最简单、也最有仪式感的项目就是点亮一颗LED。别小看这个LED电路它能讲清楚两个很重要的硬件概念正向压降和限流电阻。LED本质上是一个二极管它的电流方向是单向的而且一旦导通两端电压基本稳定在一个固定值附近。这个电压叫正向压降VF不同颜色的LED差别挺大。红色LED的VF通常在1.8V到2.2V之间绿色大概2.0V到3.0V蓝色和白色一般要2.8V到3.4V。如果GPIO输出高电平是3.3V你直接把LED接在3.3V和地之间正向压降吃掉了大约2V剩下的电压由电路里的其他阻抗来消化。如果没有任何限流元件LED的电流会瞬间飙升直到烧毁。所以必须串一个限流电阻。计算方式很简单就是欧姆定律。取红LED的典型正向压降2.0V期望电流10mA来算R (3.3V - 2.0V) / 0.01A 130Ω120Ω或130Ω不是特别好买但220Ω和330Ω都是标准阻值随处可得。用220Ω时电流约6mA用330Ω时约4mA亮度有区别但都能正常点亮。如果你手头只有100Ω的电阻电流大约13mA也在安全范围内可以凑合用。但低于50Ω就不建议了非常接近甚至超过引脚安全电流上限。还有一点关于LED正负极的确认长脚是正极阳极短脚是负极阴极。有些高亮LED或者贴片LED不太好分辨引脚长短就看你买的封装说明。接反了不会烧只是不亮因为二极管反向不导通。把正极接到GPIO引脚负极经过电阻接到GND这就是高电平点亮的经典接法。2.3 接线规范与通电前检查接线这件事看起来简单但实操中翻车率极高。我的习惯是严格按照下面几步来先断电。树莓派关机、拔掉电源线再进行任何物理接线操作。把杜邦线两头插好。插排针时要插到底用手轻轻拉一下确认不松。检查有没有把5V引脚当成3.3V接到GPIO检查LED方向有没有接反。确认无误后再上电。有人觉得关机重启很麻烦想问能不能热插拔。我的建议是尽量不要。热插拔的瞬间杜邦线头可能会碰到旁边的引脚造成瞬间短路而且树莓派GPIO没有完善的输入保护一个不小心的电压冲击就可能让某个引脚永久失灵。虽然控制个小LED风险不大但养成断电操作的习惯后面玩电机、接传感器时能少烧不少东西。另外很多现成的传感器模块、继电器模块厂家已经把电阻、三极管都集成好了你只需要把GPIO信号线接到模块的IN端即可不需要再额外串电阻。这一点我在后面4.3节会展开。3. 核心实操用RPi.GPIO点亮你的第一盏灯3.1 安装库与验证环境现在的树莓派系统Raspberry Pi OS通常会预装Python3但RPi.GPIO不一定预装。你可以在终端里先验证一下python3 -c import RPi.GPIO; print(RPi.GPIO.VERSION)如果输出了版本号比如0.7.0说明环境里已经有了。如果提示ModuleNotFoundError就用pip安装sudo apt update sudo apt install python3-pip sudo pip3 install RPi.GPIO这里有个经验要分享尽量用sudo python3 -m pip install而不要直接用pip3 install。树莓派系统管理Python包的逻辑和普通Linux一致当前登录用户的pip和root环境下的pip可能是两套体系混用会导致“明明装了却还是 import 失败”。用python3 -m pip这种方式能保证安装到正在使用的那个Python环境里。3.2 第一段代码单次点亮与熄灭现在把LED的正极通过220Ω电阻接到物理第11针也就是BCM17LED负极接到GND比如物理第6针。写下面这段代码保存成led_once.pyimport RPi.GPIO as GPIO import time LED_PIN 17 GPIO.setmode(GPIO.BCM) GPIO.setup(LED_PIN, GPIO.OUT, initialGPIO.LOW) try: GPIO.output(LED_PIN, GPIO.HIGH) print(LED ON) time.sleep(2) GPIO.output(LED_PIN, GPIO.LOW) print(LED OFF) finally: GPIO.cleanup()运行的时候需要管理员权限sudo python3 led_once.py代码逻辑很直白但几个细节值得展开说。GPIO.setmode(GPIO.BCM)是第一步告诉库我要用BCM编号方式。很多人忘记这一行库会直接抛异常。这一步同时还隐含了一个约束一个进程里只能设置一次模式如果已经用BOARD了再调BCM会报错。GPIO.setup(LED_PIN, GPIO.OUT, initialGPIO.LOW)把引脚配置成输出模式。这里多写了一个initialGPIO.LOW很多人会觉得多余但它其实很实用。不写initial的话引脚在配置成输出的瞬间电平状态是不确定的有可能上电先闪一下再被你控制的代码拉低。写上initialGPIO.LOW后配置输出的同时电平就被固定为低电平程序运行时LED不会“鬼闪”。GPIO.output(LED_PIN, GPIO.HIGH)是真正输出信号的动作。高电平维持2秒后再输出低电平LED熄灭。finally: GPIO.cleanup()是我强烈建议养成的习惯。cleanup会把你在程序里设置过的引脚全部恢复成默认状态同时释放库内部占用的资源。如果不调用cleanup程序直接退出后引脚可能保持最后的状态可能一直亮着下次再跑程序时系统还可能提示某个channel已经被占用。注意RPi.GPIO直接操作的是底层寄存器默认需要root权限所以运行命令时要加sudo。如果你不想每次都用sudo可以把当前用户加进gpio组或者配置udev规则但新手阶段没必要折腾直接用sudo最省心。运行这段代码LED会亮2秒后熄灭终端上依次打印两行信息程序结束。到这里你已经完成了第一次真正的GPIO信号输出。3.3 闪烁程序与异常清理机制单次点亮太简单我们把它变成闪烁灯。思路基本一样只是把输出高、低电平放在一个循环里中间用time.sleep(0.5)控制节奏import RPi.GPIO as GPIO import time LED_PIN 17 GPIO.setmode(GPIO.BCM) GPIO.setup(LED_PIN, GPIO.OUT, initialGPIO.LOW) try: while True: GPIO.output(LED_PIN, GPIO.HIGH) time.sleep(0.5) GPIO.output(LED_PIN, GPIO.LOW) time.sleep(0.5) except KeyboardInterrupt: pass finally: GPIO.cleanup()这里的try/except KeyboardInterrupt是Python处理CtrlC的标准方式。当你按下CtrlC时程序不会直接僵在那里而是收到一个KeyboardInterrupt异常pass把它忽略掉然后走finally里的cleanup。如果你想验证cleanup的价值可以故意把finally那行注释掉运行程序后按CtrlC然后拿万用表量一下BCM17引脚——你会发现它可能还停在3.3V。之后再跑别的程序操作这个引脚系统就会报错。这个坑基本每个玩树莓派的人都踩过。对于闪烁这个应用来说time.sleep的精度完全够用不需要纠结毫秒级误差。如果以后你要做精确到微秒的时序控制、或者要输出连续变化的模拟信号就要考虑PWM或者内核态的通用GPIO驱动了那属于这个系列后面几篇的内容。3.4 高低电平点亮两种接法的坑绝大多数教程里的LED电路是“GPIO输出高电平点亮”的接法逻辑也直观。但实际上LED也可以反过来接一端接3.3V另一端经过电阻接GPIO引脚这时GPIO输出低电平LED反而会亮。两种接法在编程上的差异就是GPIO.HIGH和GPIO.LOW的对应关系刚好相反。有些新手照着别人的代码写却发现LED不亮多半不是代码问题而是用了低电平点亮的接法却依然在代码里输出高电平。我建议新手统一用高电平点亮因为低电平点亮的电路在调试时有个坑GPIO默认状态如果没设置好上电瞬间引脚可能是低电平灯会莫名亮一下。虽然可以通过initialGPIO.HIGH来规避但总归多一层心智负担。等你能熟练控制两种接法才算真的理解了“GPIO输出高低电平”这件事而不是只会背代码。另外还有两种“作死接法”要明确避免第一不要把LED直接跨接在3.3V和5V之间或者跨接在两个GPIO引脚之间。前一种会迅速烧灯后一种可能同时损坏两个引脚。第二如果用的是蓝色或白色LED它的正向压降接近3V在3.3V供电下留给限流电阻的余量只有0.3V左右这意味着一颗电阻值很小的变化就会让电流波动巨大。遇到蓝白灯不亮优先怀疑是不是供电电压不足换成3.3V供电之外的其他方案或者直接用集成模块。4. 小项目实战按键控制LED打通输入与输出4.1 输入模式与内部上拉下拉GPIO不仅能输出信号也能读取外部信号这是硬件交互的另一个半边天。在RPi.GPIO里把引脚配置成输入模式只需要一行代码GPIO.setup(KEY_PIN, GPIO.IN, pull_up_downGPIO.PUD_UP)很多新手在做按键的时候会遇到一个经典现象不按按键时引脚的电平随机跳来跳去程序判断时灵时不灵。原因很简单引脚在输入模式下是高阻态外部如果没有确定的电平来源它就像一个没系绳的气球被周围电磁环境带着乱飘。解决办法是外接一个上拉电阻把引脚通过电阻接到3.3V或下拉电阻把引脚通过电阻接到GND让悬空状态下的引脚电平固定下来。RPi.GPIO贴心地提供了内部上拉/下拉功能pull_up_downGPIO.PUD_UP就是启动内部的几十千欧上拉电阻不需要你再外接一颗。少了这根飞线面包板清爽不少少一个能插错的点。这里有一个新手绕不过去的弯配置上拉后按键没按下时读到的电平是高HIGH按下时反而是低LOW因为按键另一端接了地按下时把引脚强行拉到了0V。所以“按下”对应的是低电平跟直觉正好相反。理解了这个逻辑你写按键判断时就不会把条件写反。4.2 按键点灯完整代码与防抖处理接下来把按键接到BCM18也就是物理第12针。按键一脚接BCM18另一脚接GND。这样配置内部上拉后按下时GPIO读到LOW。完整代码如下import RPi.GPIO as GPIO LED_PIN 17 KEY_PIN 18 GPIO.setmode(GPIO.BCM) GPIO.setup(LED_PIN, GPIO.OUT, initialGPIO.LOW) GPIO.setup(KEY_PIN, GPIO.IN, pull_up_downGPIO.PUD_UP) try: while True: if GPIO.input(KEY_PIN) GPIO.LOW: GPIO.output(LED_PIN, GPIO.HIGH) else: GPIO.output(LED_PIN, GPIO.LOW) except KeyboardInterrupt: pass finally: GPIO.cleanup()这个程序功能很简单按住按键就亮松开就灭。运行之后你会发现有时候LED会轻微闪烁或者响应不干脆这就是机械按键的抖动问题在作怪。按键按下这个动作物理上并不会像数字电路里理想的那样“啪”地从高到低跳变而是会在短时间内经历一连串快速的接触、断开、再接触。这个过程叫抖动持续几毫秒到几十毫秒不等。用上面的代码直接读等于把这串混乱的抖动也读进去了表现出来就是LED闪烁或者误触发。最简单的软件消抖就是在检测到电平变化后先等一小段时间再确认一次if GPIO.input(KEY_PIN) GPIO.LOW: time.sleep(0.02) if GPIO.input(KEY_PIN) GPIO.LOW: GPIO.output(LED_PIN, GPIO.HIGH) else: GPIO.output(LED_PIN, GPIO.LOW)第一次读到低电平后等20毫秒再读一次如果还是低才认为是真正的按下。这20毫秒足以跨过按键抖动的高峰期又不至于让响应感觉迟钝。这个方法简单可靠适合所有按键场景。你还可以把程序升级成“按一下切换状态”的开关模式用一个布尔变量记录当前LED状态每次检测到完整的“按下-松开”过程就把状态取反。注意要处理好“按住不放”的情况避免一次按压被循环反复触发。4.3 从LED到继电器、蜂鸣器输出信号的扩展学到这里你可能已经发现GPIO输出的本质就两个状态高和低。但从这两个状态里能演化出非常多的应用。买个继电器模块把GPIO信号接到模块的IN端。输出高电平时继电器吸合接在继电器输出端的220V设备就开始工作输出低电平时继电器断开。这样你就在用3.3V的逻辑信号控制一个隔离的功率回路。继电器模块内部自带驱动三极管和续流二极管你不需要自己搭这些电路。蜂鸣器模块也是一样模块上有源蜂鸣器自带振荡电路只要给高电平就会响程序上跟控制LED几乎没区别。电机驱动模块、步进电机驱动板、舵机控制本质都是靠GPIO输出高低电平或者脉冲序列来驱动。之所以变化无穷只是因为你在信号端用高低电平表达“开”与“关”而功率端由各个模块去负责。所以第一篇文章的内容扎实不扎实决定你后面玩这些模块顺不顺利。别急着贪多把一个LED点亮的每个细节都搞明白比囫囵吞枣跑通十个例子更有价值。5. 常见问题排查与实用笔记5.1 权限、引脚占用、模式错乱等高频问题玩RPi.GPIO这段时间我把新手和同事常遇到的问题整理成了一个速查表遇到问题直接对照着找能省很多时间。现象大概率原因解决办法运行报RuntimeError: No access to /dev/mem当前用户没有GPIO寄存器操作权限用sudo python3运行或者给用户加对应权限报RuntimeError: Please set pin numbering mode using GPIO.setmode()忘记调用setmode在第一条setup前加上GPIO.setmode调用报RuntimeError: Channel already in use引脚被之前未cleanup的进程占用用sudo pkill -f python3清理残留进程或重启树莓派操作了某个引脚但没反应BOARD与BCM模式用错编号对不上检查setmode参数对照引脚图重新确认编号程序运行正常但LED不亮LED方向接反、限流电阻过大、接错引脚先看电路再看代码可用万用表量引脚电压按键识别不灵敏、乱触发按键抖动或引脚悬空加软件消抖检查上拉/下拉配置最隐蔽的一个问题是引脚复用冲突。树莓派很多GPIO引脚默认就被系统占用了比如BCM14和BCM15默认用做串口调试控制台BCM2和BCM3默认用做I2C时钟和数据。你不用这些功能时它们看似空闲但系统底层驱动可能已经在操作这些引脚。如果恰好选到了这些引脚可能出现“startup阶段还好好的某个系统服务起来后引脚状态就变了”的灵异现象。新手的应对方案很简单先用手册里标注“普通GPIO”的引脚比如BCM17、BCM18、BCM27避开默认复用引脚。等以后需要I2C、串口时再去显式配置和切换。另一个值得强调的习惯是用完清理。我见过不少人写代码时把cleanup忘得一干二净导致同一个引脚被不同程序反复“抢”来“抢”去出问题后又不知道是哪个进程在占用。排查时可以运行sudo ps aux | grep python看是不是有残留的python进程在跑。找到PID后sudo kill PID或者直接sudo pkill -f python3然后规范地把try/finally cleanup这套结构用进后面的每一个脚本里。5.2 电流、供电、发热等硬件层面的注意事项软件层面的坑说完了硬件层面同样有讲究。上面提到GPIO引脚输出高电平约3.3V这只是空载电压。当你把LED、模块接到引脚上电流流动后引脚电压会因为内部驱动电阻而略微下降这是正常的不用担心。真正要警惕的是总电流超限。树莓派的GPIO并没有特别可靠的输出电流保护它的安全边界取决于PCB设计和片上驱动器的限制。单引脚建议不要超过16mA全部引脚总输出电流控制在50mA以内比较稳妥。如果你同时点亮十几个灯总电流可能就到了危险区。这时候不能继续硬接而是要优化电路选更小电流的LED、通过MOS管驱动、或者给LED单独供电。所谓“单独供电”做法是把LED的正极接到树莓派的3.3V或5V电源引脚而不是从GPIO引脚取电。GPIO引脚只作为开关负责控制MOS管或三极管导通大电流走电源引脚和地。这样GPIO本身的电流负担只有几毫安却能控制几百毫安甚至更大的负载。还有一个容易忽略的点树莓派排针上有3.3V和5V两种电源引脚。有些外部模块逻辑是5V的比如部分光电传感器、旧款显示屏它们的输出高电平可能是5V直接接回树莓派GPIO会有超过3.3V电平的风险。反过来树莓派GPIO输出的3.3V信号驱动一些要求5V高电平的模块时可能又被识别成低电平导致模块不动作。所以买模块前先看工作电压和逻辑电平尽量选3.3V兼容的。已经买了5V的模块可以通过一个电阻分压或者电平转换模块来匹配信号。最后关于发热GPIO长时间大电流驱动外部设备时树莓派主板上相关元件会微微发热这是正常现象。但如果你发现某个引脚周边的PCB位置温度明显异常大概率是电流超标了赶紧断电检查不要强行继续跑。树莓派几十块钱的板子烧了一个引脚虽然还能用其他引脚但总归不划算。我个人在实际操作中的体会是GPIO编程的技术难度不大真正的难点在于“软硬件联调”时的判断力。代码的错编译器和报错信息多少会给点提示电路的错完全靠眼睛和万用表去发现。所以调试时别光盯着代码看拿个万用表打到直流电压档红表笔点被测引脚黑表笔点GND然后在代码里切换高低电平看电压是不是跟着变。如果引脚电压能正常切换说明树莓派没坏程序逻辑也没大问题问题基本出在外部电路上。靠着这个方法我能在几分钟内把“硬件问题”和“软件问题”分开比盲猜快得多。这个系列的第一篇就到这里。RPi.GPIO的输入检测、事件回调、PWM输出都还没展开那些是后续章节的内容。但不管你往后要玩什么先把“设置引脚为输出、让引脚输出高低电平”这个基本功练扎实了后面都是一通百通的事。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询