STM8S105同时开启SPI_TXE与RXNE中断触发复位故障排查
STM8S SPI同时开启TXE/RXNE中断触发复位的解决方法
STM8S完全支持同时开启SPI的TXE和RXNE中断,你遇到的复位问题大概率是中断服务函数(ISR)未正确实现、初始化流程错误或未处理SPI错误中断导致的,以下是具体排查和解决步骤:
1. 必须正确实现SPI中断服务函数
TXE和RXNE中断会共享同一个SPI中断向量,若ISR未定义或未正确处理标志位,设备会因非法中断跳转触发复位。请确保ISR函数名与你的STM8S型号匹配(多数型号为SPI_IRQHandler),并在函数内处理所有可能触发的中断标志:
void SPI_IRQHandler(void) { // 处理RXNE中断(接收完成) if (SPI_GetITStatus(SPI_IT_RXNE) != RESET) { uint8_t recv_data = SPI_ReceiveData(); // 读取数据自动清除RXNE标志 // 在这里添加你的接收数据处理逻辑 } // 处理TXE中断(发送缓冲区空) if (SPI_GetITStatus(SPI_IT_TXE) != RESET) { SPI_SendData(your_tx_data); // 写入数据自动清除TXE标志 // 在这里添加发送数据的准备逻辑(比如更新下一个要发送的字节) } // 关键:必须处理SPI错误中断,否则错误会触发复位 if (SPI_GetITStatus(SPI_IT_OVR) != RESET) { uint8_t dummy = SPI_ReceiveData(); // 读取DR寄存器清除OVR标志 SPI_ClearITPendingBit(SPI_IT_OVR); } if (SPI_GetITStatus(SPI_IT_MODF) != RESET) { SPI_ClearITPendingBit(SPI_IT_MODF); } }
2. 严格遵循SPI初始化顺序
错误的初始化顺序会导致硬件状态异常,触发复位,请按以下顺序执行:
// 1. 初始化SPI参数(根据你的主/从模式配置) SPI_Init(SPI1, SPI_FirstBit_MSB, SPI_BaudRatePrescaler_16, SPI_Mode_Master, SPI_CPOL_Low, SPI_CPHA_1Edge, SPI_Direction_2Lines_FullDuplex, SPI_NSS_Soft, 0x07); // 2. 开启SPI外设 SPI_Cmd(SPI1, ENABLE); // 3. 开启全局中断 enableInterrupts(); // 4. 最后开启SPI的TXE和RXNE中断 SPI_ITConfig(SPI1, SPI_IT_TXE, ENABLE); SPI_ITConfig(SPI1, SPI_IT_RXNE, ENABLE);
3. 排查硬件与寄存器配置
- 确认SPI引脚(SCK/MOSI/MISO/NSS)连接正确,无短路、虚焊;
- 核对参考手册版本与你的STM8S型号一致,确保
SPI_ICR寄存器的TXEIE(位7)和RXNEIE(位6)位定义正确(0xC0确实是同时开启两位的正确值); - 检查是否误开启了其他未处理的中断,或SPI模式(主/从)、NSS配置与硬件不匹配。
4. 定位复位原因(替代OpenOCD的调试方法)
若无法使用OpenOCD,可通过读取复位状态寄存器RST_SR判断复位类型,快速定位问题:
uint8_t reset_reason = RST_GetResetSource(); // 检查复位类型 if (reset_reason & RST_FLAG_ILLOP) { // 非法操作复位:大概率是中断向量未定义或ISR执行错误 } else if (reset_reason & RST_FLAG_WWDGF) { // 看门狗复位:检查看门狗是否误开启 } else if (reset_reason & RST_FLAG_SWIF) { // 软件复位:检查代码中是否有主动复位操作 }
内容的提问来源于stack exchange,提问作者samcns
相关产品推荐
相关产品推荐

