Arduino双板SPI通信故障:从机SPI_STC_vect中断未触发
问题排查与修复方案
针对你的SPI从机中断未触发、无法接收数据的问题,以下是逐步排查和修复的要点:
1. 修正主机代码的SPI操作顺序
主机当前先拉低SS再初始化SPI事务,会导致从机提前激活但主机尚未配置好通信参数(速率、模式等),引发通信不匹配。调整顺序为先初始化SPI事务,再拉低SS激活从机:
void loop() { uint8_t outByte = 0xA5; Serial.print("Master kirim: 0b"); Serial.println(outByte, BIN); // 先初始化SPI参数 SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0)); digitalWrite(SS_PIN, LOW); // 激活从机 SPI.transfer(outByte); digitalWrite(SS_PIN, HIGH); // 释放从机 SPI.endTransaction(); delay(500); }
同时可删除主机中pinMode(MOSI_PIN, OUTPUT)等引脚模式设置,因为SPI.begin()会自动配置SPI相关引脚的模式,手动设置可能引发冲突。
2. 调整从机SS引脚配置
从机当前使用INPUT_PULLUP,上拉电阻会导致主机拉低SS时,引脚电平无法达到足够低的触发阈值(尤其是主机引脚驱动能力较弱时),导致从机未正确激活。将SS引脚改为普通输入:
pinMode(SS_PIN, INPUT); // 替换原有的INPUT_PULLUP
3. 确认硬件连接的正确性
务必检查以下连接(尤其是共地和引脚对应关系):
- 主机MOSI(11) ↔ 从机MOSI(11)
- 主机MISO(12) ↔ 从机MISO(12)
- 主机SCK(13) ↔ 从机SCK(13)
- 主机SS(10) ↔ 从机SS(10)
- 两块Arduino必须共地:使用杜邦线连接两块板子的GND引脚,否则电平参考不一致,完全无法通信。
4. 从机SPI初始化的优化
直接操作SPCR寄存器没问题,但结合SPI库初始化更稳妥,避免寄存器配置冲突:
void setup() { Serial.begin(9600); delay(10); pinMode(MOSI_PIN, INPUT); pinMode(MISO_PIN, OUTPUT); pinMode(SCK_PIN, INPUT); pinMode(SS_PIN, INPUT); SPI.begin(); // 初始化SPI从机模式 SPCR |= _BV(SPIE); // 启用SPI传输完成中断 }
5. 验证从机运行状态
可在从机loop中添加心跳输出,确认从机串口工作正常,排除串口本身故障:
void loop() { static uint32_t lastCount = 0; static uint32_t lastHeartbeat = 0; // 心跳输出,确认从机运行正常 if (millis() - lastHeartbeat > 1000) { Serial.println("Slave running..."); lastHeartbeat = millis(); } if (recvCount != lastCount) { Serial.print(">>> ISR terjadi #"); Serial.print(recvCount); Serial.print(", data diterima = 0b"); Serial.println(lastReceived, BIN); lastCount = recvCount; } }
按上述步骤调整后,从机应该能正常触发SPI_STC中断并接收数据。
内容的提问来源于stack exchange,提问作者Althey they
相关产品推荐
相关产品推荐

