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

STM32F427 SPI Slave与MCP2210主设备无法正常收发数据求助

MCP2210 SPI主设备与STM32F427 SPI从设备通信数据异常排查

背景与配置

使用MCP2210作为SPI主设备(通过HID转USB连接电脑),与STM32F427 MCU SPI从设备通信,采用hidapi库并遵循MCP2210 datasheet配置:

  • SPI模式:Mode 0
  • 比特率:1500
  • CS引脚:连接至MCP2210的GP2
  • 数据传输要求:以64字节块发送,命令格式如下:

MCP2210 SPI传输命令格式

字节索引含义
00x42(SPI数据传输命令码)
1本次传输的字节数(0-60)
2保留(0x00)
3保留(0x00)
4-63待发送的SPI数据

MCP2210预期响应格式

字节索引含义
00x42(回显命令码)
10x00(命令执行成功,SPI数据已接收)
2返回的SPI接收数据字节数
30x10(SPI传输完成,无更多数据)
4-63接收到的SPI数据(数量由字节2指定)

主机端(PC,C++)代码

int main()
{
    unsigned char data[64]; // 发送到从设备的64字节缓冲区
    unsigned char rdata[64]; // 从从设备接收的64字节缓冲区
    int res;

    // 打开HID设备
    hid_device* dev = hid_open(0x04D8, 0x00DE, NULL);
    if (!dev) {
        std::cerr << "Error: can´t open HID" << std::endl;
        return 1;
    }

    // 填充传输缓冲区
    data[0] = 0x00; 
    data[1] = 0x42;      // SPI传输启动命令
    data[2] = 0x3C;  // 发送60字节数据
    data[3] = 0x00;
    data[4] = 0x00; 
    data[5] = 0x01; // 第一个发送数据为0x01(MSB优先)

    for (int r = 6; r<64; r++) {
        data[r] = 0xAA; // 其余填充0xAA
    }

    res = hid_write(dev, data, 64);
    res = hid_read(dev, rdata, 64);  

    if (res < 0) {
        std::cerr << "can´t read HID" << std::endl;
    }

    std::cout << "HID response: \n";
    // 打印接收缓冲区
    for (int i = 0; i < 64; i++) {
        std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)rdata[i] << " ";
    }
    std::cout << std::endl;

    printf("FIN \n");
    hid_close(dev);
    return 0;
}

从机端(STM32F427,C)代码

主函数

#include "main.h"

SPI_HandleTypeDef hspi1;

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_SPI1_Init(void);

#define SPI_TIMEOUT 10000

uint8_t txBuffer[60];
uint8_t rxBuffer[60];

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_SPI1_Init();

    // 注:原代码中重新定义了局部txBuffer/rxBuffer,会覆盖全局变量,已注释
    // uint8_t txBuffer[60];
    // uint8_t rxBuffer[60];

    for (int i = 0; i < 60; i++) {
        txBuffer[i] = 0xAA;
    }

    while (1)
    {
        HAL_SPI_TransmitReceive(&hspi1, txBuffer, rxBuffer, sizeof(txBuffer), SPI_TIMEOUT);
        HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_10);
        if (rxBuffer[0] == 0x01){
            HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_15); // 触发LED1
        }
    }
}

SPI初始化函数(CubeIDE自动生成)

static void MX_SPI1_Init(void)
{
    hspi1.Instance = SPI1;
    hspi1.Init.Mode = SPI_MODE_SLAVE;
    hspi1.Init.Direction = SPI_DIRECTION_2LINES;
    hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
    hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;  // SPI Mode 0
    hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; // SPI Mode 0 
    hspi1.Init.NSS = SPI_NSS_HARD_INPUT;
    hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
    hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
    hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
    hspi1.Init.CRCPolynomial = 10;
    if (HAL_SPI_Init(&hspi1) != HAL_OK)
    {
        Error_Handler();
    }
}

异常现象

  • 从机端HAL_SPI_TransmitReceive能检测到SPI信号(GPIOE_PIN_10 LED在超时前切换)
  • 双向数据异常:
    1. 主机端接收到的60字节数据全为0xFF
    2. 从机端未接收到主机发送的0x01,GPIOE_PIN_15 LED未触发

求助

请帮忙排查程序或操作中的问题,谢谢!


内容的提问来源于stack exchange,提问作者Diego Rodrigo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 01:17:55