欢迎光临
我们一直在努力

嵌入式开发笔记:SPI通讯协议精讲——从片选配置到电夹爪案例

嵌入式开发笔记:SPI通讯协议精讲——从片选配置到电夹爪实战

文章目录

  • 嵌入式开发笔记:SPI通讯协议精讲——从片选配置到电夹爪实战
    • @[toc]
    • 1. 前言:为什么SPI是嵌入式开发者的必修课
    • 2. SPI总线基础:四根线背后的故事
      • 2.1 四根信号线
      • 2.2 一主多从的拓扑结构
    • 3. SPI的四种工作模式:CPOL与CPHA
      • 3.1 CPOL:时钟极性
      • 3.2 CPHA:时钟相位
      • 3.3 四种模式组合
    • 4. 片选(CS)配置:SPI的灵魂所在
      • 4.1 CS的本质:低电平有效
      • 4.2 硬件片选 vs 软件片选
      • 4.3 CS的时序要求
    • 5. 多从机场景下的片选方案设计
      • 5.1 方案一:独立片选(推荐)
      • 5.2 方案二:菊花链(Daisy Chain)
      • 5.3 方案三:译码器扩展
    • 6. 实战案例:电夹爪的SPI通信与控制
      • 6.1 系统架构
      • 6.2 通信协议设计
      • 6.3 片选配置要点
      • 6.4 代码示例
      • 6.5 常见问题与排查
    • 7. SPI调试心得:那些年踩过的坑
      • 7.1 片选相关的坑
      • 7.2 时钟相关的坑
      • 7.3 调试工具推荐
    • 8. 总结

1. 前言:为什么SPI是嵌入式开发者的必修课

在嵌入式开发中,SPI(Serial Peripheral Interface)是最常用的高速同步串行通信协议之一。无论是Flash存储芯片、LCD显示屏、传感器模块,还是本文将要重点讲解的电夹爪,SPI都扮演着不可或缺的角色。

与I²C相比,SPI拥有更高的数据吞吐能力、更强的灵活性以及更低的协议复杂度。但正因为其灵活性,SPI的配置——尤其是片选(CS)信号的配置——往往成为新手工程师最容易栽跟头的地方。

本文将从一个实际项目视角出发,深入剖析SPI协议原理,重点讲解片选配置的种种细节,并以电夹爪控制为例,展示SPI在工业设备中的典型应用。 > 📌 **配图位置**:建议在此处插入一张“SPI总线典型应用场景图”,展示MCU通过SPI连接Flash、LCD、传感器和电夹爪等外设。


2. SPI总线基础:四根线背后的故事

SPI是一种全双工、同步的串行通信协议,由Motorola公司首创。其通信采用主从模式,一个主设备(Master)可以控制一个或多个从设备(Slave)。

2.1 四根信号线

标准的SPI接口由以下四根线组成:

信号线全称方向(相对主机)功能
SCK Serial Clock 主机输出 主设备生成的时钟信号,控制数据传输节奏
MOSI Master Out Slave In 主机输出 主设备发送数据,从设备接收
MISO Master In Slave Out 主机输入 从设备发送数据,主设备接收
CS/SS Chip Select / Slave Select 主机输出 片选信号,用于激活某个从设备

SPI是全双工通信:在每个SCK周期,主设备向从设备发送一位数据的同时,也会接收从设备响应的一位数据。

2.2 一主多从的拓扑结构

在实际项目中,一个MCU往往需要连接多个SPI从设备。典型的一主多从拓扑如下:

  • 共享总线:所有从设备并联SCK、MOSI、MISO三根线
  • 独立片选:每个从设备有独立的CS引脚,由主设备分别控制

MCU (Master)
├── SCK ────────┬────────┬────────┐
├── MOSI ────────┼────────┼────────┤
├── MISO ◄───────┼────────┼────────┤
├── CS0 ────────► Flash │ │
├── CS1 ────────► LCD │ │
└── CS2 ────────► 电夹爪 │ │

SPI通信以CS线置低电平为开始信号,以CS线被拉高作为结束信号。当CS为高电平时,从设备与SPI总线断开连接,不响应任何通信。


