SPI通信从原理到调试:CPOL/CPHA、片选与DMA实战指南
2026/9/23 17:24:36 网站建设 项目流程

调一块MT6701磁角度传感器,逻辑分析仪上SCLK和MOSI波形看着都正常,MISO也有翻转,但寄存器值读回来怎么都不对。折腾了一下午,最后发现是CPOL配反了——SCLK空闲实际是高电平,我在代码里配成了低电平。

SPI就是这样,作为串行数据传输总线里“看着最简单”的一种,四根线、全双工、没有地址帧、没有应答机制,好像看两眼时序图就能写驱动。可真到了板子上,拓扑、时钟极相、片选策略、DMA中断,任何一个环节都能让数据变得不像话。这篇文章把SPI从原理到接线、从时序到调试、从CubeMX配置到实际项目经验完整过一遍。刚开始学SPI的工程师能顺着走通,被SPI折磨过的老手也可以回来对一下排查思路。

1. 串行总线不止一种,SPI靠什么立足

串行传输这个概念本身,就是为了对抗并行总线那堆“线”的问题。并行接口一次传一个字节,速度快,但8位甚至16位数据线加上时钟、控制线,走线全是成本,高速时线间串扰还特别大。于是串行总线把数据变成一位一位地传,用很少的线换来可接受的速率,SPI、I2C、UART都是这个思路,但它们各自的侧重点完全不同。

UART是最老的方案,两根线,全双工,点对点通信,靠双方约定波特率来保证时序。它的上限速度和协议灵活性都一般,常见的也就几Mbps,但实现极其简单,调试口、GPS模块、蓝牙模块这些低速率设备至今还在大量用它。I2C用两根线(SDA+SCL)就能挂一堆设备,靠地址寻址,协议自带ACK/NACK应答,硬件上节省引脚,但代价是协议帧开销大,标准模式只有100kHz,快速模式400kHz,高速模式也才3.4MHz,还要处理总线仲裁和时钟拉伸。

SPI是Motorola定义的一套接口,四根线:MOSI、MISO、SCLK、CS。特点一句话就能说清:主机控制时钟,片选选中谁就跟谁通信,数据是全双工地怼着走。没有地址,没有应答,没有帧格式,想传多少位就传多少位,时钟能跑到几十MHz,协议开销几乎为零。

四类常用串行总线的定位差异,我一般用下面这张表来看:

项目SPII2CUART
线数4根(含片选)2根2根
通信方式全双工半双工(一般)全双工
速率几十MHz最高数MHz通常几Mbps以内
多设备支持靠CS片选,从机数受CS引脚限制地址寻址,可挂很多点对点
协议开销极低ACK、地址、NACK等起始位、停止位、校验
典型设备Flash、SD卡、传感器、显示屏EEPROM、温湿度、RTC调试口、蓝牙、GPS

SPI站住脚的真正原因,是它把“传输”这件事做到了最简单的极致。在I2C上,主机要读一个传感器的数据,得先发设备地址、再发寄存器地址、等ACK、重发起始条件、再读数据、最后回NACK和停止位。而在SPI上就是拉低CS,把时钟给够,数据就回来了。所以凡是涉及高速、大批量、低延迟数据传输的场合,比如SPI Flash读写、SD卡、高刷新率屏幕、高精度ADC、角度传感器,基本都在用SPI。

SPI这种“无协议”特性也是一把双刃剑。没有像I2C那样的标准ACK,意味着从机到底有没有正确收到命令,主机不能靠一个硬件应答位来判断。所有“通信是否成功”的确认,都得靠应用层手动去读状态寄存器。这也是一开始很多做惯了I2C的人转换到SPI时最不适应的一点:通信不成功,连个报错都没有,只能靠逻辑分析仪。

2. 四根线的江湖:SPI主从模型和片选的设计玄机

2.1 认识四根线:MOSI/MISO/SCLK/CS各管什么

先把四根线的职责理清楚。

  • MOSI(Master Output Slave Input):主机输出、从机输入。主机发出去的命令、地址、数据全都走这根线。
  • MISO(Master Input Slave Output):从机输出、主机输入。从机回给主机的数据走这根线。
  • SCLK:串行时钟,由主机产生。时钟线是整个SPI通信的节拍器,没有时钟就没有数据传输。
  • CS/SS/NSS:片选信号,一般是低有效。主机把CS拉低,相当于对某个从机说“我要开始跟你说话了”,其他从机看到自己的CS还是高电平,就知道这次通信跟自己无关。

