首页 > 解决方案 > 了解用于禁用和恢复 SREG 中断状态的 AVR 代码

问题描述

我对如何禁用和恢复我为 8 位 AVR 处理器找到的中断状态的示例感到有些困惑。

像 ATmega 2560 这样的 8 位 AVR 处理器在状态寄存器 (SREG) 中有一个全局中断启用位(标记为“I”)。该CLI指令通过清除该位来禁用所有中断。来自 AVR 指令集手册:

CLI - 清除全局中断使能位

描述

清除 SREG(状态寄存器)中的全局中断允许 (I) 位。中断将立即被禁用。指令后不会执行中断CLI,即使它与指令同时发生CLI。(相当于指令 BCLR 7。)

AVR 指令集手册还显示了以下示例:

1   in temp, SREG      ; Store SREG value (temp must be defined by user)
2   cli                ; Disable interrupts during timed sequence
3   sbi EECR, EEMWE    ; Start EEPROM write
4   sbi EECR, EEWE
5   out SREG, temp     ; Restore SREG value (I-flag)

第 5 行的意图似乎是将 SREG 的 I-flag 恢复到它在第 2 行执行之前的值。事实上,这段代码存储了所有 SREG 标志的状态——它似乎只是假设 SREG 的其他标志的值不会在第 1 行和第 5 行之间改变。但是,如果在第 1 行和第 2 行之间发生中断,则不能它会导致一些 SREG 的其他标志被“恢复”不正确吗?

1   in temp, SREG      ; Store SREG value (temp must be defined by user)
    ; <------- interrupt occurs here
2   cli                ; Disable interrupts during timed sequence
3   sbi EECR, EEMWE    ; Start EEPROM write
4   sbi EECR, EEWE
5   out SREG, temp     ; Restore SREG value (I-flag)

标签: interruptavratomic

解决方案


  • 当中断发生时,CPU 将切换到中断服务程序,但在切换之前 CPU 会记住程序的位置(通过将程序计数器压入堆栈)
  • CPU 将执行 ISR
  • 执行 ISR 后像中断之前一样恢复 CPU 环境(SERG、GPR、SP、PC)非常重要和关键,这将由您的代码完成(如果您在中断后没有恢复 CPU 环境,您的程序将很有可能崩溃)
  • CPU 将返回相同的位置(通过从堆栈中恢复 PC)
1   in temp, SREG      ; Store SREG value (temp must be defined by user)
    ; <------- interrupt occurs here
    ; <-------------go to interupt  handler
    ; <--------Rutern from interupt with same value of temp, SREG, and all GPR are same value 

2   cli                ; Disable interrupts during timed sequence
3   sbi EECR, EEMWE    ; Start EEPROM write
4   sbi EECR, EEWE
5   out SREG, temp     ; Restore SREG value (I-flag)

上面的代码只是告诉你“确保第 3,4 行将在没有中断的情况下依次执行”

如果在第 1 行和第 2 行之间发生中断,是否会导致 SREG 的某些其他标志“恢复”不正确?

如果第 1 行和第 2 行之间发生中断,则中断将在第 2 行之前处理并返回,并且任何中断代码必须保留 CPU 环境


推荐阅读