本帖最后由 Clin 于 2025-7-16 16:50 编辑
在STM32F103上进行裸机开发,使用硬件SPI与一个CPLD芯片通信时,遇到了一个奇怪的问题: SPI的写入操作在各种环境下都正常,但读取操作在外部中断服务函数(EXTI ISR)内部调用时出现异常,而在主循环(main)或定时器中断(TIM ISR)中调用则完全正常。 写入操作(所有场景): 成功将数据写入CPLD的指定地址。硬件SPI和软件SPI都正常。 读取操作(主循环或定时器中断): 使用硬件SPI能成功从CPLD的指定地址读取回正确的数据值。 读取操作(外部中断中): 使用 相同的硬件SPI代码 在EXTI ISR内部读取CPLD数据时,返回的值 不是预期的数据,而是之前写入的地址值(地址addr) 。例如,在EXTI ISR中调用 data = SPI_ReadCPLD(0xA5) 后,data 的值是 0xA5 而不是CPLD实际返回的数据。 软件SPI(所有场景): 如果在外部中断服务函数中使用软件模拟的SPI(即通过GPIO手动控制时钟和数据线)进行读写操作,则 读取和写入都完全正常 ,能正确写入地址并读回数据。
后面通过在外部中断里设置标志位,把所有的读写操作全都移到主函数里处理了,没发现问题。 但是还是想知道为什么? /***************************************** 新添补充 **********************************************/
1. 主函数里硬件SPI写CPLD指令,CPLD触发一个高电平输入到MCU的外部中断 2. 外部中断里硬件SPI写CPLD、读CPLD,写正常,读异常 3. 示波器测得波形如下,读回来数据片选被自动拉高了(在其他情况正常)
图1
硬件SPI写CPLD的最后有一个等待总线空闲延时,再拉高片选,但是图1却没拉高,直接进入外部中断里进行下一指令操作。 初步怀疑是主函数里写CPLD还在等待总线空闲,片选还没拉高就触发外部中断,执行外部中断3里写指令、读指令,然后不知道什么原因导致读回来数据(图2最后16bit)的片选被自动拉高了。 后面在读函数里一进入就先关闭SPI的使能,延迟2us再打开使能,测试正常。 不知道能不能这样子操作,感觉有点问题,不知道为什么片选会拉高。
|