ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

树莓派GPIO入门实战:从引脚速查到LED与按键控制

树莓派GPIO入门实战:从引脚速查到LED与按键控制 折腾树莓派4B装好系统、连上Wi-Fi、开好VNC之后大多数人会突然不知道该干什么了。它确实可以当小电脑用但如果你只是用浏览器、写写文档那它和普通迷你主机没什么区别。树莓派真正值钱的地方在于那两排露在外面的引脚——GPIO。这篇学习笔记就是系列里的第5篇聊聊GPIO的入门操作。我会从基础知识、引脚对照讲到最简单的LED灯控制再配合按键输入做一个小交互实验最后整理我实际踩过的坑。适合已经装好系统、会SSH登录、但没有硬件编程基础的朋友有STM32或Arduino经验的人可以直接跳到后半部分看差异点。1. GPIO入门概念与引脚速览1.1 GPIO到底是什么先破除几个MCU经验带来的误区GPIO的全称是General Purpose Input/Output通用输入输出。拆开来看就八個字通用、输入、输出。意思是说树莓派通过这些引脚既能输出高/低电平去控制外部设备也能读取外部设备给出的电平信号。你可以把它理解成树莓派伸出来的神经末梢电脑上的USB口是帮你封装好了协议按一下就能传数据GPIO则是把最原始的电平暴露给你高还是低你来决定怎么用也你来决定。很多人问我玩过STM32是不是就能直接上手树莓派GPIO答案是可以但有三个坑必须先避开。第一GPIO模式。STM32的GPIO有8种工作模式输入浮空、输入上拉、输入下拉、模拟输入、开漏输出、推挽输出、复用开漏、复用推挽选错模式功能就不对这是MCU开发者特别熟悉的一套东西。树莓派上的GPIO没这么复杂用户能控制的层面主要就是输入和输出外加可以开内部上拉或下拉电阻。你用gpiozero这个库写LED、按键、PWM库在背后帮你把模式设好了不需要自己对着寄存器翻数据手册。第二电平标准。STM32的GPIO一般是3.3V逻辑部分引脚支持5V容忍树莓派是严格的3.3V逻辑电平引脚不推荐直接接5V超过3.3V就可能损坏芯片。很多Arduino玩家习惯拿5V板子的经验来玩树莓派一个5V信号直接怼进GPIO芯片就冒烟了。这点必须时刻记着。第三引脚数量。树莓派4B的40针排针里真正可编程的GPIO只有26个左右剩下的都是电源、地、以及复用功能脚。不是每一根针都能当普通IO乱用比如GPIO2和GPIO3默认接了1.8kΩ上拉电阻主要用于I2C通信你硬要拿它们做普通按键输入会碰到上拉带来的干扰。1.2 树莓派4B的40针引脚BCM编号和物理引脚别搞混树莓派的引脚编号有两种体系新手最容易在这里翻车。第一种是物理编号就是板子上从1到40的顺序号。左上角那个方形的引脚是1号然后往右是2号再往下是3号、4号按蛇形排列。这种编号只看板子物理位置优点是永远不变缺点是记起来费劲而且和芯片内部的GPIO号完全不对应。第二种是BCM编号也就是Broadcom芯片内部的GPIO编号。写代码时用的就是BCM编号比如LED(17)指的是BCM17对应物理引脚11。很多教程会直接说接GPIO17说的就是BCM编号不是物理第17个针脚。你要是按物理编号插线大概率插错。建议你在终端里直接敲一行命令pinout官方系统自带这个工具运行后会在屏幕上画出当前主板的引脚布局清楚标出物理编号、BCM编号、I2C、SPI、UART、PWM这些功能。我第一次接触时是打印了一张引脚图放在桌上后来发现pinout命令更方便换板子也不会过时。我整理了一份常用引脚速查表照着接线就行功能BCM编号物理引脚备注3.3V电源-1、17电源输出别当GPIO用5V电源-2、4电源输出别把信号接这里GND-6、9、14、20、25、30、34、39没接地线一切白搭GPIO171711最常用来做LED实验的引脚GPIO223默认用于I2C SDA带1.8kΩ上拉GPIO335默认用于I2C SCL带1.8kΩ上拉GPIO14148默认用于板载串口TXDGPIO151510默认用于板载串口RXDGPIO8824SPI0 CE0GPIO9921SPI0 MISOGPIO101019SPI0 MOSIGPIO111123SPI0 SCLKGPIO121232支持硬件PWMGPIO131333支持硬件PWMGPIO181812支持硬件PWMGPIO191935支持硬件PWM1.3 3.3V逻辑和供电能力的边界先知道才能不烧板树莓派的GPIO输出高电平是3.3V输出低电平是0V。这和很多5V单片机不一样所以外接模块时一定要先确认模块的逻辑电平。除了电压还要关心电流。树莓派单个GPIO引脚的安全输出电流大约在16mA左右整块板所有GPIO同时输出的总电流最好控制在50mA以内。这个数字听起来很小实际上驱动一个LED绰绰有余LED正常工作电流也就5到10mA但如果你想直接驱动继电器线圈、直流电机、蜂鸣器或者舵机电流就远远不够了必须通过三极管、MOS管或者专门的驱动模块来扩流。注意树莓派GPIO不是Arduino3.3V脚也不是电源输出口。想给外设模块供电3.3V引脚只能承担很小的负载5V引脚也不能通过GPIO来控制通断。老老实实理解成信号控制端别把它当电源用。另外树莓派上电后所有GPIO默认是输入模式不会主动输出高电平或低电平。所以你要是先把LED接好再给树莓派上电灯不会亮这是正常的不是线和程序的问题。程序运行后GPIO进入输出模式并置高灯才会亮。2. 环境准备与硬件接线2.1 系统、Python库和GPIO工具链怎么选目前官方Raspberry Pi OS系统装好之后Python 3是自带的gpiozero库也是自带的。这一步省去了很多麻烦不需要自己pip install任何东西。打开终端确认一下环境python3 --version python3 -c import gpiozero; print(gpiozero.__version__)如果第二行输出了一个版本号比如1.6.2就说明环境没问题可以直接写代码。这里要多说一句库的选择。网上大量老教程用的是RPi.GPIO这个库GPIO.setmode(GPIO.BCM)、GPIO.setup(17, GPIO.OUT)、GPIO.output(17, GPIO.HIGH)这套流程。这个库很经典随手一搜一大把资料在树莓派4B上也能正常用。但它有一个问题作者早已停止维护新的树莓派5系统上已经不支持官方主推的是gpiozero这也是树莓派官方文档现在的默认推荐。如果你是全新入门我强烈建议直接学gpiozero。它的代码抽象层更高一个LED就是LED(17)一个按键就是Button(2)一个PWM灯就是PWMLED(17)代码可读性比RPi.GPIO好太多。等以后要读底层寄存器或者做性能敏感的项目再回头补RPi.GPIO或者直接用libgpiod也不迟。2.2 点亮LED前必须搞懂的限流电阻计算先说材料清单都是便宜东西淘宝一套下来十几块钱树莓派4B一台已经用SSH远程登录或接显示器面包板一块公对母杜邦线若干5mm LED一个220Ω电阻一个没有的话330Ω也可以四脚按键开关一个有条件的话我还建议买一块40pin的GPIO扩展板加排线。把扩展板插到树莓派排针上再用杜邦线从扩展板引到面包板比直接往树莓派针脚上怼线安全得多也不容易松动。然后是限流电阻。LED是电流型器件工作时光靠自身电阻限制不了电流必须串联一个电阻。红色LED的正向压降大约2.0V工作电流取10mA树莓派GPIO输出高电平是3.3V那么电阻值就是R (3.3V - 2.0V) / 0.01A 130Ω所以用220Ω、330Ω都在安全范围内。330Ω时电流大约4mA红色LED照样能亮只是亮度不是最亮而已。如果你用的是蓝色或白色LED正向压降往往在3.0V以上同样的330Ω电阻会让它非常暗甚至不亮这时候可以把电阻降到100Ω左右但要确保电流不超过16mA的上限。接线也简单GPIO17接电阻电阻另一端接LED长脚正极LED短脚负极接GND。2.3 程序退出后引脚还会输出高电平吗要不要手动清理初学者经常问程序跑完红灯一直亮着退出之后会不会把这个引脚锁死gpiozero的设计是程序正常退出时会自动清理把用过的引脚恢复成输入状态所以不用你手动做什么。但要注意如果你的程序是因为CtrlC中断gpiozero也会通过try/finally机制清理引脚状态这点比裸写RPi.GPIO更省心。不过有一个例外程序崩溃或者被强制kill掉的时候引脚状态可能来不及清理会出现你看到的现象LED依然亮着程序却已经退出了。这种情况不用慌下次运行任何gpiozero程序它会重新初始化相关引脚。你要是实在强迫症可以顺手把树莓派重启一下所有引脚必然恢复默认输入状态。3. 实操LED闪烁、按键输入与PWM调节3.1 第一个LED闪烁程序从代码到原理一步步拆新建一个文件名字随意比如led_blink.pyfrom gpiozero import LED from time import sleep led LED(17) while True: led.on() sleep(1) led.off() sleep(1)运行python3 led_blink.py如果你接线没错应该能看见LED每秒亮一下、灭一下。led.on()和led.off()很好理解就是一个让引脚输出高电平和低电平的过程。sleep(1)是让程序暂停1秒不然高中低电平时长就看不见了。但这段代码有个不太优雅的地方while True循环把CPU占着虽然树莓派4B不在乎这点占用但它阻塞了其他代码执行的路径后面想加按键、加传感器时会很被动。gpiozero其实提供了更漂亮的做法from gpiozero import LED from signal import pause led LED(17) led.blink() pause()led.blink()启动闪烁然后pause()让程序一直挂起等待进程不退出但也不占CPU。这个例子虽然简单但体现了gpiozero的一个核心设计理念把底层细节封装掉让你关注逻辑而不是电平翻转。以后跑更复杂的项目你会发现这种事件驱动信号挂起的写法能省很多心。如果你想做一个灯光渐变效果就要用到PWM了。树莓派4B有部分引脚支持硬件PWM其他引脚可以用软件PWM。gpiozero的PWMLED把这两者都处理好了代码层面你不需要关心硬件细节from gpiozero import PWMLED from time import sleep led PWMLED(17) while True: for v in range(0, 101): led.value v / 100 sleep(0.02) for v in range(100, -1, -1): led.value v / 100 sleep(0.02)led.value的范围是0.0到1.00.0表示全灭1.0表示最亮。上面这段代码让LED从灭到亮再回到灭形成一个呼吸灯效果。PWM的本质是快速切换高低电平让LED的平均电压可调从而改变亮度。这个原理后面控制舵机、直流电机调速时会反复用到。3.2 按键输入与上拉电阻为什么按键另一端要接GNDLED只是单向输出要让树莓派读取外部信号就得做输入实验。最常见的入门输入设备就是按键。接线方法按键一端接GPIO2另一端接GND。然后写代码from gpiozero import LED, Button led LED(17) btn Button(2) btn.when_pressed led.on btn.when_released led.off运行之后按一下按键LED亮松开LED灭。这个例子里的按键交互逻辑已经完全出来了。这里的核心知识点是上拉电阻。GPIO2在树莓派上默认带了内部的1.8kΩ上拉电阻也就是说当引脚悬空时它会被电阻拉到高电平。而按键的另一端接的是GND按下时引脚被拉到低电平产生一个从高到低的电平跳变。Button(2)这个类默认就会启用上拉电阻然后检测到这个跳变触发when_pressed回调。很多新手想不通为什么按键不接3.3V而是接GND原因就在这里。默认上拉的前提下接GND才能制造按下拉低的跳变。如果你把按键另一端接3.3V那么按下去之后引脚依然是高电平电平没有变化代码就永远不会触发回调。当然你可以在创建Button时显式写pull_upFalse然后把按键接3.3V那也成立。但为了和大量现成教程保持一致建议默认使用接GND的接法。还有一种情况是按键需要程序等待比如按下后才继续执行后面的步骤。gpiozero提供了wait_for_press()方法from gpiozero import Button btn Button(2) print(请按下按键...) btn.wait_for_press() print(按键已按下继续执行)这种阻塞等待在拍照触发、启动任务等场景里很有用比while True轮询优雅得多。3.3 轮询和事件回调性能差在哪可能有基础的朋友会问用while True: if btn.is_pressed:这样不停轮询检测不行吗硬件上当然行树莓派4B性能足够但你思考一下两种方式的差别。轮询模式while True: if btn.is_pressed: led.on() else: led.off()这段代码每秒钟会执行成千上万次判断CPU被白白占用。而且按键按下和松开的瞬间电平不是立刻稳定的会有抖动可能触发好几次误判。gpiozero的when_pressed/when_released是事件回调它在后台检测边沿变化只有电平真正发生变化时才执行你注册的函数而且库里内置了软件去抖生活体验完全不同。以后你接传感器、接编码器、接多个按键事件回调的优势会越来越明显。把主循环空出来程序还能干别的活这是从玩具代码走向正经代码的关键一步。4. 常见问题与排查技巧实录4.1 引脚占用、权限问题、接线错误这三类问题占大头GPIO报错信息五花八门但绝大多数跑不出这三类。我一个个说。第一类是引脚被占用。gpiozero对树莓派上一些默认有特殊功能的引脚会做保护。比如你拿GPIO2做普通输入运行时会看到类似这样的警告The pins used by GPIO... have been reserved for...意思是这个引脚默认有I2C功能你强行当普通IO用可以但会有潜在冲突。我建议如果只是入门实验干脆避开GPIO2和GPIO3这两个I2C脚如果后面要接OLED屏、传感器这类I2C设备更要避开免得两边打架。第二类是权限问题。如果你用的是比较老的树莓派系统或者自己精简过系统可能出现PermissionError。这是因为当前用户不在gpio用户组里。解决办法sudo usermod -a -G gpio 你的用户名然后退出重新登录或者重启一下再运行程序就不需要加sudo了。注意强烈不建议用sudo python3去跑GPIO程序因为以后生成的缓存文件、进程归root所有你自己的用户反而改不了会带来一堆奇怪问题。第三类是接线错误。十个GPIO问题里至少有六个是线接错了。常见情况是BCM编号和物理编号搞混上面已经说过LED正负极接反短脚接GPIO、长脚接GND灯不亮杜邦线接触不良面包板插孔松了导致信号时有时无。排查接线最有效的办法是先把树莓派断电沿着每一根线从起点走到终点挨个确认然后重新上电。千万别怕麻烦这一步比查代码值一百倍。4.2 按键检测失效的排查思路按键没反应我遇到过四次原因各不相同这里整理成一张速查表现象大概率原因排查方法按键按下LED没反应四脚按键接错脚用万用表蜂鸣档测引脚通断或者换一种接法试按键按下了但程序里始终读到高电平按键另一端误接了3.3V确认按键另一端是否接GND按下和松开时LED频繁闪动没做软件去抖检查是否用了when_pressed回调而非轮询按键不灵敏要用力按才触发面包板接触不良换一根杜邦线或换一个面包板插孔代码运行正常但GPIO口对不上把物理编号当成了BCM编号用pinout命令核对引脚编号四脚按键这个坑值得细说。市面上常见的四脚按键开关一边的两个脚之间内部是始终导通的按下之后左右两侧才接通。很多新手把两根线分别插在同一边的两个脚上结果按下和松开测出来始终是导通程序自然什么都检测不到。正确接法是一根线接左侧任意一脚另一根接右侧任意一脚。没把握就用万用表通断档测一遍几秒钟的事。4.3 驱动负载失败不是引脚坏了而是电流不够如果你接一个继电器模块、小电机或者舵机发现不工作第一反应不要怀疑树莓派坏了大概率是电流不够。GPIO引脚只能输出十几毫安直接驱动继电器线圈、电机这类负载肯定不行。传统做法是加一只三极管比如S8050、BC337做开关或者用MOS管也可以直接用集成驱动模块。市面上的继电器模块一般有两种一种支持3.3V逻辑电平直接触发另一种需要5V高电平才能可靠触发。买的时候看清参数或者直接用低电平触发模块把模块的GND和IN引脚接好用GPIO输出低电平来控制通断这样反而稳。直流电机驱动建议用L298N、TB6612这类模块或者直接买一块树莓派小车底盘套件里面通常带了驱动板和电源方案。舵机则需要20ms周期、1到2ms脉宽的PWM信号gpiozero里有现成的Servo类但信号线千万不要直接接5V舵机电源舵机电源要单独供电。还有一个很多新手会问的问题GPIO不够用怎么办。两种思路一是用I2C扩展IO芯片比如PCF8574能扩出8路IOMCP23017能扩出16路I2C地址还能通过跳线配置一个I2C总线上可以挂好几个二是用带串口转GPIO功能的扩展模块通过UART和主控通信。树莓派的I2C和UART都是硬件接口速率也不差做多路控制完全够用。5. GPIO之上还能玩些什么5.1 从GPIO到I2C、SPI、UART三个方向都是新世界GPIO掌握之后树莓派的外设世界才算真正打开。常见方向有三个做感知接人体红外传感器、温湿度传感器、超声波测距模块核心都是读输入信号。传感器有的输出数字高低电平有的通过I2C或UART返回数据前者用GPIO输入检测就够了后者要学对应协议。做控制接继电器、电机驱动、舵机核心是输出合适的电平和PWM。直流电机的转速用PWM调舵机角度用特定脉宽的PWM信号控制这些在gpiozero里都有现成接口但底层原理还是GPIO输出。做通信I2C、SPI、UART。树莓派4B上的I2C引脚是GPIO2和GPIO3SPI引脚是GPIO8到GPIO11UART引脚是GPIO14和GPIO15。用对了设备GPIO就不仅仅是开关电平而是能挂出一整条外设总线接几十个传感器、显示屏、扩展芯片都不在话下。我个人的经验是先把LED和按键玩熟然后做一个小项目比如按键切换呼吸灯颜色或者用GPIO读取按键次数并LCD显示再一步一步往I2C和SPI推进。有具体项目拉扯着学起来比对着文档啃快得多。5.2 几条我个人认为最有用的实操习惯最后分享几条我自己踩坑踩出来的习惯。第一条每次接线前先跑一遍pinout命令确认脑子里的引脚编号和板子实际布局一致尤其换了一台树莓派之后不同型号的40针定义有细微差别别想当然。第二条接线的顺序是先断电再接线接完检查一遍最后上电。带电插拔虽然大多数时候没问题但长期下来引脚容易接触不良而且如果线接错烧芯片的概率会大很多。第三条用彩色杜邦线区分功能红色接5V、橙色接3.3V、黑色接地、其他颜色走信号。排查问题的时候这套颜色习惯能让你一眼看清线路走向。GPIO看起来只是简单的电平操作但它把软件和硬件打通了。点亮那颗LED的时候你从单纯写代码变成了真正在控制一块硬件这个门槛跨过去后面玩什么都有底气。我整理这篇笔记时也重新把基础过了一遍最大感受是树莓派的GPIO不难难的是建立先看原理图、再写代码的习惯。很多初学者喜欢上来就抄代码LED不亮就不知道问题在哪。其实先花30秒确认线路再花30秒确认引脚编号能省下后面一小时的排查时间。你要是刚把树莓派4B的系统装好下一步就照着这篇把它点亮一个灯。点亮的那一刻你和树莓派之间就不只是用户和电脑的关系了。后面还有I2C传感器、PWM舵机、各种驱动模块等着你去折腾到时候你会发现GPIO就是所有这些玩法的入口。
返回列表