3. SPI的四种工作模式:CPOL与CPHA

SPI的灵活性很大程度上体现在时钟极性(CPOL) 和时钟相位(CPHA) 这两个参数上。主设备和从设备必须工作在相同的模式下才能正常通信。

3.1 CPOL:时钟极性

CPOL决定SCK在空闲状态时的电平:

  • CPOL = 0:SCK空闲时为低电平
  • CPOL = 1:SCK空闲时为高电平

3.2 CPHA:时钟相位

CPHA决定数据在SCK的哪个边沿被采样:

  • CPHA = 0:在SCK的第一个跳变沿采样数据
  • CPHA = 1:在SCK的第二个跳变沿采样数据

3.3 四种模式组合

SPI模式CPOLCPHA空闲时SCK电平采样时刻
模式0 0 0 低电平 第一个边沿(上升沿)
模式1 0 1 低电平 第二个边沿(下降沿)
模式2 1 0 高电平 第一个边沿(下降沿)
模式3 1 1 高电平 第二个边沿(上升沿)

实际工程中,模式0和模式3最为常用。具体用哪种模式,必须查阅从设备的数据手册。

📌 配图位置:建议在此处插入一张“SPI四种模式时序对比图”。


4. 片选(CS)配置:SPI的灵魂所在

如果说SPI的四根线是一支乐队,那么CS就是指挥家——它决定了什么时候开始演奏、什么时候停止。片选配置不当,是整个SPI通信中最常见的故障根源。

4.1 CS的本质:低电平有效

SPI的CS信号通常是低电平有效:

  • CS = 低电平:从设备被选中,开始响应SPI通信
  • CS = 高电平:从设备未被选中,与总线断开

关键点:当从设备未被选中时,其MISO引脚必须设置为高阻态,否则会与总线上其他设备产生冲突。

4.2 硬件片选 vs 软件片选

片选控制方式分为两种:

控制方式实现方法优点缺点
硬件片选 由SPI外设硬件自动控制CS CPU负担小,时序精准 灵活性差,部分MCU硬件CS有BUG
软件片选 由代码通过GPIO手动拉高/拉低CS 灵活可控,易于调试 占用CPU时间

硬件片选的“坑” :有些MCU的SPI硬件CS在TX FIFO为空时会自动拉高,这会导致多字节连续传输时CS在帧间隙被意外释放。遇到这种情况,果断改用软件片选是最直接的解决方案。

软件片选的实现(以STM32 HAL库为例):

// 片选拉低(选中从设备)
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET);

// SPI数据传输
HAL_SPI_TransmitReceive(&hspi, tx_data, rx_data, length, timeout);

// 片选拉高(释放从设备)
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);

💡 工程建议:在实际项目中,优先使用软件片选。虽然多写几行代码,但能避免很多硬件片选带来的时序问题,调试起来也更加直观。

4.3 CS的时序要求

不同从设备对CS的时序要求不同,通常需要关注:

  • 建立时间:CS拉低到第一个SCK时钟到来之间的时间(通常>10ns)
  • 保持时间:最后一个SCK时钟到CS拉高之间的时间(通常>20ns)
  • CS释放延时:两次通信之间CS保持高电平的时间

调试技巧:用示波器或逻辑分析仪抓取CS、SCK、MOSI、MISO的波形,是排查SPI问题最有效的手段。


5. 多从机场景下的片选方案设计

当需要连接多个SPI从设备时,片选方案的设计就变得至关重要。

5.1 方案一:独立片选(推荐)

每个从设备分配一个独立的GPIO作为CS引脚。

优点:

  • 时序清晰,各从设备互不干扰
  • 响应迅速,实时性好
  • 调试方便,可单独控制每个设备

缺点:

  • 占用较多的GPIO引脚
  • 当从设备数量很多时,GPIO可能不够用

代码示例(STM32):

// SPI外设的MOSI、MISO、SCK正常使用
// 片选改用GPIO控制
#define CS_SLAVE1_PIN GPIO_PIN_1
#define CS_SLAVE1_PORT GPIOC
#define CS_SLAVE2_PIN GPIO_PIN_2
#define CS_SLAVE2_PORT GPIOC