时序上有个容易被忽视的关键点:SPI的时钟必须由主机独占控制。从机的数据是怎么出来的?就是靠时钟边沿把内部移位寄存器里的数据“推”出去。主机不给时钟,从机就永远不动作。SPI也因为这个特性,天然是主从模式,而且总是主机发起通信,从机没有主动上报的能力。

那如果从机有突发事件要通知主机怎么办?只能靠一个额外的中断引脚(比如DRDY、INT),或者主机定时去轮询状态寄存器。这在实际项目里要记得,别让软件设计师拿着“SPI能不能做成从机主动上报”这种需求来找你,协议层面不支持。

2.2 单主多从的两种接法:独立片选与菊花链

一个主机挂多个SPI从机,最常见的是“独立片选”接法:所有从机的MOSI、MISO、SCLK并联到同一条总线上,每个从机的CS分别由主机的一个GPIO控制。通信时主机只拉低目标从机的CS,其他从机的CS保持高电平,自动与总线隔离。

这种接法的好处是简单直观,每个从机完全独立,可以是不同厂家、不同型号、不同SPI模式,互不干扰。缺点是CS引脚随着从机数量线性增加,挂4个从机就要占4个GPIO。从机多了,主机引脚不够用,又不愿意上扩展芯片,那就得考虑菊花链。

菊花链接法是把所有从机的数据输出端(SDO)接到下一级的数据输入端(SDI),像一串移位寄存器那样串起来,所有从机的CS并联到同一根线上。发一次数据,数据会像流水一样穿过每一级,一次传输的总位数等于级数乘以每级位数。这种方案特别适合那种“每个芯片只需要一个字节数据”的场景,最常见的就是用多片74HC595级联驱动LED。

菊花链不是所有SPI器件都支持,必须器件手册里明确写了支持菊花链拓扑才行。而且每一级会有延迟累积,频率不能拉太高,调试时数据先到哪一级后到哪一级也得掰扯清楚。我自己的原则是:能走独立CS绝不上菊花链,除非是从机数量太多实在挤不出引脚。

2.3 硬件片选和软件片选:一个让数据时好时坏的经典坑

热词榜上“SPI硬件片选与软件片选”排在很前面,说明这个问题坑过不少人。简单说,MCU的SPI外设提供两种片选管理方式。

软件片选(SSM=1):把NSS引脚从SPI外设里释放出来,当作普通GPIO使用。通信前用GPIO拉低CS,通信结束后再拉高。字面意义上的“软件控制,想怎么拉就怎么拉”。好处是灵活,任何GPIO都能当CS,多从机分派方便,CS的拉低、拉高时机完全由自己掌控,想加延时加延时。

硬件片选(SSM=0):由SPI外设硬件自动管理NSS引脚。配置好之后,主机启动传输时,硬件会在第一个bit之前自动把NSS拉低,传输结束自动拉高。好处是时序非常精确,完全由外设保证,省掉GPIO操作,适合高频连续传数据的场景。

我这里要特别提醒硬件片选的一个大坑:STM32F1系列的NSS引脚内部没有默认上拉,如果配置成硬件片选,外部又不接上拉电阻,NSS引脚就会悬空。引脚电压一旦浮在不确定电平,外设会认为NSS被拉低或产生模式错误,SPI通信就会变成“时好时坏”的玄学问题。所以用外部硬件NSS时,上拉电阻一定要接。

选型上我的经验:

  • 单从机、固定通信、追求稳定时序:用硬件片选,最省心。
  • 多从机、需要灵活切换:用软件片选,GPIO控制更实在。
  • CS拉低后需要在真正发时钟前等待一段时间(很多从机要稳定时间):用软件片选,因为它可以在拉低CS后随便加延时,而硬件片选一旦启动传输,时钟立刻就来。
  • 高频连续读写、不想让CPU掺和CS操作:用硬件片选。

千万别做“配置了软件NSS,又同时把NSS引脚配置成了SPI复用功能”这种操作。引脚功能和外设管理方式不一致,通信就会在“能通”和“不能通”之间随机游走,这种问题查起来最耗时间。

