You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

仅能调试STM32主控板,如何验证与EVB-LAN9252-SPI从机的SPI通信?

SPI通信调试问题(STM32F429 Nucleo 主机 + EVB-LAN9252-SPI 从机)

我使用STM32F429ZI Nucleo板作为SPI主机(通过UART辅助调试),EVB-LAN9252-SPI板作为SPI从机,无法对从机端进行调试或检测,需要验证SPI通信是否正常。

第一阶段测试(SPI1主机 + SPI4模拟从机)

我编写了以下测试代码验证SPI工作状态:

while (k < 32)
{
  HAL_UART_Transmit(&huart4, &SPI1_Buffer_Tx[k], 1, 100);
  k++;
}
k = 0;

while (k < 32)
{
  HAL_GPIO_WritePin(GPIOE, GPIO_PIN_9, GPIO_PIN_RESET); // 硬件NSS引脚
  HAL_SPI_Transmit(&hspi1, &SPI1_Buffer_Tx[k], 1, 100);
  HAL_SPI_Receive(&hspi4, &SPI4_Buffer_Rx[k], 1, 100);
  HAL_GPIO_WritePin(GPIOE, GPIO_PIN_9, GPIO_PIN_SET);
  k++;
}
k = 0;

while (k < 32)
{
  HAL_UART_Transmit(&huart4, &SPI1_Buffer_Tx[k], 1, 100);
  k++;
}
k = 0;

while (k < 32)
{
  HAL_UART_Transmit(&huart4, &SPI4_Buffer_Rx[k], 1, 100);
  k++;
}

UART输出结果

abcdefghijklmnopqrstuvwxyzABCDEF // 原始发送缓冲区内容
 bcdefghijklmnopqrstuvwxyzABCDEF // 接收缓冲区内容

这个现象可能是因为通过HAL_SPI_Receive(&hspi4, &SPI4_Buffer_Rx[k], 1, 100);能在模拟从机侧读取到数据。

原项目测试(SPI1主机 + LAN9252从机)

我最初假设主机发送的数据会在从机端循环回传,因此编写了以下代码:

while (k < 32)
{
  HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, GPIO_PIN_RESET);
  HAL_SPI_Transmit(&hspi1, &SPI1_Buffer_Tx[k], 1, 100);
  HAL_SPI_Receive(&hspi1, &SPI1_Buffer_Rx[k], 1, 100);
  HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, GPIO_PIN_SET);
  k++;
}

但主机接收到的是32个0xFF,我有以下疑问:

  1. 数据是否真的会在从机端循环回传,是否是我的操作有误?
  2. 数据似乎已正确发送,但从机未被命令回传数据,导致无法收到有效数据?
    2-1. 若是如此,如何确认从机已正确接收数据?
    2-2. 仅能调试主机板时,如何命令从机回传有效数据?

问题分析与解答

1. 从机自动回传数据的误解

SPI是全双工同步通信,但从机不会自动回传主机发送的数据——除非从机固件被设计成将接收的数据立刻放入发送寄存器。你之前用SPI4模拟从机时收到偏移1位的数据,是SPI通信的时序特性导致:主机发送时钟时,从机必须同步输出数据,若从机未提前准备好发送数据,就会输出上一次的残留数据或默认电平,你看到的偏移是因为收发的时序延迟。

2. 收到全0xFF的核心原因

你收到全0xFF,说明从机在主机接收阶段没有输出有效数据,本质原因是:
LAN9252是SPI接口的以太网控制器,它的通信遵循特定的寄存器读写协议,不会随便回传主机发送的数据,必须先发送对应的读写命令+寄存器地址,才会返回有效数据。

2-1. 确认从机已接收数据的方法

在无法调试从机的情况下,可通过以下方式验证:

  • 抓取SPI硬件信号:用示波器检测SCK、MOSI、NSS的电平、时钟频率、相位/极性,确认是否和LAN9252 datasheet要求的一致(通常为SPI Mode 0或Mode 3)。
  • 读取从机固定寄存器:比如LAN9252的芯片ID寄存器,按手册要求发送读命令,若能读到预期的ID值,说明通信链路正常,从机已正确接收命令。

2-2. 命令从机回传数据的操作方法

必须严格遵循LAN9252的SPI通信协议:

  1. 查阅LAN9252 datasheet,确认SPI帧格式(通常是读写位+寄存器地址+数据的结构)。
  2. 构造符合要求的命令帧,比如读取芯片ID的命令(具体以手册为准)。
  3. 使用HAL_SPI_TransmitReceive()替代分开的Transmit和Receive,因为SPI是同步传输,一次操作同时完成收发,更符合协议要求。示例代码:
uint8_t cmd[3] = {0x00, 0x00, 0x00}; // 示例:读命令+寄存器地址(需按手册修改)
uint8_t rx_data[2];
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, GPIO_PIN_RESET);
// 发送3字节命令,同时接收2字节芯片ID
HAL_SPI_TransmitReceive(&hspi1, cmd, rx_data, sizeof(cmd), 100);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, GPIO_PIN_SET);
// 通过UART输出rx_data,验证是否符合预期

内容的提问来源于stack exchange,提问作者Junseok Oh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 08:04:42