【场景】
在非中断代码中有IO相关操作,在中断代码中也有相关的IO操作(即便不是同一个IO)。且两个IO配置高低电平均在同一个地址寄存器下。
【现象】
中断中的IO操作,偶尔会出现退出中断就无效的情况,抓波形仅仅抓到一个脉冲。
【分析】
由于常用的方式为异或或者与非的操作,来修改寄存器中某位bit的值,这样在汇编的角度而言,本质上主要是三个流程:
- 读取外设寄存器的值
- 修改该参数(用的通用寄存器)
- 将修改后的值写入的外设寄存器
如果中断发生在1-3步骤中间,那么会导致中断中修改了IO寄存器无效。
因为从中断退出之后,执行第3步骤之前,即将写入外设寄存器的值,还是基于进入中断前的IO状态来写入的,因此会导致中断中对IO的操作无效。(中断进入之前会保存通用寄存器的值)
【解决方案】
- 有位域操作的芯片
类似stm32的芯片,芯片实现的时候就考虑到了这种情况,也即使用位域操作的方式。 - 没有位域操作的芯片,想到如下三种解决方法
- 在(非中断)执行IO相关操作,先将对应的中断关闭。执行完成之后再打开。
- 将IO操作放在线程中执行,中断中建立相关的变量标志。
- 若外设寄存器可以使用8bit访问,则可以考虑将IO放在不通的字节中,然后独立访问。(这种方式比较独特,需要考虑的情况较多,一般常用上述两种方式。)