3. CPOL/CPHA不是玄学:SPI四种模式的波形记忆法和调错经验

3.1 边沿采样是一切的核心

SPI通信的本质是“边沿采样”。从机在SCLK的某个边沿把数据线上的电平锁存进移位寄存器,在另一个边沿把数据输出。问题就出在“哪个边沿”上。

不同厂家的器件,有的在上升沿采样,有的在下降沿采样,有的要求SCLK空闲时是高电平,有的要求是低电平。主机配置的时候必须跟从机的要求完全一致,否则就会采样到错误的数据。SPI用两个参数组合出四种模式,这就是CPOL和CPHA。

CPOL(Clock Polarity)决定SCLK空闲时的电平:

  • CPOL=0:空闲低电平,SCLK平时趴在地上,传输时跳高。
  • CPOL=1:空闲高电平,SCLK平时悬在天上,传输时拉低。

CPHA(Clock Phase)决定数据在哪个边沿被采样:

  • CPHA=0:第一个边沿采样。
  • CPHA=1:第二个边沿采样。

组合出来就是:

模式CPOLCPHA空闲电平采样边沿常见场景
Mode 000第一个边沿(上升沿)最常用,多数Flash、传感器
Mode 101第二个边沿(下降沿)部分传感器
Mode 210第一个边沿(下降沿)部分ADC
Mode 311第二个边沿(上升沿)很多器件也默认支持

3.2 怎么背怎么配:别记型号,记波形

很多刚入门的人喜欢背“某某芯片是Mode 3”之类的结论,我一般不建议这么干。同一个系列的Flash,不同厂家、不同批次,支持的SPI模式可能不一样。最可靠的习惯是拿到芯片手册直接翻到SPI时序那一页,看它画出来的波形。

时序图里一般会标注“Data sampled on the rising edge of SCLK”或者画采样箭头,直接翻译成配置:

  • 采样边沿是第一个边沿,CPHA=0;是第二个边沿,CPHA=1。
  • SCLK在CS拉低之前停留在高电平,CPOL=1;停留在低电平,CPOL=0。

看波形而不是背模式号,这是避免踩坑最朴素也最有效的办法。

调试初期如果手头没有时序图,或者时序图画得含糊,我一般先试Mode 0。绝大多数SPI器件默认支持Mode 0,不行再试Mode 3。这两个模式是“同相”的,只是空闲电平反了一下,很多器件的手册里直接说兼容Mode 0和Mode 3,所以优先在这两个里试。

3.3 模式配错的典型症状

模式配错时,读回来的数据不是完全乱掉,而是有规律地错。搞清楚这个规律,能帮你快速定位问题。

  • 读回全0xFF或全0x00:大概率不是模式问题,先查CS有没有拉低、从机有没有上电。
  • 能读,但数据错位,比如要读0x55读回来0xAA或者0x2A这种“看着有点关系但不对”的值:典型的CPHA配错。采样边沿差了一个,相当于数据在时间轴上错了一拍,位就对齐错了。
  • 值对一半,或者偶尔错一个bit:一般是时序余量不足,频率太高或者线路干扰。
  • 读出来的值整体翻过来了:多半是MSB/LSB配置反了,和CPOL/CPHA无关。

遇到SPI数据不对,第一步不是去改硬件,而是用逻辑分析仪抓波形,看解出来的bit流到底长什么样。这就引到下一节,SPI调试怎么一步步来。

4. 波形不对时先别怀疑芯片:SPI调试的完整排查链路

“SPI通信不生效”是搜索热词里被问得最多的一个。做技术支持这些年,我发现SPI问题90%都出在几个固定环节,而且这些环节有非常明确的排查顺序。我不建议一上来就改代码,更不建议直接怀疑芯片是坏的,按下面这条路走,大部分问题能在半小时内定位。

4.1 排查顺序:从物理层到协议层

第一步,确认接线。MOSI和MISO接反,是新手最常犯的错。主机的MOSI要接到从机的SDI/SI/DIN,主机的MISO接到从机的SDO/SO/DOUT。很多从机引脚命名不是MOSI/MISO,而是SDI/SDO,接的时候逻辑要对应上,别看见“SDO”就往主机“SD”上乱插。

