发布时间:2026/7/20 14:02:54
1. SPI接口基础与TMS320F280013x模块概览串行外设接口也就是我们常说的SPI几乎是每个嵌入式工程师在项目里都绕不开的通信协议。它不像I2C那样需要复杂的地址管理也不像UART那样依赖精确的波特率匹配SPI的核心就是简单、直接、高速。在需要快速、稳定传输数据的场景下比如驱动TFT屏幕、读写Flash存储器、或者与高速ADC/DAC芯片通信SPI往往是首选。今天我们就以德州仪器TI的TMS320F280013x系列微控制器为例深入拆解SPI模块从硬件原理到寄存器配置再到实际应用编程的全过程。如果你正在使用C2000系列DSP或者对SPI底层运作机制感兴趣这篇文章会帮你把那些数据手册里零散的知识点串联起来形成一套可实操、可调试的完整认知。TMS320F280013x的SPI模块是一个功能相当齐全的同步串行通信引擎。它支持经典的主从模式数据位宽可以在1到16位之间灵活配置最高通信速率理论上可达低速外设时钟LSPCLK的四分之一。模块内部集成了16级深度的发送和接收FIFO这在实际项目中是个巨大的优势能有效减轻CPU频繁响应中断的负担让CPU有更多时间处理核心算法。模块提供了四种时钟模式通过时钟极性CLKPOLARITY和时钟相位CLK_PHASE两个比特位的组合可以适配市面上绝大多数SPI从设备如传感器、存储器的时序要求。此外它还支持三线制模式以节省引脚以及针对特定应用优化的高速模式。理解这些特性是进行高效、可靠SPI通信开发的第一步。2. SPI核心工作原理与操作模式深度解析2.1 主从架构与数据流SPI通信的本质是一个环形移位寄存器。一个主设备Master和一个或多个从设备Slave通过四根线连接主设备输出从设备输入MOSI或SPISIMO、主设备输入从设备输出MISO或SPISOMI、串行时钟SCLK或SPICLK和从设备片选CS或SPISTE。主设备完全掌控时钟线SCLK的生成数据在时钟边沿进行同步移入和移出。这是一个全双工过程主设备通过MOSI线发送数据位的同时也从MISO线接收来自从设备的数据位。这意味着每一次通信交换都是主从双方同时完成一次数据的发送和接收。在TMS320F280013x中数据流的核心是SPIDAT寄存器它是一个16位的移位寄存器。当CPU或DMA将待发送数据写入发送缓冲器SPITXBUF后在适当的时机例如上一个字符发送完成数据会自动加载到SPIDAT中。随后在SPICLK时钟的驱动下数据从SPIDAT的最高位MSB或最低位LSB取决于配置开始逐位移出到SPISIMO主模式或SPISOMI从模式引脚。同时对方设备发送来的数据位也从对应的输入引脚同步移入SPIDAT的最低位。当一个完整字符1-16位传输完毕SPIDAT中的全部内容此时是接收到的数据会被复制到接收缓冲器SPIRXBUF中并置位中断标志等待CPU读取。这个过程是硬件自动完成的软件只需要关注数据的准备和提取。2.2 主模式Master Mode运作细节将SPI配置为主模式MASTER_SLAVE 1后你的MCU就成为了总线上的“指挥家”。它不仅负责产生SPICLK时钟信号还通过SPISTE引脚来控制从设备的使能。在向特定从设备发起通信前你需要先将对应的SPISTE引脚拉低有效通信结束后再拉高。主模式的波特率由SPIBRR寄存器决定。计算公式分为两段当SPIBRR值为0、1或2时波特率固定为LSPCLK/4当SPIBRR值在3到127之间时波特率 LSPCLK / (SPIBRR 1)。这里的LSPCLK是系统的低速外设时钟你需要根据你的系统时钟配置来确认其具体频率。例如若LSPCLK为50MHzSPIBRR设置为3则波特率为 50MHz / (31) 12.5 Mbps。注意计算出的波特率绝对不能超过芯片数据手册中规定的GPIO最大翻转频率。过高的速率会导致信号失真通信失败。在高速通信时还需要注意PCB布线的阻抗匹配和信号完整性。数据传输的启动很简单向SPITXBUF写入数据即可。如果此时移位寄存器SPIDAT空闲数据会立刻加载并开始发送。如果SPIDAT正忙数据会暂存在SPITXBUF中等待当前传输结束。主设备可以连续写入多个数据到FIFO硬件会自动按序发送这为大数据量传输提供了便利。2.3 从模式Slave Mode运作细节与同步要点在从模式MASTER_SLAVE 0下SPI模块变得“被动”。SPICLK时钟信号需要由外部主设备提供并且输入时钟频率不能超过LSPCLK/4。数据通过SPISIMO引脚输入通过SPISOMI引脚输出。从设备的一个关键控制位是TALK位于SPICTL1寄存器。只有当TALK位为1时从设备的SPISOMI输出才被激活否则该引脚呈高阻态。这允许多个从设备共享MISO总线主设备通过不同的SPISTE片选信号来选择当前与哪个从设备通信。特别需要注意的是如果在传输中途清零TALK位当前正在传输的字符仍会完整发送完毕以确保总线时序不乱之后输出才进入高阻态。SPISTE引脚在从模式下作为片选输入。当SPISTE为低电平时从设备被选中可以正常收发数据当其为高电平时从设备的移位寄存器会停止输出变为高阻态。这为防止总线冲突提供了硬件保障。这里有一个重要的实践经验不要简单地将SPISTE引脚直接永久接地强制有效。虽然这样从设备会一直处于被选中的“待命”状态看似简化了电路但一旦总线上有多个从设备或者主设备初始化时产生毛刺时钟就极易导致从设备内部移位计数器与主设备不同步造成后续所有通信错位。正确的做法是让主设备严格在通信前后控制SPISTE信号。2.4 四种时钟模式Clock Mode的选择与实践时钟极性CLKPOLARITY CPOL和时钟相位CLK_PHASE CPHA的组合产生了SPI的四种标准时钟模式Mode 0, 1, 2, 3。这是SPI配置中最容易混淆但也最关键的一环。模式0 (CPOL0 CPHA0)时钟空闲时为低电平。数据在时钟的上升沿被采样捕获在下降沿发生变化输出。这是最常见的一种模式。模式1 (CPOL0 CPHA1)时钟空闲时为低电平。数据在时钟的下降沿被采样在上升沿发生变化。模式2 (CPOL1 CPHA0)时钟空闲时为高电平。数据在时钟的下降沿被采样在上升沿发生变化。模式3 (CPOL1 CPHA1)时钟空闲时为高电平。数据在时钟的上升沿被采样在下降沿发生变化。“采样”对于接收方而言就是锁存数据的时刻“变化”对于发送方而言就是数据位送到引脚上的时刻。选择哪种模式完全取决于你的从设备传感器、Flash芯片等的数据手册要求。务必保证主从设备的时钟模式配置一致否则无法正确通信。一个快速判断的方法是观察从设备时序图看它的数据输入DI要求在哪个时钟边沿保持稳定Setup Hold那个边沿就是主设备输出数据的变化沿而从设备数据输出DO变化的边沿就是主设备的采样沿。在TMS320F280013x中当波特率分频系数SPIBRR1为奇数且大于3时SPICLK的占空比会不对称。例如CPOL1时高电平脉冲会比低电平脉冲多一个LSPCLK周期。在驱动某些对时钟占空比敏感的高速器件时需要留意这个特性尽量选择使SPIBRR1为偶数的分频值以获得对称的时钟信号。3. TMS320F280013x SPI高级功能与寄存器精讲3.1 FIFO功能详解与中断配置策略FIFO先入先出缓冲区是提升SPI通信效率的核心武器。TMS320F280013x的SPI模块包含了两个16×16位的FIFO分别用于发送和接收。使能FIFO设置SPIFFTX寄存器中的SPIFFENA位后传统的单缓冲区模型升级为FIFO模型中断机制也发生了变化。非FIFO模式只有一个中断源SPIINT。无论是发送缓冲空SPITXBUF数据已加载到SPIDAT还是接收缓冲满SPIRXBUF收到新数据亦或是接收溢出错误都通过这一个中断信号通知CPU。软件需要在中断服务程序中查询状态位来判断具体事件。FIFO模式发送和接收中断分离为SPITXINT和SPIRXINT。更重要的是中断触发条件变得可编程且更智能。发送中断SPITXINT当发送FIFO中的剩余数据量TXFFST小于或等于预设的触发水平TXFFIL时触发中断。例如设置TXFFIL0则发送FIFO一空就立即产生中断让CPU及时补充数据适合低延迟场景。设置TXFFIL8则等到FIFO里只剩8个字或更少时才中断可以减少中断频率适合批量传输。接收中断SPIRXINT当接收FIFO中积累的数据量RXFFST大于或等于预设的触发水平RXFFIL时触发中断。例如设置RXFFIL16则等到FIFO完全填满16个字才产生一次中断CPU一次性读取大量数据效率最高。设置RXFFIL1则每收到一个字就中断响应最及时。这种可编程中断水平机制允许你在中断响应速度和CPU占用率之间做精细的权衡。对于高速连续数据流建议将RXFFIL设置得较高如12-14TXFFIL设置得较低如2-4以实现“大块读、小块补”的高效流水线操作。3.2 延迟传输控制SPIFFCT寄存器的应用SPIFFCT寄存器中的FFTXDLY[7:0]位域提供了一个极为实用的功能可编程发送延迟。它定义了从发送FIFO传输一个字到发送移位寄存器SPIDAT之间需要间隔多少个SPICLK周期。这个功能的主要价值在于“粘合”不同速度的器件。举个例子很多SPI接口的EEPROM如25系列Flash在完成一个字节的写入后需要几微秒到几毫秒的“页编程时间”t_W在此期间芯片不响应任何命令。如果你以最高速率连续发送写入命令和数据会导致失败。有了可编程延迟你可以这样操作假设SPI时钟为1MHz周期1usEEPROM的页编程时间t_W5ms。你可以将FFTXDLY设置为一个较大的值比如200但这仍然只有200us。更好的方法是利用延迟并结合软件查询。更常见的用法是驱动那些需要CS片选在两个字节间保持一段时间低电平的器件或者单纯为了降低总线速率以匹配低速从设备。设置FFTXDLY0则FIFO中的字会背靠背back-to-back连续发送实现最大吞吐量。3.3 仿真挂起行为控制SCIPRI寄存器解析在调试阶段我们经常需要在代码中设置断点。当CPU因断点而挂起Emulation Suspend时外设的行为该如何定义这就是SCIPRI寄存器系统控制中断优先级寄存器中FREESOFT位域的作用。它决定了仿真事件发生时SPI模块是立即停止还是完成当前操作后再停止或是自由运行。00b (立即停止)一旦调试器触发挂起事件SPI模块立即停止时钟和数据传输。这可能导致一个不完整的数据帧被发送出去从设备可能收到错误数据。在调试通信协议时慎用。01b (完成当前收/发序列后停止)这是最安全、最推荐的调试设置。SPI模块会完成当前正在进行的整个字符1-16位的传输和接收然后再进入挂起状态。这保证了数据帧的完整性便于你观察一次完整通信后的总线状态和寄存器值。10b 或 11b (自由运行)仿真挂起事件被忽略SPI模块继续正常运行。这在调试系统其他部分如控制算法而不希望SPI通信可能是用于数据采集被中断时非常有用。我的经验是在开发SPI驱动和调试通信逻辑时务必将其设置为“01b”。我曾经遇到过因为使用默认值或“00b”导致在断点查看接收缓冲区时数据总是少一位或错位排查了很久才发现是断点打断了移位过程。设置为“01b”后问题迎刃而解调试体验顺畅很多。3.4 三线制SPI模式TRIWIRE节省引脚资源标准SPI需要4根线。但在一些点对点通信且只需要半双工或单向通信的场景下三线制模式可以节省一个宝贵的GPIO引脚。通过设置SPIPRI寄存器的TRIWIRE位为1来启用此模式。主设备三线模式SPISIMO引脚变为双向的SPIMOMI引脚负责数据的发送和接收。SPISOMI引脚不再被SPI模块使用可复用为普通GPIO。此时TALK位控制数据方向TALK1时引脚为输出发送TALK0时引脚为输入接收。进行读操作前软件需要先清零TALK然后向SPIDAT写入一个哑元dummy数据来产生时钟从而将从设备的数据读入。从设备三线模式SPISOMI引脚变为双向的SPISISO引脚。SPISIMO引脚被释放。需要注意的是在三线模式下由于收发共用一根数据线SPI模块自己发送的数据也会被自己接收回来。这意味着每次你发送一个字节接收缓冲区也会收到一个字节通常是你刚发送的数据的回环。因此在发送有效数据后通常需要做一次“哑读”来清除接收缓冲区中的这个回环数据才能得到从设备真正的回复。4. SPI模块的软件驱动与实战编程指南4.1 初始化配置流程与关键函数TI为C2000系列提供了完善的DriverLib库将底层寄存器操作封装成了易用的API。下面是一个典型的SPI主模式初始化流程结合寄存器操作和DriverLib函数进行说明使能外设时钟首先需要使能SPI模块所在的外设时钟。通过设置PCLKCR寄存器相应的位来完成。// 使用DriverLib使能SPI-A外设时钟 SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SPIA);配置GPIO复用功能将所用引脚SPISIMO, SPISOMI, SPICLK, SPISTE从普通GPIO模式复用到SPI功能。务必遵循数据手册的建议顺序先配置GPyGMUX如果存在再配置GPyMUX以避免引脚出现瞬时毛刺。// 假设使用GPIO16为SPISIMOA, GPIO17为SPISOMIA, GPIO18为SPICLKA, GPIO19为SPISTEA GPIO_setPinConfig(GPIO_16_SPISIMOA); GPIO_setPinConfig(GPIO_17_SPISOMIA); GPIO_setPinConfig(GPIO_18_SPICLKA); GPIO_setPinConfig(GPIO_19_SPISTEA); // 同时根据需要配置引脚的上下拉电阻GPyPUD和输入量化GPxQSELn GPIO_setPadConfig(16, GPIO_PIN_TYPE_PULLUP); // 使能内部上拉 GPIO_setQualificationMode(16, GPIO_QUAL_ASYNC); // 输入信号异步模式无滤波SPI模块基本参数配置这是核心步骤通过SCI_setConfig注意此函数名可能是文档笔误应为SPI_setConfig实际DriverLib中对应SPI_setConfig或分别设置各个寄存器来完成。SPI_Handle spiHandle SPI_init((void *)SPIA_BASE, sizeof(SPI_Obj)); // 配置为主模式、8位数据、模式0时钟、1MHz波特率假设LSPCLK50MHz SPI_setMode(spiHandle, SPI_MODE_MASTER); SPI_setCharLength(spiHandle, SPI_CHAR_LENGTH_8); // 设置数据位为8位 SPI_setClkPolarity(spiHandle, SPI_CLK_POLARITY_RISING_EDGE); // CPOL0 SPI_setClkPhase(spiHandle, SPI_CLK_PHASE_0); // CPHA0 // 计算并设置波特率SPIBRR LSPCLK / BaudRate - 1 50e6 / 1e6 - 1 49 SPI_setBaudRate(spiHandle, SPI_BAUD_RATE_1MHZ, 50000000); // 使用DriverLib辅助计算FIFO与中断配置如果需要// 使能FIFO功能 SPI_enableFIFO(spiHandle); // 设置发送FIFO中断触发水平为0空中断接收FIFO中断触发水平为16满中断 SPI_setFIFOInterruptLevel(spiHandle, SPI_FIFO_TXLVL_0, SPI_FIFO_RXLVL_16); // 使能接收FIFO中断 SPI_enableInterrupt(spiHandle, SPI_INT_RXFF); // 使能接收FIFO中断 // 在PIE向量表中配置对应的中断服务程序ISR Interrupt_register(INT_SPIA_RX, spiARxIsr); // 注册接收中断服务函数 Interrupt_enable(INT_SPIA_RX); // 使能PIE级中断使能SPI模块SPI_enableModule(spiHandle); // 最后一步使能模块开始工作4.2 数据收发实战轮询与中断模式轮询模式适用于简单、低速或非实时性要求的场景。其流程是“写入-等待-读取”。// 轮询方式发送一个字节并接收一个字节 uint16_t txData 0x55AA; uint16_t rxData; SPI_writeCharNonBlocking(spiHandle, txData); // 非阻塞写入发送缓冲区 // 等待发送完成/接收完成标志位 while(SPI_isTransmitterBusy(spiHandle) true) { ; // 空循环等待或可加入超时机制 } // 或者等待接收中断标志在非FIFO模式下发送完成也会置位接收标志 while(SPI_getInterruptStatus(spiHandle, SPI_INT_RX) false) { ; } SPI_clearInterruptStatus(spiHandle, SPI_INT_RX); // 清除中断标志 rxData SPI_readCharNonBlocking(spiHandle); // 读取接收到的数据轮询模式的缺点是CPU被长时间占用在等待状态效率低下。中断驱动FIFO模式是处理持续数据流的推荐方式。以接收连续数据为例// 在初始化中已使能接收FIFO中断水平设为16 // 中断服务函数 (ISR) __interrupt void spiARxIsr(void) { uint16_t i, rxBuffer[16]; // 检查是否是接收FIFO中断 if(SPI_getInterruptStatus(spiHandle, SPI_INT_RXFF) true) { // 一次性读取FIFO中所有数据最多16个 SPI_readCharArray(spiHandle, rxBuffer, 16); // 处理数据... (例如存入更大的环形缓冲区) for(i0; i16; i) { processData(rxBuffer[i]); } SPI_clearInterruptStatus(spiHandle, SPI_INT_RXFF); // 清除中断标志 } // 可能还需要检查接收错误中断如溢出 if(SPI_getInterruptStatus(spiHandle, SPI_INT_RX_OVERRUN) true) { // 处理溢出错误清除状态可能需要重置FIFO或重新同步 SPI_clearOverflowStatus(spiHandle); SPI_resetRxFIFO(spiHandle); } Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP7); // 应答PIE中断 }在这个中断例程中我们设置当接收FIFO满16个字时才触发中断然后一次性读出所有数据。这极大地减少了中断进入/退出的上下文切换开销让CPU可以更连续地处理核心任务只在数据积累到一定量时才进行批量处理非常高效。4.3 多从设备系统与GPIO模拟片选一个SPI主设备常常需要连接多个从设备。虽然TMS320F280013x的每个SPI模块只有一个硬件SPISTE片选输出但我们可以用普通GPIO来模拟多个片选信号。假设主SPI连接了三个从设备设备123它们共享SPICLK、SPISIMO、SPISOMI三根线。// 初始化时将SPI硬件SPISTE引脚也配置为GPIO输出高电平无效我们完全用其他GPIO控制 GPIO_setPinConfig(GPIO_19_GPIO19); // 将硬件SPISTEA引脚用作普通GPIO GPIO_setDirectionMode(19, GPIO_DIR_MODE_OUT); // 设置为输出 GPIO_writePin(19, 1); // 输出高电平 // 定义三个GPIO作为片选引脚 #define CS_DEV1 10 #define CS_DEV2 11 #define CS_DEV3 12 // ... 初始化这些GPIO为输出并默认置高不选中 // 与特定设备通信的函数 void spi_WriteToDevice(uint16_t devNum, uint16_t data) { uint16_t csPin; // 根据设备号选择片选引脚 switch(devNum) { case 1: csPin CS_DEV1; break; case 2: csPin CS_DEV2; break; case 3: csPin CS_DEV3; break; default: return; } GPIO_writePin(csPin, 0); // 拉低片选选中设备 __delay_cycles(10); // 微小延时确保片选稳定根据从设备要求调整 SPI_writeCharBlockingFIFO(spiHandle, data); // 阻塞式发送数据 // 如果需要读取可以在这里进行读写交换 __delay_cycles(10); // 传输结束后的保持时间根据从设备要求调整 GPIO_writePin(csPin, 1); // 拉高片选释放设备 }关键点在于切换不同设备通信时要确保前一个设备的片选已置高无效并等待足够时间根据数据手册的t_CSH片选无效时间后再拉低下一个设备的片选。这个延时对于保证从设备内部状态机正确复位至关重要。5. 常见问题排查与调试技巧实录即使理解了所有原理实际调试SPI时还是会遇到各种问题。下面是我在多年项目中总结的一些典型问题及其排查思路。5.1 通信完全无响应检查清单电源与物理连接用万用表或示波器确认从设备已上电引脚焊接/连接牢固没有虚焊或短路。时钟与片选信号用示波器同时测量SPICLK和SPISTE或你的GPIO片选信号。确保片选信号在通信期间为低电平且有时钟脉冲产生。如果看不到时钟检查SPI模块是否已使能SPICTL1.01主从模式设置是否正确。引脚复用配置这是最常见的问题之一。反复检查GPIO的MUX配置寄存器GPxMUX/GPyGMUX确认引脚已正确复用到SPI功能而不是停留在GPIO模式。波特率是否过高尝试将SPIBRR设置为一个较大的值如255将波特率降到极低看是否有信号。过高的波特率在长导线或面包板上可能导致信号衰减严重。从设备模式匹配再次核对从设备数据手册的时序图确认CPOL和CPHA设置与主设备完全一致。Mode 0和Mode 3的时钟空闲电平相反极易搞混。5.2 能发送但接收数据错误全0、全1、或固定值数据位对齐问题检查SPICHAR寄存器确保设置的数据位长度1-16与从设备期望的一致。例如从设备是12位ADC你却配置为8位模式那么你只会收到移入数据的前8位或后8位取决于移位方向。同时确认发送数据是左对齐写入SPITXBUF而读取时是从右对齐的SPIRXBUF中读取。MISO引脚配置在主模式下MISOSPISOMI是输入引脚。确认其GPIO方向已自动设置为输入复用为外设功能后通常自动切换并且没有意外的上拉/下拉电阻影响电平。可以用示波器直接测量该引脚看从设备是否有数据输出。三线模式下的“自收自发”如果你启用了三线模式接收到的第一个数据很可能是你发送数据的回环。记得在发送有效命令后执行一次哑读操作来清空这个回环数据再读取真正的从设备响应。从设备TALK位在从模式下如果从设备需要发送数据必须确保其TALK位SPICTL1.1被置1否则其MISO出为高阻态主设备读到的将是浮空电平通常表现为全1或随机值。5.3 FIFO与中断相关的问题中断不触发检查中断使能链SPI模块级中断使能如SPIINTENA, RXFFIENA- PIE组内中断使能PIEIERx.y- CPU级中断使能INTM位 IER寄存器。缺一不可。检查中断标志在中断服务程序ISR中首先要读取相应的中断标志如SPIINTFLG, RXFFINT来判断中断源并在处理完成后手动清除该标志位对于SPI通常读取SPIRXST或写1到特定位来清除。忘记清标志会导致中断只触发一次。FIFO触发水平在FIFO模式下确认TXFFIL和RXFFIL的设置符合你的预期。如果你设置RXFFIL16但每次只收到15个数据就停止了那么中断永远不会产生。数据丢失或溢出接收溢出OVERRUN_FLAG这发生在CPU或DMA来不及读取SPIRXBUF中的数据而新数据已经覆盖进来时。在非FIFO模式下要提高中断优先级或使用DMA在FIFO模式下应确保你的中断服务程序或DMA传输速率能跟上数据到达的平均速率并适当降低RXFFIL水平让中断更早发生。FIFO溢出RXFFOVF接收FIFO已满16个字但仍有新数据到来。这说明你的数据处理速度严重跟不上接收速度。需要优化数据搬运代码比如用DMA从SPI FIFO直接搬运到更大的内存缓冲区或者从根本上降低SPI通信波特率。发送FIFO下溢发送数据太快CPU来不及填充导致发送中断频繁发生。可以考虑增大TXFFIL值或使用DMA自动填充发送FIFO。5.4 调试工具与技巧逻辑分析仪是你的最佳伙伴一个支持SPI协议解码的逻辑分析仪如Saleae能直观地显示时钟、数据、片选波形并直接解码出十六进制或二进制数据。一眼就能看出时序模式、数据内容是否正确是排查通信问题最高效的工具。善用寄存器查看窗口在CCS的调试模式下实时查看SPI的关键寄存器SPIRXBUF接收数据、SPITXBUF发送缓冲、SPISTS状态寄存器含中断和错误标志、SPIFFRX/SPIFFTXFIFO状态。通过观察它们的变化可以判断数据流是否畅通。编写简单的回环测试将主设备的MOSI和MISO短接实现自发自收。先测试这个最简单的场景如果能正确收到自己发送的数据证明MCU的SPI模块基本配置和底层驱动是正常的问题可能出在从设备或硬件连接上。注意电源噪声和接地高速SPI通信10MHz对电源质量和地回路非常敏感。确保电源去耦电容通常0.1uF和10uF并联尽可能靠近芯片电源引脚放置。使用完整的地平面并让信号线尽量短。