深入解析SSI接口:从SPI基础到TI M3实战配置与调试
1. 同步串行接口(SSI)到底是什么?
如果你在嵌入式领域摸爬滚打过几年,肯定对SPI、I2C这些名字耳熟能详。但当你翻开一些主流MCU的数据手册,比如TI的M3系列,可能会发现一个叫SSI(Synchronous Serial Interface)的模块。乍一看,它和SPI长得太像了,都有时钟线、数据线,有时还有个片选。那它到底是SPI的“马甲”,还是一个独立的东西?今天我们就来彻底拆解一下这个在工业控制和传感器领域非常常见的通信接口。
简单来说,SSI是一种同步、全双工、主从式的串行通信接口。它的核心在于“同步”——通信双方共享一个由主设备产生的时钟信号(SSIClk),所有数据的发送和接收都严格踩着这个时钟的节拍进行。这就像乐队指挥和乐手,指挥(主设备)挥动指挥棒(时钟),所有乐手(从设备)在同一时刻演奏或停止,保证了节奏的绝对统一。这种机制避免了异步通信中因时钟偏差导致的累积误差,特别适合对时序要求苛刻、需要高速稳定传输的场景,比如读取高速ADC的数据、驱动TFT液晶屏,或者与数字音频设备通信。
SSI协议非常灵活,它支持4到16位可变长度的数据帧,这意味着你可以根据外设的需求,一次传输恰好长度的数据,避免了8位或16位固定长度带来的冗余或不足。更重要的是,SSI模块通常硬件上集成了发送和接收FIFO(先入先出缓冲区)。你可以把FIFO想象成一个小型快递分拣站。当CPU需要发送数据时,不用死等上一个字节发完,可以一次性往发送FIFO里写入多个数据,SSI硬件会自动按顺序发出;接收时,数据也会先暂存在接收FIFO里,等攒到一定数量或超时了再通知CPU来取。这极大地解放了CPU,让它不必被琐碎的字节传输所绑架,可以去处理更重要的任务,或者干脆进入低功耗睡眠模式,等FIFO快满了或超时了再被中断唤醒。
在TI M3这类微控制器上,SSI模块通常兼容两种主流的帧格式:德州仪器(TI)同步串行格式和飞思卡尔(Freescale)SPI格式。后者基本就是业界标准的SPI协议。所以,你可以理解为这个SSI模块是一个“SPI Plus”,它在标准SPI的基础上,增加了一些如TI专有格式、更灵活的中断和DMA触发机制等增强特性。对于嵌入式开发者而言,掌握SSI,就等于掌握了驱动绝大多数SPI外设的能力,并且能更精细地控制通信过程,提升系统效率。
2. 核心工作机制与帧格式深度解析
要玩转SSI,不能只停留在“配置几个寄存器就能通”的层面,必须理解时钟和数据是如何共舞的。不同的帧格式和时钟模式,直接决定了你能否正确地和你的传感器、存储器或显示屏对话。
2.1 信号线定义与角色
一个典型的SSI接口包含以下几条关键信号线:
- SSIClk(Serial Clock):串行时钟,由主设备产生,是所有数据传输的节拍器。它的频率、极性和相位是可配置的核心。
- SSIFss(Frame Synchronization):帧同步信号。这是一个多功能引脚,在SPI模式下,它通常作为片选(Slave Select)使用,低电平有效,用于选中特定的从设备。在TI同步串行格式下,它则是一个在每帧数据开始前出现的短暂脉冲。
- SSITx(Master Out Slave In, MOSI):主设备输出、从设备输入的数据线。
- SSIRx(Master In Slave Out, MISO):主设备输入、从设备输出的数据线。
在四线制全双工模式下,主从设备可以同时收发数据,效率最高。SSI也支持通过配置变为半双工或单工模式。
2.2 两种核心帧格式详解
M3的SSI模块主要支持两种帧格式,通过SSICR0寄存器中的FRF(Frame Format)位进行选择。
2.2.1 德州仪器(TI)同步串行格式
当FRF=0x1时,启用此模式。这种格式的特点是SSIFss信号作为一个短暂的同步脉冲,而非持续的片选信号。
- 时序过程:
- 空闲期:
SSIClk和SSIFss均被强制拉低,SSITx输出为高阻态。 - 启动传输:当发送FIFO中有数据时,
SSIFss会产生一个宽度为一个SSIClk周期的高电平脉冲。同时,数据从发送FIFO转移到发送移位寄存器。 - 数据移出:在
SSIFss脉冲结束后的下一个SSIClk上升沿,数据帧的最高位(MSB)从SSITx引脚移出。从设备也在同一时刻将其数据的MSB放到SSIRx线上。 - 数据锁存:主从设备都在每个
SSIClk的下降沿采样(锁存)对方数据线上的当前比特位。 - 帧结束:当最低位(LSB)被移出并锁存后,在下一个
SSIClk上升沿,接收到的完整数据帧从接收移位寄存器转移到接收FIFO。
- 空闲期:
注意:在TI格式下,数据的输出(改变)发生在时钟上升沿,而数据的输入(采样)发生在时钟下降沿。这是一个固定的“输出沿在前,采样沿在后”的时序,不可通过寄存器配置改变。这种格式常见于TI自家的某些ADC、DAC或数字接口芯片。
2.2.2 飞思卡尔(Freescale)SPI格式
当FRF=0x0时,启用此模式。这就是我们常说的标准SPI模式。在此模式下,SSIFss作为低有效的片选信号,在整帧数据传输期间保持有效(低电平)。其最大的灵活性体现在时钟极性(SPO)和相位(SPH)的可配置上,形成了四种模式组合(Mode 0-3)。
时钟极性
SPO(Clock Polarity):SPO=0:空闲时,SSIClk保持低电平。SPO=1:空闲时,SSIClk保持高电平。- 它决定了时钟线在无数据传输时的静态电平状态。
时钟相位
SPH(Clock Phase):SPH=0:数据在第一个时钟边沿(即SSIFss有效后的第一个时钟有效沿)被采样。SPH=1:数据在第二个时钟边沿被采样。- 它决定了数据采样发生在时钟周期的哪个时刻,是前半拍还是后半拍。
这两个位的组合,共同定义了数据相对于时钟的变化和采样时刻。这是SPI通信中最容易出错的地方,必须与外设的数据手册要求严格匹配。
四种SPI模式实操解读:
为了更直观,我们结合时序图来理解。假设传输一个8位数据0xAA(二进制10101010),MSB先行。
模式0 (SPO=0, SPH=0):
- 空闲状态:
SSIClk低,SSIFss高。 - 启动:
SSIFss变低选中从设备。在第一个SSIClk边沿(上升沿)到来之前,主设备就必须将第一位数据(MSB,即1)放到SSITx上并稳定。 - 采样:数据在
SSIClk的上升沿被从设备采样。 - 变化:主从设备在
SSIClk的下降沿更新下一位数据。 - 这是最常用的模式之一,因为数据在时钟上升沿稳定,逻辑分析仪观察起来很直观。
模式1 (SPO=0, SPH=1):
- 空闲状态:
SSIClk低,SSIFss高。 - 启动:
SSIFss变低。此时,第一个SSIClk边沿(上升沿)是一个“空拍”,不采样数据。主从设备在这个上升沿之后(即时钟高电平期间)才将第一位数据放到数据线上。 - 采样:数据在
SSIClk的下降沿被采样。 - 变化:数据在
SSIClk的上升沿更新。 - 注意:对于连续传输(
SSIFss一直为低),数据位之间没有“空拍”,采样和变化边沿交替进行。
模式2 (SPO=1, SPH=0):
- 空闲状态:
SSIClk高,SSIFss高。 - 启动:
SSIFss变低。在第一个SSIClk边沿(下降沿)到来前,数据必须就位。 - 采样:数据在
SSIClk的下降沿被采样。 - 变化:数据在
SSIClk的上升沿更新。 - 可以看作是模式0的“镜像”,把时钟极性反了过来。
模式3 (SPO=1, SPH=1):
- 空闲状态:
SSIClk高,SSIFss高。 - 启动:
SSIFss变低。第一个SSIClk边沿(下降沿)是“空拍”。 - 采样:数据在
SSIClk的上升沿被采样。 - 变化:数据在
SSIClk的下降沿更新。 - 可以看作是模式1的“镜像”。
实操心得:如何快速确定外设的SPI模式?看数据手册时序图时,抓住两个关键点:1.时钟空闲电平(是高是低)对应
SPO。2.数据采样边沿(是第一个有效边沿还是第二个)对应SPH。绝大多数SPI Flash(如W25Q系列)使用模式0或模式3。一些传感器(如MPU6050)可能使用模式3。配置错误最常见的现象就是读回的数据全是0xFF或0x00,或者完全错乱。
2.3 数据帧与FIFO操作
SSI支持4到16位的数据帧长度,通过SSICR0寄存器的DSS(Data Size Select)字段配置。例如,DSS=0x7表示8位数据,DSS=0xF表示16位数据。
这里有一个至关重要的细节:数据寄存器SSIDR是16位的。当你配置的数据帧小于16位时(比如12位),你必须将数据右对齐写入SSIDR的低位,高位会被硬件忽略。同样,从SSIDR读取数据时,硬件会自动将接收到的数据右对齐放在寄存器的低位。如果你忘记右对齐,直接写入一个16位数,高位无效数据会被发送出去,导致通信失败。
FIFO操作是提升效率的关键。发送时,只要发送FIFO非满(TNF=1),你就可以连续写入数据;接收时,只要接收FIFO非空(RNE=1),你就可以连续读取。硬件会自动管理移位过程。你可以通过中断或DMA来响应FIFO状态的变化,而不是傻傻地用while循环去查询。
3. 寄存器配置与初始化实战
理解了原理,我们来看如何让一个M3的SSI模块动起来。配置过程需要严格按照步骤进行,特别是时钟的开关顺序。
3.1 关键寄存器功能速查
首先,我们快速过一遍最核心的几个寄存器,建立一个整体印象:
| 寄存器名称 | 偏移地址 | 核心功能简述 |
|---|---|---|
| SSICR0 | 0x00 | 控制寄存器0:配置串行时钟速率(SCR)、时钟相位/极性(SPH,SPO)、帧格式(FRF)、数据位宽(DSS)。 |
| SSICR1 | 0x04 | 控制寄存器1:主从模式选择(MS)、SSI模块使能(SSE)、回环测试(LBM)、传输结束中断使能(EOT)等。 |
| SSIDR | 0x08 | 数据寄存器:读写操作分别访问接收和发送FIFO。数据必须右对齐。 |
| SSISR | 0x0C | 状态寄存器:只读。查看忙状态(BSY)、发送FIFO空(TFE)/非满(TNF)、接收FIFO非空(RNE)/满(RFF)。 |
| SSICPSR | 0x10 | 时钟预分频寄存器:设置时钟分频系数CPSDVSR,必须是2-254之间的偶数。 |
| SSIIM | 0x14 | 中断掩码寄存器:使能或屏蔽各类中断(接收中断RXIM、发送中断TXIM、接收超时RTIM、DMA中断等)。 |
| SSIRIS | 0x18 | 原始中断状态寄存器:反映中断源是否触发(无论是否被屏蔽)。 |
| SSIICR | 0x20 | 中断清除寄存器:向特定位写1,可清除对应的中断状态。 |
3.2 初始化配置步骤详解
假设我们需要将SSI0配置为SPI主模式,模式为SPO=1, SPH=1(即SPI Mode 3),比特率1 Mbps,数据位宽8位。系统主时钟CMCLK为20 MHz。
第一步:模块时钟与引脚使能在操作任何外设寄存器前,必须确保其时钟门控是打开的。对于M3,通常需要设置CMPCLKCR0寄存器中对应的SSI模块时钟使能位。同时,通过引脚复用功能配置,将对应的GPIO引脚设置为SSI功能(SSIClk,SSIFss,SSITx,SSIRx)。
第二步:禁用SSI模块在修改关键配置寄存器(SSICR0,SSICR1等)之前,必须先清除SSICR1中的SSE(Synchronous Serial Port Enable)位,将其设置为0。这是一个安全锁,防止在运行中更改配置导致通信错误。
第三步:配置主从模式在SSICR1寄存器中,将MS位清0,配置为主模式。
第四步:计算并设置时钟参数这是配置的难点和核心。SSI的比特率计算公式为:SSIClk = CMCLK / (CPSDVSR * (1 + SCR))其中:
CMCLK:系统提供给SSI模块的时钟源频率(本例为20MHz)。CPSDVSR:SSICPSR寄存器中的预分频值,必须是2到254之间的偶数。SCR:SSICR0寄存器中的时钟速率参数,范围0-255。
我们的目标是SSIClk = 1 MHz。 代入公式:1 MHz = 20 MHz / (CPSDVSR * (1 + SCR))我们需要寻找一对合适的CPSDVSR(偶数)和SCR(整数)值。 一个常见的策略是先确定CPSDVSR。为了获得较精细的速率调整,通常先设一个较小的偶数分频。假设我们设CPSDVSR = 2。 则公式变为:1 = 20 / (2 * (1+SCR))=>2*(1+SCR) = 20=>1+SCR = 10=>SCR = 9。 校验:20 MHz / (2 * (1+9)) = 20 MHz / 20 = 1 MHz。完美匹配。 因此,我们向SSICPSR寄存器写入0x2,向SSICR0的SCR字段(位15-8)写入0x9。
第五步:配置SSICR0其他位
SPH和SPO:根据需求设置。本例中SPO=1,SPH=1,即SPH位(bit7)和SPO位(bit6)都置1。FRF:选择帧格式。0x0为Freescale SPI格式。DSS:选择数据位宽。8位数据对应0x7。 我们需要组合这些值写入SSICR0。寄存器位域如下:- Bits 15-8:
SCR = 0x09 - Bit 7:
SPH = 1 - Bit 6:
SPO = 1 - Bits 5-4:
FRF = 0x0 - Bits 3-0:
DSS = 0x7计算其十六进制值:SCR部分0x09左移8位是0x0900。SPH=1是0x80,SPO=1是0x40,FRF=0是0x00,DSS=7是0x07。 总和:0x0900 + 0x80 + 0x40 + 0x00 + 0x07 = 0x09C7。 因此,向SSICR0寄存器写入0x000009C7。
第六步:(可选)配置中断或DMA如果需要使用中断,则配置SSIIM寄存器,使能所需的中断源(如接收FIFO非空中断RXIM)。 如果需要使用DMA进行大数据块搬运,则需配置SSIDMACTL寄存器,使能发送(TXDMAE)或接收(RXDMAE)DMA通道,并正确设置µDMA控制器。
第七步:使能SSI模块最后,将SSICR1寄存器中的SSE位置1,SSI模块开始工作,时钟信号将根据配置产生。
完整的C语言配置代码示例(基于寄存器直接操作):
// 假设寄存器地址已定义 #define SSI0_CR1_R (*((volatile uint32_t *)0x40008004)) #define SSI0_CPSR_R (*((volatile uint32_t *)0x40008010)) #define SSI0_CR0_R (*((volatile uint32_t *)0x40008000)) #define SSI0_DR_R (*((volatile uint32_t *)0x40008008)) #define SSI0_SR_R (*((volatile uint32_t *)0x4000800C)) void SSI0_Master_Init(void) { // 1. 确保SSI模块时钟和引脚已在上层函数中使能 // 2. 禁用SSI (SSE=0) SSI0_CR1_R &= ~0x00000002; // 清除SSE位 // 3. 配置为主模式 (MS=0) SSI0_CR1_R = 0x00000000; // 同时确保其他位为0 // 4. 设置时钟预分频 (CPSDVSR = 2) SSI0_CPSR_R = 0x00000002; // 5. 配置CR0: SCR=9, SPH=1, SPO=1, FRF=0 (SPI), DSS=7 (8-bit) SSI0_CR0_R = 0x000009C7; // 0x09<<8 | 1<<7 | 1<<6 | 0x0<<4 | 0x7 // 6. (可选) 配置中断掩码,例如使能接收中断 // SSI0_IM_R |= 0x00000004; // 设置RXIM位 // 7. 使能SSI模块 SSI0_CR1_R |= 0x00000002; // 设置SSE位 } uint8_t SSI0_TransferByte(uint8_t data) { // 等待发送FIFO有空间 (TNF != 0) while((SSI0_SR_R & 0x00000002) == 0) { // 等待,或可在此处加入超时机制 } // 写入数据(右对齐,8位数据写入低16位) SSI0_DR_R = data; // 等待接收FIFO有数据 (RNE != 0) while((SSI0_SR_R & 0x00000004) == 0) { // 等待 } // 读取数据(硬件已右对齐) return (uint8_t)(SSI0_DR_R & 0x00FF); }4. 中断与DMA机制的高级应用
对于高效的系统,轮询(Polling)方式读取SSISR状态位是最简单但效率最低的。SSI提供了丰富的中断和DMA机制来解放CPU。
4.1 中断源与处理策略
SSI的中断事件被“或”在一起,向中断控制器产生一个单一的SSI中断请求。具体是哪个事件触发的,需要查询SSIRIS(原始中断状态)或SSIMIS(已屏蔽中断状态)寄存器。
主要中断源:
- 接收FIFO服务中断 (
RXIM):当接收FIFO中的数据量达到预设的触发水位(例如半满)时产生。适合在接收数据流时,批量读取FIFO。 - 发送FIFO服务中断 (
TXIM):当发送FIFO中的空位达到预设的触发水位时产生。适合在需要连续发送数据时,批量填充FIFO。 - 接收超时中断 (
RTIM):这是一个非常实用的中断。当接收FIFO从空变为非空后,会启动一个32个SSIClk周期的超时定时器。如果在超时前FIFO被读空,定时器重置;如果超时后FIFO中仍有数据,则触发此中断。这用于处理“最后一包”数据:当主设备发送完数据后,从设备可能还有最后一个字节在途中,主设备发送结束就停止了时钟,此时接收FIFO里可能还剩1-2个字节。超时中断能确保这些“残留”数据被及时读取。 - 接收溢出中断 (
RORIM):当接收FIFO已满,但硬件又试图往里面存入新数据时触发。这表明CPU或DMA读取速度跟不上接收速度,是严重的错误,通常需要检查系统设计。 - 传输结束中断 (
EOTIM):当发送FIFO为空且移位寄存器的最后一位已发出时触发。这个中断非常有用,它可以安全地指示一次传输序列的完全结束。例如,在驱动一个SPI显示屏发送完一帧图像数据后,可以利用EOT中断来安全地关闭SSI模块时钟以节能,或者切换片选信号操作下一个设备。
避坑指南:接收超时中断的清除。在超时中断服务程序(ISR)中,正确的操作顺序是:先读取接收FIFO中的数据,然后立即向
SSIICR寄存器的RTIC位写1来清除中断标志。切忌在读取FIFO之前清除,也切忌在中断返回前过晚清除。如果清除得太晚,可能在中断返回前硬件又满足了超时条件,导致中断被不必要地再次触发。
4.2 DMA传输配置与陷阱
对于需要搬运大量数据的场景(如音频流、图像数据),使用DMA是必须的。SSI模块与µDMA控制器紧密耦合,提供独立的发送和接收通道。
DMA请求触发条件:
- 发送通道:
- 单次请求:发送FIFO中至少有1个空位置时触发。
- 突发请求:发送FIFO中至少有4个空位置时触发。
- 接收通道:
- 单次请求:接收FIFO中至少有1个数据时触发。
- 突发请求:接收FIFO中至少有4个数据时触发。
通过配置SSIDMACTL寄存器的TXDMAE和RXDMAE位来使能相应通道的DMA。DMA控制器会根据通道配置,决定使用单次还是突发传输模式。
DMA使用中的一个关键陷阱:当µDMA完成一次从发送FIFO的数据传输后,SSIRIS寄存器中的DMATXRIS位会被置位。这个位不能通过向SSIICR寄存器的DMATXIC位写1来清除!正确的清除流程必须在DMA传输完成中断服务程序中进行:
- 在DMA完成ISR中,首先禁用SSI的发送DMA使能(清除
SSIDMACTL中的TXDMAE位)。 - 然后,再向
SSIICR的DMATXIC位写1。 - 如果需要再次启动DMA传输,则重新使能
TXDMAE位。
如果不按这个顺序操作,DMA完成中断标志可能无法正确清除,导致中断持续触发或状态混乱。对于接收DMA完成中断(DMARXRIS),处理逻辑类似。
5. 调试技巧与常见问题排查
即使配置看起来完全正确,实际调通SSI/SPI通信也常常会遇到问题。下面是我在多年调试中总结的一些实战技巧和常见问题的排查思路。
5.1 硬件连接与信号测量
问题现象:通信完全无反应,读回的数据固定为0xFF或0x00。
- 排查:
- 电源与地:首先确认主从设备共地,电源电压符合要求。
- 引脚连接:再三检查
SSIClk,MISO,MOSI,SS四条线是否接反、接错或虚焊。特别是MISO和MOSI,很容易搞混。 - 片选信号:确认片选信号(
SSIFss)是否有效。用逻辑分析仪或示波器查看,在传输期间它是否被拉低(SPI模式)。有些从设备要求片选在字节之间也需要保持低电平(连续传输),有些则要求每个字节都重新拉低。 - 时钟信号:测量
SSIClk引脚是否有波形输出?频率是否符合预期?如果完全没有时钟,检查SSI模块是否已使能(SSE=1),以及GPIO引脚是否正确复用为SSI功能。 - 上拉电阻:对于开漏输出的信号线(某些从设备的MISO),是否缺少上拉电阻?
5.2 软件配置与逻辑分析
问题现象:有时能读到数据,但数据错误、不稳定。
- 排查:
- 模式匹配:这是最高频的错误源!用逻辑分析仪同时抓取
SSIClk、MOSI、MISO、SS四路信号。对照抓取的波形,逐一核对:- 时钟空闲电平(
SPO)对吗? - 数据是在哪个时钟边沿采样(
SPH)的?第一个边沿还是第二个? - 数据是在哪个时钟边沿变化的? 确保你的SSI配置与外设数据手册的时序图完全一致。
- 时钟空闲电平(
- 时钟速率:比特率是否超过从设备支持的最大值?尝试降低
SCR或增大CPSDVSR,用低速先测试通。 - 数据位序:确认是MSB先行还是LSB先行。SSI固定为MSB先行,有些外设可能要求LSB先行,这时就需要在软件里对每个字节进行位反转。
- 数据位宽:你配置的
DSS(如8位)和外设期望的(如16位)是否一致?读写SSIDR时是否做了正确的右对齐处理? - FIFO与中断:如果使用中断,是否正确使能和清除了中断标志?中断服务函数是否高效地读/写了FIFO?是否发生了溢出(Overrun)?检查
SSIRIS寄存器的RORRIS位。 - 延时问题:在片选有效到发送第一个字节之间,以及连续字节之间,从设备是否需要一定的建立时间(
t_SU)?在快速连续操作时,可以在两次SSIDR写入之间加入短暂延时,或检查TNF状态位。
- 模式匹配:这是最高频的错误源!用逻辑分析仪同时抓取
5.3 逻辑分析仪使用技巧
一个支持协议解码的逻辑分析仪是调试串行总线不可或缺的工具。
- 设置:将采样率设置为时钟频率的5-10倍以上。正确配置解码器为SPI,并指定
CLK,MOSI,MISO,CS通道,设置正确的时钟极性和相位。 - 观察:
- 看解码出的数据字节是否与你发送/期望的一致。
- 观察片选信号的行为,特别是在连续传输模式下是否符合预期。
- 如果通信失败,看是在第几个时钟周期出现问题,数据线是否在采样边沿已经稳定(建立时间和保持时间是否满足)。
5.4 常见问题速查表
| 问题现象 | 可能原因 | 排查方向 |
|---|---|---|
| 读回数据全是0xFF | 从设备未响应,MISO线可能为高阻态 | 检查片选信号、从设备电源/使能、MISO线上拉电阻、主从模式是否设反(从设备应配置为SPI��模式)。 |
| 读回数据全是0x00 | 主设备MISO引脚输入配置错误,或硬件短路 | 检查GPIO输入配置,测量MISO线电平。 |
| 数据错位(如0x55读成0xAA) | 时钟相位(SPH)配置错误 | 用逻辑分析仪核对采样边沿,切换SPH设置试试。 |
| 数据位反转(如0x01读成0x80) | 位序错误(MSB/LSB) | SSI固定MSB先行,检查外设是否要求LSB先行,是则需软件位反转。 |
| 只有第一个字节正确 | 片选信号行为错误 | 检查是每字节拉低还是一次传输拉低。对于需要每字节拉低的从设备,在连续传输时需将SSIFss在字节间拉高再拉低。 |
| 通信随机出错 | 时钟速率过快,时序裕量不足 | 降低比特率。检查PCB走线,过长或干扰大的线可能需串联小电阻或降低速率。 |
| DMA传输卡住 | DMA中断标志未正确清除 | 严格按照“先禁用DMA使能位,再清中断标志”的顺序操作。检查DMA通道配置(源/目标地址、传输大小、循环模式等)。 |
调试是一个耐心和逻辑结合的过程。从最基础的电源、地、连线查起,然后用逻辑分析仪这个“眼睛”看清实际发生的通信过程,将实际波形与理论时序、配置参数进行比对,大部分问题都能迎刃而解。记住,SPI/SSI通信是硬件行为,软件配置只是给了硬件一个指令,最终的一切都要以逻辑分析仪上看到的波形为准。