第二步,确认供电和复位。从机供电电压是不是在手册范围内,电源纹波大不大,复位引脚有没有正确处理。有些传感器复位引脚悬空会自己震荡,SPI怎么配都通不了。这一步看起来基础,但能排除掉一半的“疑难杂症”。

第三步,上逻辑分析仪看CS。CS有没有被拉低?拉低了之后低电平持续了多长时间?是不是有毛刺?CS是SPI的开关,开关动作不干净,后面的数据全白搭。

第四步,看SCLK。SCLK有没有波形?频率对不对?空闲电平是你要的哪种?波形上升沿是不是太缓?如果波形不是方波而是个三角形,说明线上RC负载太重,从机采样时电平还没稳定,数据自然错。

第五步,看MOSI和MISO。主机发出的命令字节对不对?字节顺序对不对?从机到底有没有驱动MISO?MISO如果一直浮空或者没有电平变化,那从机压根没工作或者根本没被正确选中。

第六步,才是回来看代码。初始化顺序对不对,外设时钟开了没有,CS拉低之后有没有给从机留足够的稳定时间,中断和DMA有没有正确配置。

4.2 波形异常对照表

实际操作中,我习惯把异常现象和对策整理成一张表,定位起来特别快:

现象最可能的原因优先检查项
SCLK完全没有波形SPI未使能、GPIO复用配错、外设时钟没开初始化代码、CubeMX引脚配置
CS从不拉低CS引脚配错、软件片选逻辑没执行GPIO配置、代码流程
读回全0xFF从机未选中、从机电源没上、MISO悬空CS时序、电源、MISO上拉
读回全0x00从机一直把MISO拉低、MISO虚焊从机复位、引脚虚焊
数据整体错位CPHA配错、MSB/LSB配置反了模式配置
偶尔错一个bit频率太高、走线太长、干扰降速、缩短走线、加滤波
通信时好时坏NSS引脚悬空、接触不良、电源不稳上拉电阻、焊点、电源纹波

4.3 两个容易漏的物理层问题

第一个是共地。SPI所有信号都是相对GND的,主机和从机之间如果没有共地,波形会在逻辑分析仪上显示得乱七八糟,通信成功率几乎为零。多块板子接在一起调试的时候,检查地线是否连接,永远排在前面。

第二个是高速信号质量。SPI跑到10MHz以上的时候,SCLK边沿会非常陡,如果MISO走线和SCLK靠得近,SCLK的跳变会通过寄生电容耦合到MISO上,造成误采样。这种问题在低速时根本看不到,一升频就冒出来。解决方法是走线拉开距离、中间加地隔离,或者线上串一个小电阻(22Ω到33Ω)压制振铃。

还有一条调试铁律:功能调通之前,先把SPI时钟降到非常低。用72MHz主频跑SPI的人,先把分频系数调到最大,比如让SCLK只有100多kHz,跑通了再说提频的事。很多“SPI不生效”的问题,在低速下自己就消失了,那就排除了协议配置问题,剩下的就是信号完整性问题,再针对性地处理。

5. STM32F103实战:CubeMX配DMA把SPI读数据跑利索

5.1 为什么SPI一定要配DMA

SPI本身是逐字节传输的,如果每收一个字节就进一次中断,高数据率下CPU会被疯狂的SPI中断拖死。比如以1MHz的SCLK读SPI Flash,每秒要传125KB,相当于每8微秒就有一个字节要处理。这还是在SPI外设有硬件FIFO的情况下,F103的SPI连FIFO都很浅,纯粹靠中断搬运的话,CPU大部分时间都在响应中断。

DMA(直接存储器访问)的意义就在于,数据搬运完全由DMA控制器完成,不占用CPU。启动一次DMA传输后,CPU该干嘛干嘛,数据满了DMA就触发一次完成中断,把一整块数据交给应用层。读MT6701这种需要高频连续采样的角度传感器,DMA几乎是标配。

5.2 CubeMX配置步骤

我以一个实际项目为例:STM32F103,SPI1,全双工主机模式,通过DMA读取MT6701磁角度传感器数据。

