
1. 引脚图的真正难点不在图上而在三套坐标的互相翻译很多人拿到一块 Arduino Nano第一反应是找一张引脚分配图对着丝印一根一根往上接。接完上电程序不跑或者某个传感器读数乱跳于是回头再看图发现图上写的 D2 和代码里的 2 是两个概念A4 和 SDA 又是同一个脚的两个身份。引脚图本身不难难的是你脑子里要同时装下三套坐标系并且随时能把它们对上号。第一套是物理坐标板上那两排各 15 个孔从 USB 口那一端往另一端的第几个位置。第二套是逻辑坐标D0 到 D13、A0 到 A7这是印在板子丝印上、写在程序里最常用的那套名字。第三套是芯片坐标ATmega328P 这颗芯片内部的端口寄存器PD0 到 PD7、PB0 到 PB5、PC0 到 PC5。烧进芯片的每一条指令只认第三套编译器和底层库负责把第二套翻译成第三套而你手上的杜邦线接的是第一套。这三套坐标一旦错位症状往往不是不亮这么仁慈而是偶尔能用、偶尔抽风。比如有人把 A6 当数字输出用编译能过下载成功接上 LED 就是不亮——因为 A6 在芯片上压根没有输出驱动器。这类问题靠猜是猜不出来的只能靠把引脚定义吃透。这篇内容面向的是已经上手过几天、手里有板子、想把它真正用明白的人也适合刚开始画扩展板、做模块化接线、需要一次性把引脚规划清楚的读者。下面按先分清版本、再搞定电源、剩下按功能分组的顺序往下走中间会穿插大量实际接线时的取舍和坑点。1.1 从丝印到寄存器一次完整的翻译过程拿最普通的一句代码举例digitalWrite(5, HIGH);。编译器先把常量 5 这条信息交给底层库底层库内部维护着一张映射表把它换算成芯片的 PB1 端口和对应的位。接着生成的机器指令去操作 ATmega328P 的 PORTB 寄存器把第 1 位置 1。最终电平从芯片第 15 号物理焊球出来经过板子的铜箔走到排针上的 D5 那个孔。这条链路里有两个容易出事的点。第一个是端口号不等于引脚序号。ATmega328P 的三个端口每个只有 8 位PB 端口的位 0 对应 D8位 5 对应 D13中间没有任何连续性可言。做过 AVR 裸机开发的人都知道直接写PORTB | (15)点的是 D13 上的板载 LED和 D5 一个字节的关系都没有。第二个是模拟口的命名重叠。A0 到 A5 在芯片上是 PC0 到 PC5它们既能读模拟量也能做数字口而 A6、A7 是独立的 ADC6、ADC7只挂在模拟多路复用器上没有数字驱动电路。下面这张表把三套坐标对齐建议打印出来贴在工位边上丝印芯片端口复用功能能否 digitalWrite能否 analogReadD0PD0RXD 串口接收是否D1PD1TXD 串口发送是否D2PD2INT0 外部中断是否D3PD3INT1 中断 / OC2B PWM是否D4PD4T0 定时器输入是否D5PD5OC0B PWM / T1是否D6PD6OC0A PWM / AIN0是否D7PD7AIN1 比较器输入是否D8PB0ICP1 输入捕获是否D9PB1OC1A PWM是否D10PB2SS 片选 / OC1B PWM是否D11PB3MOSI / OC2A PWM是否D12PB4MISO是否D13PB5SCK / 板载 LED是否A0–A5PC0–PC5ADC0–ADC5A4SDAA5SCL是是A6、A7ADC6、ADC7仅模拟输入否是看这张表的时候注意一个细节D0 到 D13 里其实包含了两个完全不同的端口组PORTD 管 D0–D7PORTB 管 D8–D13。这就是为什么有人尝试用PORTD整字节操作来控制 8 个 LED 时会发现只有低 8 个引脚响应——另外 6 个在另一个寄存器里。1.2 三个版本长得一样引脚定义差得不少市面上流通的 Nano 大致有三条产品线外形尺寸和排针位置基本一致插到同一块底板上毫无违和感但电气特性和部分引脚定义并不通用。这一点在做可替换设计的时候必须先确认清楚。经典款用的是 ATmega328P5V 逻辑引脚定义就是上面那张表。它的模拟口只有 A0–A5 具备完整数字能力A6、A7 是残缺的。后面有一个变体把主控换成了另一款 8 位芯片引脚位置刻意做成兼容但 A0–A7 八个口全部可以用作数字 I/OPWM 通道的分布也变了原来的 D3、D5、D6、D9、D10、D11 这六个 PWM 位置不再是全部新的排布里 PWM 更多但位置不同。如果你写的程序里写死了analogWrite(3, x)换板子之后可能变成一声不吭的状态。再往上是 32 位的那两条线一颗是 ARM 内核一颗是带无线功能的 SoC。这两类板子最大的变化是逻辑电平从 5V 变成了 3.3V而且引脚耐压只有 3.3V。把经典款上跑得好好的 5V 传感器直接插上去轻则读数不对重则当场废掉一个引脚甚至整块板。它们的模拟分辨率也从 10 位提到了 12 位同样的代码analogRead()返回值范围从 0–1023 变成 0–4095所有涉及阈值的判断都得重新标定。特性经典款328P8 位改进款32 位款逻辑电平5V5V3.3VADC 分辨率10 位10 位12 位A6/A7 数字能力无有有PWM 引脚数6更多更多单脚电流上限约 40mA极限约 40mA约 7mA3V3 引脚来源板载串口芯片板载稳压主稳压输出最后一行值得单独说一句。经典款的 3V3 引脚来自板载的 USB 转串口芯片内部稳压器能拿出来的电流只有几十毫安接一个低功耗传感器勉强够接屏幕或者无线模块立刻掉压。要做 3.3V 供电的外设老实外挂一颗 LDO别指望这个脚。而 32 位款上的 3V3 是主稳压器直接出来的能撑几百毫安完全不是一回事。2. 电源与地这几个脚是烧板事故的高发区新手烧板的原因排第一的不是接错信号线而是电源接反或者电压送错位置。Nano 上跟电源相关的引脚一共就那么几个但每一个的脾气都不一样混着用很容易出事。这一节把 VIN、5V、3V3、AREF、RESET 这几个非 I/O 引脚单独拎出来讲透。2.1 VIN 与 5V谁给谁供电方向不能反VIN 是外部电源输入端板载稳压器把 7–12V 这个区间的电压降到 5V 供全板使用。这个脚接的是稳压器的输入绝不能往外输出大电流——它本质上是入口不是出口。很多人误以为 VIN 可以拿来给外部 12V 设备供电实测下来电压会被拉垮稳压器还会发烫。5V 脚是双向的这一点最容易踩坑。用 USB 供电的时候5V 脚上有电可以抽出来给外部小电流设备用但如果外部已经有一个稳定的 5V 电源也可以直接接到 5V 脚上给板子供电绕过稳压器。问题在于这两个来源不能同时硬接。板子上有一个自动切换电路USB 插入时优先用 USB 的电但同时从 5V 脚灌入外部电源会造成两个电源顶牛轻则稳压器发热重则 USB 口那边的主机保护甚至损坏。我的做法是外接电源的时候要么走 VIN 让它过稳压器要么走 5V 脚并且拔掉 USB 线。绝对不要出现一边插着 USB 调试、一边从 5V 脚灌电的状态。真要边调试边外供电就在 USB 的 5V 线上加一个肖特基二极管做隔离或者干脆用带电源切换的底板。还有一个细节VIN 的可用范围虽然标称很宽但压差越大稳压器发热越严重。输入 12V、板子带一个 200mA 的负载稳压器上就要白白消耗掉约 1.4W那颗小封装芯片撑不住会热保护。我的经验是输入电压尽量控制在 7–9V超过 10V 就得考虑负载和散热了。2.2 RESET、AREF 与两个 GND各有各的讲究RESET 脚内部有上拉低电平触发复位。板上已经引出了一个复位按键和一个串联电容接到串口芯片的 DTR 信号上用来实现下载程序时自动复位。如果你要外接复位按键直接把这个脚拉低就行但不要在外部再并一个大电容否则会和原有的复位电容一起构成 RC 延迟导致下载程序时复位时序错乱出现下载器找不到板子的玄学问题。AREF 是模拟参考电压输入。默认情况下模拟读数的基准是芯片的供电电压5V10 位分辨率下每一格大约 4.9mV。如果想让读数更精确可以在 AREF 脚上加一个精密基准源然后在程序里指定外部参考。这里有个顺序问题必须先配置参考源再去读而且要避开芯片内部的 1.1V 参考和外部 AREF 同时启用的冲突那会把两个参考源顶在一起。用内部 1.1V 参考时AREF 脚悬空即可不要接任何电压。两个 GND 脚在物理上是连通的接一个就够用。但在实际布线里两个都用上会明显降低接触不良的概率——尤其是用排线接多个模块的时候一根地线松了整条链路都废两根地线是廉价的冗余。模拟测量精度要求高的场合还应该把传感器的地和板子的地单独拉一根线避开电机、继电器这类大电流负载的回流路径。3. 数字引脚 D0–D13哪些脚能随便用哪些脚一碰就出事14 个数字脚看着挺多真正能自由支配的其实不到一半。串口占了两个外部中断占了两个SPI 占了四个I2C 占了两个PWM 占了六个还有一个是板载 LED。这些功能是叠加在同一批物理引脚上的一个脚往往有三四重身份用之前得先看清楚有没有冲突。3.1 串口与中断两个最该被保护起来的脚D0 和 D1 分别是串口的接收和发送它们直接连到板载的 USB 转串口芯片上。这意味着两件事第一每次下载程序这两个脚上都有数据在跑如果你在这两个脚上接了外部设备下载时会产生干扰甚至失败第二程序里的Serial.print()输出的内容会直接经过这两个脚跑到电脑上任何接在上面的外设都会收到一串莫名其妙的电平跳变。我的习惯是把 D0、D1 当成调试专用脚永远不接负载。需要第二路串口的时候用软件模拟串口指定到 D10、D11 这类空闲脚上。软件模拟串口在低波特率9600 到 19200下用起来没大问题但它很吃中断响应时间如果程序里还有别的中断在跑偶尔会丢字节。速率往上提就得换成硬件串口或者干脆上多串口的方案。D2 和 D3 是仅有的两个硬件外部中断脚分别对应 INT0 和 INT1。编码器、霍尔传感器、按键唤醒这类需要立刻响应的信号接这两个脚最省心中断响应延迟只有几个时钟周期。如果这两个脚被占了其他脚也不是不能做中断芯片支持引脚变化中断把同一端口的 8 个脚编成一组任一引脚变化都能触发但代价是你在中断服务函数里还得自己判断是哪个脚变了响应也慢一些。这在低速场景能用高速脉冲计数就不行了。3.2 PWM、SPI 与 I2C 的落点别随手挪动六个 PWM 脚分布在三个定时器上D5、D6 归 Timer0D9、D10 归 Timer1D3、D11 归 Timer2。这个分配关系平时看不出来一旦你引入了舵机库或者别的会占用定时器的库问题立刻显现——舵机库默认接管 Timer1接上去之后 D9、D10 的 PWM 输出就废了analogWrite()写进去没有任何反应但也不会报错。更隐蔽的是 Timer0。它同时负责系统计时millis()、micros()、delay()全都靠它。如果你手动改了 Timer0 的分频系数来调 PWM 频率millis()的计时就会跟着失真跑十分钟慢半分钟这种情况非常典型。我一般的原则是Timer0 只读不改需要非标准频率的 PWM宁可挪到 Timer1 或 Timer2 上或者上外部专用芯片。I2C 落在 A4SDA和 A5SCL上这是硬件 TWI 的唯一落点不能改。好处是这两个脚同时也能当模拟输入用屏幕和传感器不冲突。SPI 落在 D10 到 D13 上其中 D10 是片选可以改成别的脚D11、D12、D13 这三根是硬件 SPI 的固定引脚动不了。很多人把 SPI 屏幕接上之后发现 D13 上的板载 LED 一直微微闪那不是故障是数据在 SCK 上跑板载 LED 通过一个限流电阻挂在同一个节点上纯属正常现象。功能组占用引脚能否改用其他脚常见冲突硬件串口D0、D1否接外设导致下载失败外部中断D2、D3引脚变化中断可替代编码器与舵机同时使用硬件 I2CA4、A5否与模拟输入共用无冲突硬件 SPID11、D12、D13否D13 板载 LED 干扰观察PWMD3、D5、D6、D9、D10、D11是舵机库占用 Timer14. 模拟输入 A0–A7十位精度背后藏着的几个陷阱八路模拟输入看起来是白送的功能直接analogRead()就能读数。但读数准不准、跳不跳、能不能信取决于参考电压、信号源阻抗、布线方式这几个因素和引脚本身关系不大。这一段把模拟侧的几个关键点拆开讲。4.1 十位分辨率的真实含义十位 ADC 意味着把参考电压切成 1024 份。以默认的 5V 参考计算每一份约 4.88mV。也就是说一个 1mV 的变化在读数上根本体现不出来数值会在两个相邻值之间来回跳。想让小信号变化被看清有两条路换用内部 1.1V 参考把量程压到 1.1V每一份降到约 1.07mV或者在前端加一级运放把信号放大。内部参考的代价是量程被限制住了输入电压不能超过 1.1V 太多超了读数直接饱和到 1023而且过压还可能损伤引脚。我的做法是测热电偶、测电桥这类毫伏级信号用内部参考加前级放大测电池电压、测电位器这类伏特级信号用默认的 5V 参考简单可靠。另一个容易被忽略的是采样时间。芯片内部的采样保持电路需要一个充电过程信号源内阻越大充电越慢。数据手册给出的建议是信号源阻抗控制在 10kΩ 以内超过这个值读数会明显偏低且不稳定。用一个 100kΩ 的电位器分压直接接进去转轴的中间位置读数会飘这不是板子坏了是阻抗不匹配。解决办法是在中间抽头和地之间并一个 0.1μF 电容或者加一级电压跟随器。4.2 A6 和 A7 是半残的脚用之前必须知道这两个脚只在模拟多路复用器上有通道芯片内部没有连接数字输出驱动器也没有内部上拉电阻。表现为编译digitalWrite(A6, HIGH)不会报错但引脚没有任何输出编译pinMode(A6, INPUT_PULLUP)不会报错但上拉不生效读数会乱飘analogRead(A6)正常工作和 A0 没区别。这个特性在做八路模拟采集的项目里会突然咬你一口。比如你做了八路光敏电阻采集前六路一点问题没有后两路要么恒为 0 要么乱跳查半天代码没毛病最后发现是给 A6、A7 打开了内部上拉——那个调用对它们完全无效输入悬空读数自然是一片噪声。我的建议很直接A6、A7 只接模拟信号源而且要保证信号源是低阻抗的不接就接地或者接一个确定的分压。需要八路都可配置成数字口的场合直接换 32 位款的板子省去所有麻烦。引脚数字输出内部上拉模拟输入建议用途A0–A5支持支持支持通用可灵活切换A6不支持不支持支持纯模拟传感器专用5. 图上不会画的那些限制电流、上电状态与保护引脚分配图标的是这个脚叫什么、能干什么它不会告诉你这个脚最多能吐多少电流、上电那一瞬间它是什么电平。而实际项目里翻车的往往就是这些没画在图上的东西。5.1 单脚与整片的电流红线芯片手册写的绝对最大额定值是每个 I/O 脚 40mA整个芯片所有 I/O 加起来通过 VCC 和 GND 的总电流不超过 200mA。这两个数字是极限值不是工作值。真正长期稳定工作的推荐值是单脚 20mA 以内。拿这个标准去衡量常见负载一颗普通 5mm LED 直连串 220Ω 电阻电流约 15mA踩在安全线上八颗 LED 同时点亮就是 120mA已经吃掉了整片的一大半预算一个 5V 继电器模块的输入电流通常在 60–80mA直接接引脚长期跑那个脚的驱动管会慢慢老化。我的处理方式是超过 20mA 的负载一律上三极管或者 MOSFET引脚只负责给控制信号。这不是保守是修过太多用了一个月突然某个脚不工作了的板子之后形成的条件反射。还有一个容易被忽略的是灌电流和拉电流的不对称。芯片引脚拉高时输出电流的能力比拉低时灌入电流的能力略弱驱动 LED 时如果接成引脚输出高电平点亮亮度会稍微低一点。更常见的做法是接成低电平点亮把 LED 的正极接 5V负极串电阻接引脚这样引脚只需要往下灌电流。5.2 上电瞬间的引脚状态ATmega328P 复位之后所有引脚默认是高阻输入状态除了少数几个有特殊默认值的。这意味着上电的一瞬间你的继电器、电机驱动、LED 都不会有确定电平可能因为外部干扰出现短暂的误动作。驱动大功率负载的场合这个瞬间误动作可能是灾难性的。解决办法是在硬件上给关键控制脚加一个下拉电阻10kΩ 到地保证上电期间是确定低电平程序里初始化完成之后再切成输出。我做过一个控制水泵的项目早期版本没有加下拉每次上电水泵都会抽一下虽然只有几百毫秒但长期下来对管路是个损耗。加了 10kΩ 下拉之后彻底干净了。D13 那个脚还有个特殊性板上通过一个 1kΩ 电阻接了 LED 到地。当你把 D13 配置成输入并打开内部上拉时这个 LED 会形成一条额外的通路影响读取外部开关的状态。做按键输入的时候避开 D13能省掉一堆莫名其妙的调试时间。6. 把引脚表变成自己的接线规划一次实际的分配推演光看表没用真正有价值的是在动手之前把整个项目的引脚占用列清楚标注冲突预留余量。这一节用一个典型的多传感器采集项目走一遍完整流程顺便说说接线错误该怎么按顺序排查。6.1 一个多外设项目的引脚分配过程假设要做的是一个环境监测节点一个 I2C 的温湿度传感器、一个 SPI 的存储芯片、一路电池电压检测、一个蜂鸣器报警、一个按键、一个状态 LED外加串口回传数据。先把不可协商的固定下来。I2C 占 A4、A5SPI 占 D11、D12、D13片选可以挪到 D10串口占 D0、D1不接任何东西电池电压检测用 A0因为 A0 是模拟口里最靠前、走线最短的。到这里已经用掉了 A0、A4、A5、D0、D1、D10、D11、D12、D13。接着排可选的。按键需要中断唤醒放 D2用 INT0蜂鸣器需要 PWM 调音放 D9用 Timer1 的通道 A状态 LED 放 D8普通数字输出就够。剩下 D3、D4、D5、D6、D7、A1、A2、A3、A6、A7 全部空闲作为预留。这里有个取舍值得说蜂鸣器为什么放 D9 而不是 D5因为 D5 和 D6 归 Timer0一旦有别的库介入 Timer0蜂鸣器音调会跟着变甚至millis()一起受影响。D9 归 Timer1独立性强代价是舵机库也用 Timer1将来要加舵机就得二选一。想清楚未来可能加什么比当下能不能跑通更重要。外设占用引脚理由备注温湿度传感器A4、A5硬件 I2C 唯一落点需 4.7k 上拉存储芯片D10–D13硬件 SPID10 为片选电池检测A0模拟输入分压后接入分压电阻控制在 10k 内按键D2硬件中断唤醒外部 10k 下拉蜂鸣器D9Timer1 PWM避开 Timer0状态灯D8普通输出串 220Ω串口调试D0、D1固定不接外设6.2 接线出问题时的排查顺序接线错了症状千奇百怪但排查顺序可以固定下来按这个顺序走能省掉大量时间。第一步先量电源。万用表打到直流电压档红笔接 5V 脚黑笔接地应该是稳定的 4.9–5.1V。低于 4.7V 说明负载太重或者供电不足先把电源问题解决别急着看信号。第二步断开所有外设只留 USB 线跑一个最简单的闪灯程序确认板子和工具链是好的。第三步一根一根接外设每接一根就测一次接第三根出问题就说明是第三根的事别一次全插上去再查。第四步才是看代码逻辑。最常见的三个错误按出现频率排一是 I2C 设备没有共地两块板子各自供电但地线没连通信时好时坏二是 SPI 的 MOSI 和 MISO 接反读出来的永远是 0xFF三是把 5V 器件的信号线直接接到 3.3V 板子的输入脚上开始能用几天后那个脚就彻底死了。还有一个我自己踩过不止一次的坑面包板上的电源轨断裂。很多面包板的电源轨中间是断开的看起来是一整条实际左右不通。用万用表通断档量一下两秒钟的事能救半小时。最后分享一个习惯每做一个项目就在纸上或者文档里画一张自己的引脚占用表标清楚每个脚接了什么、为什么这么接、还有哪些空闲。下次拆开重做的时候这张表比任何引脚图都管用因为它记录的是你这个项目的具体上下文而不是芯片的通用规格。