// 选中从设备1
HAL_GPIO_WritePin(CS_SLAVE1_PORT, CS_SLAVE1_PIN, GPIO_PIN_RESET);
// 通信…
HAL_GPIO_WritePin(CS_SLAVE1_PORT, CS_SLAVE1_PIN, GPIO_PIN_SET);

5.2 方案二:菊花链(Daisy Chain)

所有从设备的CS连接在一起,数据从一个从设备串行传递到下一个。

优点:节省GPIO资源

缺点:

  • 协议复杂,需要从设备支持菊花链模式
  • 延迟累积,通信效率降低
  • 一个设备故障会影响整个链路

适用场景:从设备数量多、GPIO资源紧张、且从设备本身支持菊花链的情况。

5.3 方案三:译码器扩展

当GPIO实在不够用时,可以使用3-8译码器(如74HC138)来扩展片选信号。

3个GPIO → 74HC138 → 8路CS输出

适用场景:从设备数量多(>5个)、且对实时性要求不极端苛刻的系统。


6. 实战案例:电夹爪的SPI通信与控制

电夹爪(电动夹爪)是工业自动化和机器人领域常见的末端执行器。现代电夹爪通常集成了无刷伺服系统、高精度力传感器,支持精密力、位混合控制。而SPI正是其内部控制器与主控MCU之间常用的通信方式之一。

6.1 系统架构

典型的电夹爪SPI控制系统架构如下:

主控MCU (Master)

├── SCK ────► 电夹爪控制器 (Slave)
├── MOSI ───► 电夹爪控制器
├── MISO ◄─── 电夹爪控制器
└── CS ────► 电夹爪控制器 (独立片选)

├── 电机驱动 (位置/速度/力矩控制)
├── 力传感器 (夹持力反馈)
└── 位置传感器 (开合位置反馈)

6.2 通信协议设计

电夹爪的SPI通信通常采用命令-响应模式,主控发送指令帧,电夹爪返回状态帧。

典型指令格式:

字节内容说明
Byte 0 命令码 如0x01=打开、0x02=闭合、0x03=设置夹持力
Byte 1 数据高字节 参数值
Byte 2 数据低字节 参数值
Byte 3 校验和 简单校验或CRC

典型响应格式:

字节内容说明
Byte 0 状态码 0x00=成功、0x01=忙、0x02=错误
Byte 1 当前位置高字节 夹爪开合位置反馈
Byte 2 当前位置低字节
Byte 3 当前夹持力 力传感器反馈值

6.3 片选配置要点