CubeMX里这么配:

  1. 时钟树:SPI1挂在APB2上,最高72MHz;SPI2/SPI3挂在APB1上,最高36MHz。要高速SPI就优先用SPI1。
  2. SPI1配置:Mode设为Full-Duplex Master,Data Size选16 bits(MT6701角度数据16位一帧),CPOL和CPHA按从机手册选。这里关键参数如下:
// MT6701 手册里SSI模式的数据在SCLK上升沿变化,主机在下降沿采样 // 对应 CPOL=0, CPHA=1,即 SPI Mode 1 // 如果你的芯片就是标准SPI从机模式,则按 Mode 0 或 Mode 3 配置 hspi1.Init.Mode = SPI_MODE_MASTER; hspi1.Init.Direction = SPI_DIRECTION_2LINES; // 全双工 hspi1.Init.DataSize = SPI_DATASIZE_16BIT; // 16位一帧 hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; // CPOL=0 hspi1.Init.CLKPhase = SPI_PHASE_2EDGE; // CPHA=1,Mode 1 hspi1.Init.NSS = SPI_NSS_SOFT; // 软件片选 hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32; // 72MHz/32 = 2.25MHz hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  1. DMA配置:在DMA Settings里添加SPI1_RX和SPI1_TX两个请求。F103上SPI1_RX对应DMA1_Channel2,SPI1_TX对应DMA1_Channel3,CubeMX会自动分配,手动改容易配错。接收方向建议开循环模式(Circular),方便持续采样。
  2. NVIC设置:打开SPI1中断和DMA1_Channel2、DMA1_Channel3中断。
  3. 生成代码。注意main函数里初始化顺序是DMA先于SPI,CubeMX生成的代码已经处理好了,别手工调整顺序。

5.3 用DMA读取MT6701的代码实现

MT6701这类磁角度传感器读取有个特点:读取角度本质上就是主机给时钟,从机把角度数据从MISO送回来,主机在发时钟的同时发送什么数据并不重要。我用16位Receive模式,主机发送一个无意义的0x0000帧,换取从机返回的16位角度数据。

普通方式读取:

uint16_t mt6701_read_raw(void) { uint16_t rx = 0; HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET); // 给一点稳定时间 for (volatile int i = 0; i < 10; i++); HAL_SPI_Receive(&hspi1, (uint8_t *)&rx, 1, 10); HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET); return rx; }

DMA方式连续读多帧:

#define ANGLE_BUF_LEN 8 uint16_t angle_buf[ANGLE_BUF_LEN]; volatile int angle_ready = 0; void mt6701_start_dma_read(void) { angle_ready = 0; HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET); // 启动一次DMA接收,收够N帧后自动停止 HAL_SPI_Receive_DMA(&hspi1, (uint8_t *)angle_buf, ANGLE_BUF_LEN); } void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi) { if (hspi->Instance == SPI1) { // DMA传输完成,CS可以拉高,结束本次通信 HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET); angle_ready = 1; // 在这里处理 angle_buf,提取角度值 } }

用DMA接收时有一个细节要特别注意:CS的拉低要在启动DMA之前完成,CS的拉高要在DMA完成回调里做。如果DMA还在传输,回调里就去拉高CS,数据会少几位。反过来,如果先启动DMA再拉低CS,从机可能没等到CS有效就开始接收,第一帧数据就废了。

如果你用的是DMA循环模式(Circular),那么不会有“传输完成”回调,因为DMA一直在跑。这种情况下通常搭配半传输中断来处理前半段/后半段缓冲区。但CS的拉高拉低就会变得很麻烦,因为循环模式意味着一次CS低电平保持期间持续跑完无数帧,CS根本没法拉到高。所以我的建议是:单从机、固定连续采样,用硬件NSS加DMA循环模式;多从机、需要灵活控制CS,就用软件CS加单次DMA接收,数据来了再启动下一轮。

5.4 实战中的几个坑

CubeMX配置SPI DMA的坑,我列几个真实踩过的:

一是DMA请求添加后,CubeMX不会自动帮你开DMA通道中断。忘了在NVIC里勾选,会导致DMA传完了程序却不知道。二是初始化顺序问题。手动移植代码时如果把SPI_Init放在DMA_Init前面,运行时DMA请求可能没挂上,传输启动后直接死在等待完成标志。三是HAL_SPI_Receive_DMA的第三个参数是指定16位数据的个数,不是字节数。配成字节数会导致DMA搬运量翻倍,缓冲区越界。

