AM275x I2C与MCSPI寄存器深度解析与底层驱动实战

📅 2026/7/19 11:12:33
AM275x I2C与MCSPI寄存器深度解析与底层驱动实战
1. 项目概述与核心价值在嵌入式系统开发中I2C和SPI是连接主控芯片与各类传感器、存储器和外设的“血管”与“神经”。对于像TI AM275x这样的高性能信号处理器理解并精准配置其内部的I2C和MCSPI控制器寄存器是打通这些“血管神经”、让系统真正“活”起来的第一步。很多开发者习惯于依赖高级驱动库这固然高效但一旦遇到通信不稳定、数据错乱或驱动库无法覆盖的复杂场景就会束手无策。这时直接与寄存器打交道的能力就成了区分普通开发者和资深工程师的关键。本文将从一份真实的AM275x技术参考手册寄存器描述片段出发为你深入解析I2C和MCSPI的核心寄存器配置逻辑与通信原理。我不会止步于翻译手册而是结合我十多年在工业控制、车载电子等领域调试通信总线的实战经验告诉你每个寄存器位背后设计的“为什么”分享那些手册上不会写的配置“坑点”和调试“秘籍”。无论你是正在为AM275x平台移植驱动还是希望深入理解串行通信的硬件本质这篇文章都将提供从理论到实践的一站式指南。我们将从I2C的地址协商机制聊到SPI的时钟相位玄学最终让你能自信地写出稳定、高效的底层通信代码。2. I2C控制器寄存器深度解析与配置实战AM275x的I2C控制器是一个高度可配置的模块支持标准模式100 kbps、快速模式400 kbps和高速模式最高3.4 Mbps。其寄存器配置是通信的基石理解每个寄存器的作用是进行任何高级操作的前提。2.1 地址寄存器族身份标识与多主寻址I2C通信始于寻址。AM275x的I2C控制器支持多达4个独立的自身地址Own Address这为设计复杂的多角色设备例如一个设备既可作为某个主设备的从机又可作为另一个从设备的主机提供了硬件基础。I2C_OA (Own Address Register, 偏移 A8h):这是最基础的自身地址寄存器。其OA字段位[9:0]用于设置7位或10位从机地址。这里有一个关键细节I2C地址在总线上传输时是左对齐的。对于一个7位地址如0x50你需要将其左移一位后写入OA字段即写入0xA0。因为I2C协议中地址字节的最低位是读写位R/W#控制器硬件会自动处理这一点。对于10位地址则需要按照手册规定的格式组合写入。I2C_OA1, OA2, OA3 (偏移 C4h, C8h, CCh):这三个寄存器提供了额外的从机地址。为什么需要多个地址设想一个智能传感器集线器它可能需要响应来自不同主控器的不同命令集。通过配置OA1为0x20OA2为0x30该设备就能在总线上以两个独立的逻辑设备存在简化了系统架构。I2C_ACTOA (Active Own Address Register, 偏移 D0h) 与 I2C_SBLOCK (Clock Blocking Enable Register, 偏移 D4h):这两个寄存器是高级功能的关键。ACTOA是一个只读状态寄存器其OAx_ACT位会指示当前是哪一个自身地址匹配并响应了总线上的一次寻址。这在多地址应用中用于判断是哪套“身份”被呼叫。而SBLOCK寄存器则更为强大。它的OAx_EN位用于为每个自身地址单独启用时钟拉伸Clock Stretching功能。当时钟拉伸启用后如果该地址被寻址从设备可以通过拉低SCL线来暂停总线为自己争取处理时间直到准备好数据或完成命令。这是一个非常重要的流控机制尤其当从设备是低速MCU或需要时间访问非易失性存储器时。配置时需谨慎滥用时钟拉伸会影响总线整体效率。实操心得地址冲突排查在调试多设备I2C系统时最头疼的就是地址冲突。除了检查代码中的地址值务必用逻辑分析仪抓取总线启动后的第一个字节地址读写位。确认地址字节与你配置的OA寄存器值一致。我曾遇到过一个案例软件配置的地址是0x68但总线上出现的却是0xD0最后发现是某处代码错误地对地址进行了右移而非左移操作。2.2 时钟配置寄存器总线速度的生命线I2C的通信速率由SCL时钟的频率决定。AM275x通过三个寄存器精细控制时钟生成其配置逻辑需要仔细计算。I2C_PSC (Clock Prescaler Register, 偏移 B0h):这是时钟分频的第一级。PSC字段位[7:0]用于对模块的输入时钟通常来自系统PLL进行预分频分频系数为(PSC 1)。例如输入时钟为48MHz若要得到12MHz的内部时钟用于后续细分则需设置PSC 3。这个寄存器的配置直接影响后续SCLL和SCLH的计算基准。I2C_SCLL (SCL Low Time Register, 偏移 B4h) 与 I2C_SCLH (SCL High Time Register, 偏移 B8h):这两个寄存器共同决定了SCL时钟的高低电平时间是设定标准/快速模式总线速率的核心。SCLL定义SCL低电平周期。SCLH定义SCL高电平周期。总线频率计算公式为f_{SCL} f_{internal\_clk} / ((SCLL 7) (SCLH 5))其中f_{internal\_clk}是经过PSC分频后的内部时钟频率。公式中的“7”和“5”是硬件内部的固定延迟补偿。例如目标频率为400kHz快速模式f_{internal\_clk}12MHz则总计数周期应为12MHz / 400kHz 30。分配SCLL和SCLH时通常让高低电平时间相等以占空比50%即(SCLL 7) ≈ (SCLH 5) ≈ 15。解得SCLL 8,SCLH 10。写入前需确认计算值未超出寄存器范围0-255。高速模式HS mode则使用HSSCLL和HSSCLH字段位[15:8]其计算逻辑类似但时间参数更小用于实现最高3.4 Mbps的通信速率。关键点控制器不会自动在标准模式和高速模式间切换需要软件在发送HS模式主机码0000 1XXX后动态切换时钟配置。2.3 系统与缓冲状态寄存器调试与监控的眼睛I2C_SYSTEST (System Test Register, 偏移 BCh):这个寄存器是硬件调试的“瑞士军刀”。它允许软件直接读取SCL_I, SDA_I和驱动SCL_O, SDA_OI2C总线引脚即使控制器处于非活动状态。这在以下场景极其有用总线死锁恢复当总线因某个设备故障被意外拉低时你可以通过置位SDA_O或SCL_O为1并输出尝试将总线拉高打破死锁。硬件连接测试在初始化前可以手动产生一个START条件SDA拉低 while SCL高和STOP条件SDA拉高 while SCL高测试总线物理连接是否正常。功能验证SCL_I_FUNC等位反映了在正常工作模式下引脚的电平可用于辅助诊断。I2C_BUFSTAT (Buffer Status Register, 偏移 C0h):该寄存器提供了FIFO缓冲区的状态信息。TXSTAT和RXSTAT指示发送和接收缓冲区的数据量。FIFODEPTH则告诉你硬件实现的FIFO深度是多少例如2h可能表示深度为4级。在编写DMA或中断驱动的传输程序时必须查询此寄存器来确保不会发生缓冲区溢出Overflow或下溢Underflow。一个最佳实践是在发送中断服务程序中检查TXSTAT是否小于FIFO深度再填充数据在接收中断中检查RXSTAT是否大于0再读取数据。3. MCSPI控制器寄存器架构与通道配置详解与I2C的半双工、多主多从特性不同SPI是全双工、主从同步的通信协议。AM275x的MCSPIMulti-Channel SPI控制器功能更为复杂和强大支持多达4个独立的物理通道CH0-CH3每个通道都可独立配置为主或从模式。3.1 系统级控制与状态寄存器在配置具体通道前必须理解几个全局性的系统寄存器。MCSPI_SYSCONFIG (偏移 110h):这是模块的“电源和时钟管理中枢”。SIDLEMODE位[4:3]空闲模式管理。强烈建议在大多数应用中使用模式2h(Smart-idle)。在此模式下模块仅在内部无活动如DMA传输完成、FIFO空时才响应系统的低功耗请求进入IDLE状态平衡了功耗与性能。ENAWAKEUP位[2]唤醒使能。在智能空闲模式下如果此位置1模块可以通过特定事件如从模式下的片选信号变化产生唤醒信号将系统从低功耗状态唤醒。对于电池供电的传感器采集设备此功能至关重要。AUTOIDLE位[0]自动时钟门控。保持为1h默认允许硬件在接口空闲时自动关闭时钟以省电对性能几乎无影响。MCSPI_SYSSTATUS (偏移 114h):最重要的位是RESETDONE位[0]。在任何软件复位向MCSPI_SYSCONFIG[1]写1或模块上电后必须轮询此位直到其变为1才能进行后续的寄存器配置。忽略这一步是导致SPI初始化失败的常见原因。MCSPI_MODULCTRL (偏移 128h):此寄存器控制模块级功能如单通道/多通道模式选择、主/从模式全局设置通常每个通道可独立设置、以及时钟选择。对于AM275x通常需要确认MS位主/从选择和SINGLE位是否为单通道模式的配置符合你的硬件连接设计。3.2 通道配置寄存器定制你的SPI链路每个SPI通道CH0-CH3都有一套独立的配置(CONF)、状态(STAT)、控制(CTRL)、发送(TX)和接收(RX)寄存器。MCSPI_CHxCONF是核心。MCSPI_CHxCONF (通道x配置寄存器):虽然输入片段未给出该寄存器的位域详情但根据TI PRU-ICSS架构的通用设计它通常包含以下关键字段其配置决定了通信的基本电气和时序特性CLKD(时钟分频器)决定SPI时钟SCLK的频率。计算公式通常为f_{SCLK} f_{input\_clk} / (CLKD 1)。需要根据从设备的最大支持速率谨慎设置。POL(时钟极性CPOL)决定SCLK空闲时的电平。0: SCLK空闲时为低电平。1: SCLK空闲时为高电平。PHA(时钟相位CPHA)决定数据在SCLK的哪个边沿被采样。0: 数据在SCLK的第一个边沿若CPOL0则为上升沿CPOL1则为下降沿被采样。1: 数据在SCLK的第二个边沿被采样。CPOL和CPHA的组合构成了SPI的四种模式Mode 0-3。必须确保主设备和所有从设备的模式完全一致否则数据采样会错位。例如常见的NOR Flash通常使用Mode 0 (CPOL0, CPHA0) 或 Mode 3 (CPOL1, PHA1)。EPOL(片选极性)决定片选信号CS的有效电平。0通常表示低电平有效这是最常见的情况。TRM(传输模式)选择是发送接收全双工、只发送、只接收还是循环测试模式。WL(字长)设置每个SPI数据帧的位数常见的有8位、16位、32位。必须与从设备的数据格式匹配。3.3 数据传输与FIFO管理MCSPI_TXx 与 MCSPI_RXx (发送/接收数据寄存器):这是数据进出的门户。在查询Polling方式下你向TXx寄存器写入数据启动传输然后轮询状态或等待一段时间后从RXx读取数据。注意在全双工模式下每次写入TXx启动传输都会同时接收到一个数据存入RXx即使你并不需要从设备的数据。MCSPI_XFERLEVEL (偏移 17Ch):这是FIFO中断触发水位线设置寄存器。当使用FIFO和中断驱动传输时此寄存器至关重要。AEL(Almost Empty Level)设置发送FIFO“几乎空”的阈值。当TX FIFO中的数据量小于或等于此值时可能触发TXx_EMPTY中断提示主机需要填充更多数据。AFL(Almost Full Level)设置接收FIFO“几乎满”的阈值。当RX FIFO中的数据量大于或等于此值时可能触发RXx_FULL中断提示主机需要读取数据以防溢出。合理设置AEL和AFL可以平衡中断频率和系统响应延迟。例如对于一个深度为16的FIFO设置AEL4,AFL12可以在数据量适中时触发中断避免因频繁中断设AEL15或响应不及时导致FIFO空/满设AEL0的问题。MCSPI_IRQSTATUS 与 MCSPI_IRQENABLE (中断状态与使能寄存器):这两个寄存器协同工作管理所有通道的中断事件。IRQSTATUS标识了事件的发生如TX0_EMPTY,RX0_FULL,TX0_UNDERFLOW而IRQENABLE则决定哪些事件能真正产生CPU中断。TXx_UNDERFLOW:发送下溢。当主机或DMA未能及时向TX FIFO提供数据而硬件需要发送数据时发生。这通常意味着你的数据流供应不足需要检查上游数据源或提高中断/DMA响应优先级。RXx_OVERFLOW:接收溢出仅从模式。当RX FIFO已满但又从总线收到新数据时发生。这意味着你的主机读取数据速度跟不上从设备发送速度或者中断被阻塞太久。避坑指南SPI时钟相位与采样时刻SPI模式配置错误是导致通信失败的头号原因。我曾调试过一个三轴陀螺仪数据始终不对。逻辑分析仪显示SCLK、MOSI波形都正确但MISO线上的数据在主机采样时刻总是不稳定。最后发现陀螺仪手册定义的“Mode 0”是CPOL0, CPHA0但它的数据是在SCLK的下降沿后有效而我的主机配置在上升沿采样。虽然都叫Mode 0但细微的时序差异导致了采样错误。教训永远不要只看模式编号一定要核对从设备数据手册中关于数据建立时间t_SU和保持时间t_HOLD的图示并据此调整主机的CPHA配置必要时可能需要在主设备端加入微小的SCLK延迟。4. 从寄存器到代码I2C与SPI初始化配置实战理解了寄存器最终要落地为代码。下面以AM275x的PRU-ICSS可编程实时单元为例展示如何通过直接操作寄存器来初始化I2C和SPI控制器。这里假设使用C语言在PRU核心上进行编程并已正确映射了外设寄存器内存空间。4.1 I2C控制器初始化与主机发送流程假设我们需要将I2C0初始化为快速模式400kbps的主机输入时钟为48MHz。// 寄存器定义 (基地址根据具体I2C实例如I2C0为0x20000000) #define I2C0_BASE 0x20000000 #define I2C_PSC (*(volatile unsigned int *)(I2C0_BASE 0xB0)) #define I2C_SCLL (*(volatile unsigned int *)(I2C0_BASE 0xB4)) #define I2C_SCLH (*(volatile unsigned int *)(I2C0_BASE 0xB8)) #define I2C_CON (*(volatile unsigned int *)(I2C0_BASE 0xA4)) // 控制寄存器片段中未给出但必不可少 #define I2C_SA (*(volatile unsigned int *)(I2C0_BASE 0xAC)) #define I2C_CNT (*(volatile unsigned int *)(I2C0_BASE 0x98)) // 数据计数寄存器 #define I2C_DATA (*(volatile unsigned int *)(I2C0_BASE 0x9C)) // 数据寄存器 void i2c_init_master(void) { // 1. 确保模块处于复位/禁用状态 (假设I2C_CON的I2C_EN位为0) // 2. 配置时钟预分频器 (PSC) // 目标内部时钟 ~12MHz (用于400kbps计算) 分频系数 48MHz / 12MHz - 1 3 I2C_PSC 3; // PSC 3, 实际分频为4 // 3. 配置SCL高低时间 (快速模式400kHz) // 计算: 内部时钟 48MHz / (31) 12MHz // 所需总计周期 12MHz / 400kHz 30 // 分配: SCLL7 ≈ SCLH5 ≈ 15 // 得: SCLL 8, SCLH 10 I2C_SCLL 8; I2C_SCLH 10; // 4. 配置自身地址 (主机模式下通常可设为任意不冲突地址或忽略) // I2C_OA 0x00; // 作为主机自身地址非必须 // 5. 配置控制寄存器 (I2C_CON) // 使能I2C控制器设置为主机模式使能中断(如果需要) // 假设I2C_CON的位定义: 位[15] I2C_EN1, 位[10] MST1 (主机模式) I2C_CON (1 15) | (1 10); // 使能模块主机模式 // 6. 可选配置FIFO阈值、中断使能等 } int i2c_master_write(uint8_t slave_addr, uint8_t *data, uint32_t len) { // 1. 设置目标从机地址 (7位地址左移一位) I2C_SA (slave_addr 1); // 假设是写操作最低位R/W#为0 // 2. 设置要传输的数据字节数 I2C_CNT len; // 3. 写入数据到数据寄存器 (可能是FIFO或单字节寄存器) for (int i 0; i len; i) { // 等待TX就绪标志 (需查询I2C_IRQSTATUS或I2C_BUFSTAT) while (!(I2C_BUFSTAT 0x3F)); // 示例检查TXSTAT非空 I2C_DATA data[i]; } // 4. 启动传输 (设置I2C_CON的STT位) // I2C_CON | (1 0); // 假设位0是STT (START) // 5. 等待传输完成 (查询I2C_IRQSTATUS的ARDY位或中断) // while (!(I2C_IRQSTATUS (1 ...))); return 0; // 成功 }4.2 MCSPI控制器初始化与全双工通信示例假设我们需要将MCSPI0的通道0初始化为SPI主机模式0 (CPOL0, CPHA0)8位数据帧时钟频率为1MHz系统输入时钟为24MHz。// 寄存器定义 (MCSPI0基地址为0x20100000) #define MCSPI0_BASE 0x20100000 #define MCSPI_SYSCONFIG (*(volatile unsigned int *)(MCSPI0_BASE 0x110)) #define MCSPI_SYSSTATUS (*(volatile unsigned int *)(MCSPI0_BASE 0x114)) #define MCSPI_MODULCTRL (*(volatile unsigned int *)(MCSPI0_BASE 0x128)) #define MCSPI_CH0CONF (*(volatile unsigned int *)(MCSPI0_BASE 0x12C)) #define MCSPI_CH0STAT (*(volatile unsigned int *)(MCSPI0_BASE 0x130)) #define MCSPI_CH0CTRL (*(volatile unsigned int *)(MCSPI0_BASE 0x134)) #define MCSPI_TX0 (*(volatile unsigned int *)(MCSPI0_BASE 0x138)) #define MCSPI_RX0 (*(volatile unsigned int *)(MCSPI0_BASE 0x13C)) void spi_init_master_ch0(void) { // 1. 等待模块复位完成 (如果之前有复位操作) while (!(MCSPI_SYSSTATUS 0x1)); // 等待RESETDONE1 // 2. 配置系统控制寄存器 (智能空闲使能唤醒自动时钟门控) MCSPI_SYSCONFIG (0x2 3) | (0x1 2) | 0x1; // SIDLEMODE2, ENAWAKEUP1, AUTOIDLE1 // 3. 配置模块控制寄存器 (使能多通道模式设置为主机) // 假设位定义: 位[0] SINGLE0 (多通道), 位[2] MS1 (主机模式), 位[3] FDAA0 (自动片选) MCSPI_MODULCTRL (0 0) | (1 2) | (0 3); // 4. 配置通道0参数寄存器 (MCSPI_CH0CONF) // 计算时钟分频: CLKD f_in / f_sclk - 1 24MHz / 1MHz - 1 23 uint32_t ch0conf_value 0; ch0conf_value | (23 6); // 假设CLKD在bit[13:6]设置时钟分频 ch0conf_value | (0 4); // 假设POL在bit[4] CPOL0 ch0conf_value | (0 5); // 假设PHA在bit[5] CPHA0 (Mode 0) ch0conf_value | (0 2); // 假设EPOL在bit[2] 片选低有效 ch0conf_value | (0x0 14); // 假设TRM在bit[15:14]0 全双工模式 ch0conf_value | (0x7 0); // 假设WL在bit[2:0]7 8位字长 (WL1) MCSPI_CH0CONF ch0conf_value; // 5. 使能通道0 // 假设MCSPI_CH0CTRL的位0 (EN) 为使能位 MCSPI_CH0CTRL | 0x1; // 6. 可选配置FIFO触发水位线 (MCSPI_XFERLEVEL) 和中断使能 (MCSPI_IRQENABLE) } uint8_t spi_transfer_byte(uint8_t tx_data) { // 1. 等待发送缓冲区就绪 (TX0为空) while (!(MCSPI_CH0STAT 0x1)); // 假设位0为TX0_EMPTY状态位 // 2. 写入要发送的数据 MCSPI_TX0 tx_data; // 3. 等待接收缓冲区有数据 (RX0有数据) while (!(MCSPI_CH0STAT 0x2)); // 假设位1为RX0_FULL状态位 // 4. 读取接收到的数据 return (uint8_t)(MCSPI_RX0 0xFF); }5. 高级应用、调试技巧与常见问题排查掌握了基础配置后面对复杂场景和棘手问题才能游刃有余。5.1 I2C多主机仲裁与时钟同步当总线上有多个主机时I2C协议通过仲裁机制防止数据冲突。AM275x的I2C控制器内置了仲裁逻辑。如果两个主机同时发起传输当它们发送的地址或数据位不同时发送“1”释放SDA线为高的主机将检测到SDA线实际为低因为另一个主机在发送“0”从而知道自己仲裁失败并立即切换到从机接收模式监听获胜主机后续的数据。开发者通常无需直接干预此过程但理解它对于调试总线冲突至关重要。如果你发现某个主机设备偶尔“丢失”数据可以检查其I2C_IRQSTATUS寄存器中是否有仲裁丢失AL标志位被置位。5.2 SPI的DMA配置与大数据流处理对于高速、大批量的SPI数据传输如读写SD卡、传输图像数据使用CPU查询或中断搬运每个字都会成为瓶颈。此时必须启用DMA。配置DMA请求源在MCSPI中TXx_EMPTY和RXx_FULL事件可以触发DMA请求。需要在MCSPI_IRQENABLE中使能相应中断但更重要的是需要根据芯片的互联INTC或DMA控制器配置将这两个事件映射到具体的DMA通道请求线。设置FIFO水位线通过MCSPI_XFERLEVEL寄存器精细调整AEL和AFL。对于DMA通常希望减少中断频率因此可以将AEL设得较小如FIFO深度的1/4AFL设得较大如深度的3/4让DMA一次性搬运更多数据。注意数据对齐如果SPI字长是16位或32位而你的DMA和内存数据是8位字节数组需要特别注意字节序Endianness和数据打包问题。可能需要在DMA配置中设置数据宽度和地址增量模式。5.3 实战调试技巧与问题排查表当通信失败时系统性的排查至关重要。以下是我常用的检查清单问题现象可能原因排查步骤与工具I2C/SPI无任何波形1. 模块时钟未使能。2. 模块未解除复位或未使能。3. GPIO引脚复用功能未正确配置为I2C/SPI。1. 检查系统时钟控制器CM配置确认外设时钟已开启。2. 读取MCSPI_SYSSTATUS[RESETDONE]和I2C_CON[I2C_EN]等使能位。3. 检查引脚控制寄存器PINCTRL确认MUX模式已设置为对应的外设功能而非GPIO。I2C能发出START但无ACK1. 从机地址错误。2. 从机设备未上电或损坏。3. 总线上下拉电阻不合适太弱或太强。4. 从机忙如正在写EEPROM。1. 用逻辑分析仪确认发出的7位地址字节是否正确已左移。2. 测量从机电源和复位信号。3. 检查SDA/SCL线上拉电阻值标准模式通常用4.7kΩ快速模式用2.2kΩ。4. 查询从机状态寄存器如果有或增加重试和超时机制。SPI数据错位或全为0xFF/0x001. SPI模式CPOL, CPHA不匹配。2. 数据字长WL不匹配。3. 片选信号CS时序或极性错误。4. 主从设备位序MSB/LSB first不匹配。1.这是最常见原因用逻辑分析仪同时抓取SCLK、MOSI、MISO、CS四线。对照从设备手册的时序图检查数据在哪个时钟边沿被采样与主机配置是否一致。2. 确认主机WL设置与从设备期望的数据帧长度一致。3. 检查CS信号是否在数据帧开始前有效结束后无效极性是否正确EPOL。4. 检查是否有LSBFE低位先发送之类的配置位需要设置。I2C信随机失败1. 总线受噪声干扰。2. 电源不稳定导致从机复位。3. 多个主机仲裁失败处理不当。4. 时钟拉伸超时。1. 检查PCB布局确保SDA/SCL线远离噪声源且长度不过长。可考虑降低总线速度测试。2. 监测从机电源纹波。3. 检查主机驱动中仲裁失败后是否妥善清理了状态并重新初始化传输。4. 如果从设备支持时钟拉伸适当增加主机的超时等待时间。SPI高速传输丢数据1. CPU/DMA处理速度跟不上SPI时钟速度。2. FIFO溢出或下溢。3. 中断响应延迟过大。4. 系统总线带宽不足。1. 降低SPI时钟频率测试。2. 检查MCSPI_IRQSTATUS是否有TX_UNDERFLOW或RX_OVERFLOW标志。优化FIFO水位线XFERLEVEL设置。3. 提高SPI中断优先级或改用DMA模式。4. 检查系统总线如OCP的仲裁和带宽确保SPI控制器能及时获取数据。最后一个黄金法则投资一个靠谱的逻辑分析仪或带有高级触发功能的示波器。在调试通信问题时它能直观地展示出START、STOP、ACK、数据位等所有细节比任何打印日志都有效。通过对比实际抓取的波形与协议标准时序图绝大多数硬件通信问题都能无处遁形。寄存器配置是骨骼而总线上的信号波形则是流动的血液两者结合才能真正驾驭AM275x强大的I2C与SPI通信能力。