在电夹爪的SPI通信中,片选配置尤为关键:

  • 独立片选:电夹爪应使用独立的CS引脚,避免与其他SPI从设备共用
  • 软件片选:建议使用软件GPIO控制CS,确保每次通信的CS时序完全可控
  • CS释放:每次通信结束后必须将CS拉高,否则电夹爪会持续处于“选中”状态,可能影响其内部状态机
  • 6.4 代码示例

    // 电夹爪SPI通信示例(STM32 HAL库)

    #define CLAW_CS_PORT GPIOC
    #define CLAW_CS_PIN GPIO_PIN_1

    // 发送指令并读取响应
    uint8_t claw_send_command(uint8_t cmd, uint16_t param, uint8_t *response, uint8_t resp_len)
    {
    uint8_t tx_buf[4];
    uint8_t rx_buf[4];

    // 组装指令
    tx_buf[0] = cmd;
    tx_buf[1] = (param >> 8) & 0xFF;
    tx_buf[2] = param & 0xFF;
    tx_buf[3] = cmd + tx_buf[1] + tx_buf[2]; // 简单校验

    // 软件片选:拉低CS,选中电夹爪
    HAL_GPIO_WritePin(CLAW_CS_PORT, CLAW_CS_PIN, GPIO_PIN_RESET);

    // 等待一小段时间满足CS建立时间
    delay_us(10);

    // SPI收发数据
    HAL_SPI_TransmitReceive(&hspi1, tx_buf, rx_buf, 4, 100);

    // 软件片选:拉高CS,释放电夹爪
    HAL_GPIO_WritePin(CLAW_CS_PORT, CLAW_CS_PIN, GPIO_PIN_SET);

    // 复制响应数据
    if (response && resp_len > 0) {
    memcpy(response, rx_buf, (resp_len < 4) ? resp_len : 4);
    }

    return rx_buf[0]; // 返回状态码
    }

    // 控制电夹爪闭合(带夹持力设置)
    uint8_t claw_close(uint16_t force)
    {
    return claw_send_command(0x02, force, NULL, 0);
    }

    // 读取电夹爪状态
    uint8_t claw_get_status(uint16_t *position, uint8_t *force)
    {
    uint8_t response[4];
    uint8_t status = claw_send_command(0x04, 0, response, 4);

    if (status == 0x00) {
    *position = (response[1] << 8) | response[2];
    *force = response[3];
    }
    return status;
    }

    6.5 常见问题与排查

    问题现象可能原因解决方法
    电夹爪无响应 CS未正确拉低 检查GPIO配置和电平
    数据错乱 SPI模式不匹配 核对CPOL/CPHA是否与电夹爪手册一致
    通信不稳定 时钟频率过高 降低SCK频率
    CS无法释放 硬件片选自动控制 改用软件片选

    7. SPI调试心得:那些年踩过的坑

    在多年的嵌入式开发中,SPI调试积累了一些“血泪经验”,分享给大家:

    7.1 片选相关的坑

  • CS拉低后立即发数据:有些从设备需要CS拉低后等待一段时间才能接收数据。务必查阅数据手册的建立时间(t_setup) 参数。

  • 多从机共用总线时MISO冲突:当某个从设备未被选中时,其MISO必须为高阻态。如果从设备不支持三态门,需要在硬件上加缓冲器隔离。

  • 硬件片选自动释放:部分MCU的硬件CS在数据发送完成后会自动拉高,导致需要CS持续低电平的多字节操作失败。解决方案:改用软件片选。

  • 7.2 时钟相关的坑

  • 模式不匹配:主从设备的CPOL/CPHA必须一致。用示波器看SCK的空闲电平,一眼就能判断CPOL是否正确。

  • 时钟频率过高:SPI时钟频率受限于最慢的从设备。不要以为MCU能跑多快就设多快。

  • 7.3 调试工具推荐

    • 逻辑分析仪:查看CS、SCK、MOSI、MISO的完整时序,是SPI调试的“眼睛”
    • 示波器:观察信号质量(上升沿、下降沿、毛刺)
    • 环回测试:将MOSI与MISO短接,自发自收,验证SPI硬件是否正常

    8. 总结

    SPI协议虽然只有四根线,但其中的门道却不少。本文从SPI的基础原理出发,重点讲解了片选(CS)信号的配置与管理,这是SPI通信中最关键也最容易出问题的环节。

    核心要点回顾:

  • SPI是高速全双工同步通信协议,主从模式,四线制
  • 四种工作模式由CPOL和CPHA决定,主从必须匹配
  • 片选是低电平有效,建议使用软件片选以获得最大的灵活性和可控性
  • 多从机场景优先采用独立片选方案,时序清晰、易于调试
  • 电夹爪等工业设备的SPI通信,需特别注意CS的建立/保持时间和模式匹配
  • SPI的配置看起来简单,但每一个细节——从CS的拉低时机到SCK的空闲电平——都可能影响通信的成败。希望本文能帮助你在实际项目中少走弯路,让SPI通信“一次成功”。


    📚 参考资料

    • CiA DS402 CANopen驱动与运动控制设备行规
    • SPI协议标准文档(Motorola)
    • 各品牌MCU参考手册与电夹爪产品数据手册

    本文为嵌入式开发笔记系列文章,如有疑问或建议,欢迎在评论区留言讨论。

    赞(0)
    未经允许不得转载:171主机测评 » 嵌入式开发笔记:SPI通讯协议精讲——从片选配置到电夹爪案例
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址