如何在所有银行中定义一个寄存器?

时间:2016-09-16 00:15:24

标签: assembly interrupt pic

如何使用PIC16F887或类似工具在汇编中跨所有存储区定义寄存器?

应该在不更改STATUS位的情况下访问该文件。

我想在输入中断例程之前将W寄存器保存到临时文件(W_TEMP)。

从Microchip文档:

  

必须在所有存储区中定义用户寄存器W_TEMP,并且必须在与存储区基址相同的偏移处定义(即,W_TEMP在Bank0中定义为0x70 - 0x7F)

1 个答案:

答案 0 :(得分:3)

当发生中断时,我们需要保存WSTATUS,但STATUS已经在RAM中,并且没有指令将寄存器从RAM位置移动到另一个位置,所以必须先将其复制到W然后再复制到最终目的地 这意味着我们必须在此完全顺序中保存WSTATUS

  1. 保存W
  2. STATUS移至W
  3. 保存W(= STATUS
  4. 我们无法在将STATUS移至W之前修改STATUS,否则我们将无法恢复其现在可能丢失的原始值;由于我们在保存W后移动W ,我们无法对其进行修改以选择要保存W的特定银行。

    当发生中断时,可以选择任何银行,因此我们必须能够将 #define W_TEMP 0x40 保存到任何银行。 如果我们使用

    W_TEMP

    这意味着我们的程序必须将地址0x40,0x80 + 0x40,0x100 + 0x100,0x180 + 0x40全部认为保留,因为这些位置可能被中断突然覆盖。

    这就是

    的含义
      

    用户寄存器W_TEMP必须在所有库中定义,并且必须与银行基址相同的偏移量定义

    这是一个,也许不是很清楚,警告STATUS存在于所有银行(如果没有保存则根本没有银行)。 要“定义”寄存器,意味着为它设置偏移量,数字。

    在保存RP<1:0>时,我们必须小心,我们无法将其保存在任何银行中,因为ISR会对其进行修改,我们将丢失原来的STATUS位,告诉银行STATUS已被保存 所以我们需要选择一个银行并使用它,通常它是0,因为有些芯片只有RAM 由于设置银行需要修改STATUS,这似乎是一个无法解决的问题 幸运的是,我们需要将W移至W进行保存,因此一旦进入BCF,我们就可以使用STATUS指令设置当前银行而不更改原始{ {1}}(现在在W)。

    示例代码

    #define W_TEMP 0x70
    #define STATUS_TEMP 0x71
    
    MOVWF W_TEMP          ;Save W
    SWAPF STATUS, W
    BCF STATUS, RP0       ;Set bank0
    MOVWF STATUS_TEMP     ;Save STATUS
    

    注意:由于SWAPF更改了STATUS标记,因此必须使用WMOVF保存到Z中,并且在恢复期间不能使用。

    在ISR恢复状态后,必须以相反的顺序执行上述操作

    SWAPF STATUS_TEMP, W
    MOVWF STATUS              ;Restore STATUS (and bank)
    
    ;There is no load W from memory without affecting flags
    
    SWAPF W_TEMP, F           ;We swap W_TEMP in place (no flags affected)
    SWAPF W_TEMP, W           ;Then swap W_TEMP in W (this restoring W)
    

    有些器件,如PIC16F887,在所有存储体中共享一部分RAM 这部分是每个库的最后16个字节,偏移量为0x70-0x7f 在这种情况下,如果定义W_TEMPSTATUS_TEMP,我们无需在上下文保存期间切换银行:

    #define W_TEMP 0x70
    #define STATUS_TEMP 0x71
    
    MOVWF W_TEMP
    SWAPF STATUS, W 
    MOVWF STATUS_TEMP 
    

    这解释了

      

    (即W_TEMP在Bank0中定义为0x70 - 0x7F)

    引用的一部分。

    有关处理中断的更多信息,请in this Microchip document about it 请注意,有些评论充其量是神秘的,在最坏的情况下会产生误导。