昨天做一个项目,在中断中调用配置IO口的输出接口修改IO口输出状态,输出波形偶尔出现预期不符的情况。
用示波器检查通过检查IO口波形,发现中断中将IO口电平更改后,但10us后电平又会变回去。检查程序逻辑测试都没有发现问题,包括用另一个IO口跟这个IO同步变化,屏蔽所有其他地方更改这个IO口状态的函数都没发现问题。问芯片厂反馈是不清楚。于是陷入死局。
使用程序屏蔽大法测试,发现屏蔽一段模拟IIC的程序就不会出现这个问题。但这个地方操作的IO口和中断里操作的并不是同一个IO口,进一步检查这个地方的代码,发现这里是操作整个输出寄存器(PxOUT寄存器,对应ST的ODR寄存器),函数为PxOUT |= 1 <<pin。
这个函数执行的时候,应该是有三个步骤,首先读出PxOUT寄存器的值,然后将值某一位改为1,然后再赋值回PxOUT寄存器。
因此,我怀疑是不是因为这个地方操作IO口时,程序执行读PxOUT值时进入中断,中断退出后这里程序继续执行,于是就将IO口状态改回去了。
于是将这里的函数修改为使用置位和清空寄存器来操作IO口,中断里继续使用直接操作PxOUT寄存器方式,测试后问题解决。
以前学习ST时,一直不明白操作IO口的置位清空寄存器的使用场景,经过这次调试后,终于明白这个寄存器的价值了。