还有一个F103特有的坑:SPI在全双工模式下,用HAL_SPI_Receive_DMA读从机数据时,MOSI端口会输出0xFF或者0x00。对于MT6701这种读取时忽略MOSI内容的器件没问题,但有些从机会根据MOSI上的数据进行判断,这时候就得改用HAL_SPI_TransmitReceive_DMA,主机同时发送0x0000并接收。别小看这个差异,不少SPI通信不对的问题就出在这。

6. SPI也有边界:半双工、引导加载与混合存储里的位置

6.1 半双工SPI:什么时候可以只留一根数据线

SPI标准是四根线,但很多MCU支持半双工模式,把MOSI和MISO合并成一根双向数据线,引脚从四根变成三根。代价是同一时间只能单向传输,主机必须切换数据线的传输方向,速度会打折扣。

实际的取舍是:当SPI从机本来就不需要同时收发(比如很多单芯片温湿度传感器,主机发命令时从机不回数据,从机回数据时主机不关心MOSI),半双工模式就能省下一个引脚。但我在项目里用半双工的场景不算多,除非GPIO真的紧张到不行。因为半双工模式需要软件控制数据方向,出现问题的概率比标准全双工高不少,一旦通信异常,排查起来还得把方向切换的时序也考虑进去。

6.2 SPI NOR Flash在启动链里的角色

SPI的另一大应用场景是系统启动介质。SPI NOR Flash容量不大,但支持XIP(Execute in Place,片上执行),CPU可以直接映射地址空间跑里面的代码,不需要先把代码拷贝到RAM。因此很多SoC、交换芯片、网卡芯片都用SPI Flash做引导加载器存储。

RTL9071CP这类网络交换芯片用SPI加载固件,RK3588S这类复杂SoC用SPI NOR存引导、PCIe NVMe SSD存系统,本质逻辑是一样的:引导代码体积小、要求非易失、要上电就能快速执行,SPI NOR正好满足;操作系统和业务数据体积大、需要高速访问,就放到PCIe NVMe SSD上。这种混合存储方案的成功关键,就是SPI部分担任“点火”角色,稳定性要求极高,一旦SPI Flash里引导数据坏了,整板可能就起不来了。

所以做存储型SPI器件的驱动时,要格外重视几个细节:

  • 写Flash之前必须先发送Write Enable命令,直接写会被硬件拒绝。
  • 写完一个page或擦除一个sector后必须轮询状态寄存器的忙位,确认操作完成才能进行下一步。
  • 不同厂商的SPI Flash命令集大体兼容,但细节有差异,严格按照JEDEC ID识别型号后再决定命令序列。

6.3 混合存储方案里的片选与性能设计

回到RK3588S或类似平台的混合存储方案,SPI部分的设计不只是在核心板上一颗Flash那么简单。实际项目中还要考虑:SPI Flash的时钟频率选多高、供电是3.3V还是1.8V(不同电压对应不同型号)、要不要在量产时烧录一次性校准数据和序列号、系统升级失败时能不能从SPI引导做个恢复模式。

低层驱动跑通之后,还要考虑性能。SPI Flash读速度跟SCLK频率和命令模式(普通读、双线读、四线读)直接相关。想用SPI Flash直接跑日志系统,吞吐不够肯定不行。这里要提醒的是,系统级优化要把SPI主控的DMA、缓存、Flash的QSPI模式打通,而不是简单地提个频就完事。

片选策略在混合存储方案里也会被放大:如果核心板上有SPI Flash、传感器、实时时钟好几个SPI从机,而且分散在不同电压域,就要特别小心CS引脚的电平转换。3.3V的CS直接连到1.8V的从机引脚,轻则通信异常,重则烧坏IO。

最后再分享两个我自己的习惯。调任何SPI设备,第一次跑通之前先把SCLK降到1MHz以下,功能通了再慢慢提频,能省去无数查信号完整性的时间。另一点是把SPI模式、分频、位序这些参数集中在头文件里用宏定义,调试时一口气切换所有配置,比一行一行改代码方便得多。SPI这四根线的门道,说到底也就这么多,但每一根线背后都有足够多的坑等着你踩。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询