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传输命令格式
| 字节索引 | 含义 |
|---|---|
| 0 | 0x42(SPI数据传输命令码) |
| 1 | 本次传输的字节数(0-60) |
| 2 | 保留(0x00) |
| 3 | 保留(0x00) |
| 4-63 | 待发送的SPI数据 |
MCP2210预期响应格式
| 字节索引 | 含义 |
|---|---|
| 0 | 0x42(回显命令码) |
| 1 | 0x00(命令执行成功,SPI数据已接收) |
| 2 | 返回的SPI接收数据字节数 |
| 3 | 0x10(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在超时前切换) - 双向数据异常:
- 主机端接收到的60字节数据全为0xFF
- 从机端未接收到主机发送的0x01,GPIOE_PIN_15 LED未触发
求助
请帮忙排查程序或操作中的问题,谢谢!
内容的提问来源于stack exchange,提问作者Diego Rodrigo
相关产品推荐
相关产品推荐

