STM32F427 SPI中断从机与MCP2210通信故障求助
SPI通信故障排查(STM32F427从机 + MCP2210主机)
问题现象
- STM32作为SPI从机,
HAL_SPI_RxCpltCallback中断回调能触发(LED闪烁),但无法识别主机发送的0x33数据(对应LED未触发) - MCP2210主机接收不到STM32的响应数据
- 双方配置均为SPI模式0、9字节长度、1MHz波特率
从机代码问题分析与修复
1. 初始化顺序错误
原代码初始化顺序颠倒,SPI外设初始化依赖系统时钟,错误顺序会导致时钟配置异常:
// 错误顺序 MX_GPIO_Init(); MX_SPI1_Init(); HAL_Init(); SystemClock_Config();
修复后顺序:
int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_SPI1_Init(); // 初始化发送数据 spi_tx_data[0] = 0x34; spi_tx_data[1] = 0x34; spi_tx_data[2] = 0x34; spi_tx_data[3] = 0x34; spi_tx_data[4] = 0x09; spi_tx_data[5] = 0x05; spi_tx_data[6] = 0x05; spi_tx_data[7] = 0x00; spi_tx_data[8] = 0x02; // 仅启动一次接收中断,避免重复覆盖中断请求 HAL_SPI_Receive_IT(&hspi1, spi_rx_data, 9); while (1) { // 主循环无需重复启动中断 } }
2. 回调函数发送逻辑错误
原回调使用阻塞式HAL_SPI_Transmit,从机发送依赖主机时钟,阻塞方式无法保证时序同步。应利用SPI全双工特性,同步收发:
void HAL_SPI_RxCpltCallback (SPI_HandleTypeDef *hspi) { HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_15); // 检查接收数据 if (spi_rx_data[0] == 0x33){ HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_10); } // 启动下一次全双工中断,同步收发数据 HAL_SPI_TransmitReceive_IT(hspi, spi_tx_data, spi_rx_data, 9); }
3. 软件NSS配置缺失
STM32配置为软件NSS模式,但未启用内部上拉或手动控制电平,导致从机无法正确进入接收状态。在MX_SPI1_Init的USER CODE BEGIN SPI1_Init 2中添加:
__HAL_SPI_ENABLE_NSSPULLUP(&hspi1);
主机代码问题分析与修复
1. MCP2210命令格式错误
MCP2210的0x42 SPI传输命令有固定格式:[报告ID(0x00), 命令(0x42), 字节数低8位, 字节数高8位, CS配置, 数据...],原代码字节数配置错误:
// 修正后命令配置(9字节数据) data[0] = 0x00; // HID报告ID data[1] = 0x42; // SPI传输命令 data[2] = 0x09; // 传输字节数低8位(9字节) data[3] = 0x00; // 传输字节数高8位 data[4] = 0x01; // CS引脚配置(根据实际硬件调整,0x01对应GP0) data[5] = 0x33; // 第一个数据字节 for (int r = 6; r < 6+8; r++) { data[r] = 0xAA; // 后续8个数据字节 }
2. 收发逻辑冗余
原代码循环读取的逻辑无依据,简化后直接收发即可:
if (x == 1) { // 发送完整SPI命令包(总长度14字节:1+1+2+1+9) res = hid_write(dev, data, 14); std::this_thread::sleep_for(std::chrono::milliseconds(1)); // 读取MCP2210响应(固定64字节) res = hid_read(dev, rdata, 64); // 打印从机返回的9字节数据(响应第5字节开始为有效数据) std::cout << "Slave response: "; for (int i = 5; i < 5+9; i++) { std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)rdata[i] << " "; } std::cout << std::endl; }
额外排查建议
- 用示波器测量SPI的CLK、MOSI、MISO、CS引脚波形,确认时序符合SPI模式0要求
- 检查硬件连接:STM32的MOSI(PA7)、MISO(PA6)、CLK(PA5)需正确连接到MCP2210对应引脚
- 确认MCP2210的CS引脚配置为主动拉低模式
内容的提问来源于stack exchange,提问作者Diego Rodrigo
相关产品推荐
相关产品推荐

