PIC汇编程序中的存储区切换

c0m*_*0m4 2 assembly pic switch-statement bank

我对PIC汇编程序中的银行切换感到困惑......这适用于在usart上放置'Q':

bsf PORTB,1         ;Set Transmit DIR (PORTB (0x6) not mirrored in other banks)
movlw 'Q'           ;'Q' to work reg
movwf TXREG         ;work reg to TXREG (TXREG (0x19) not mirrored in other banks)
clrwdt              ;Clear watchdog
btfss TXSTA,TRMT    ;Wait until 'Q' is shifted (TXSTA is 0x18, not mirrored)
goto $-2
bcf PORTB,1         ;Set Recive DIR
Run Code Online (Sandbox Code Playgroud)

这同样有效:

BCF 0x3, 0x5        ;Switch to bank 0
BCF 0x3, 0x6
bsf PORTB,1         ;Set Transmit DIR
movlw 'Q'           ;'Q' to work reg
movwf TXREG         ;work reg to TXREG 
BSF 0x3, 0x5        ;Switch to bank 1
clrwdt              ;Clear watchdog
btfss TXSTA,TRMT    ;Wait until 'Q' is shifted
goto $-2
BCF 0x3, 0x5        ;Switch to bank 0
bcf PORTB,1         ;Set Recive DIR
Run Code Online (Sandbox Code Playgroud)

我已经检查过编译器在我不看的时候没有进行任何银行切换......什么时候需要切换银行?

syb*_*eon 7

最好只使用BANKSEL自动进行银行转换.它是一个特殊的汇编程序指令,告诉汇编程序切换到正确的存储区.因此,如果您希望在使用之前访问PORTB,只需使用BANKSEL(PORTB).

PS:PORTB位于PIC16系列的BANK0中,而不是代码中的BANK1.


Har*_*ton 5

我也发现银行选择很难理解.

我正在使用PIC12F1822s开始一个项目,用于其I2C功能.研究背景就像解开线程的束缚,每个人在明确之前都需要进行大量的挣扎.我设法撤出的其中一个线程是对"BANKSEL"指令的解释.

背景.有几十个特殊功能寄存器-特殊功能寄存器-即协助设备的操作,映射到较低的数据存储.因为有这么多,它们被组织成32个银行,编号为0到31,每个32个SFR.SFR以(bbbbbfffffff)形式顺序编号,其中bbbbb是存储体编号,fffffff是存储体中的偏移量.它们的值在PIC的.INC文件中定义,序列中有许多间隙.注意,对于存储体0到30中的SFR偏移,仅5位就足够了,但对于存储体31,则需要7位.

当访问其中一个SFR时,其Bank号必须位于BSR寄存器中,该寄存器由"MOVLB"汇编器指令设置.为了简化这一过程,可以在每次访问SFR之前使用指令"BANKSEL".(在其他PIC中,STATUS寄存器中的位保存存储区编号)成功测试后,可以删除任何多余的BANKSEL.我的谜题(到目前为止建立这个 - 文档中的信息稀疏和分散)是这个指令的工作原理.当然,在生成任何代码之前,汇编程序会对其进行评估,这是我的测试代码,使用EQU进行计算并解释它(注意locn是"Location"即指令的地址.):

        ;BANKSEL is a directive that does the equivalent of 
        ;       movlb  (<SFRname> & 0XF0) >> 7

        ;For example TRISA is defined in P12F1822.INC as:

        ;-----Bank1------------------
        TRISA            EQU  H'008C' 

   Assembler:
   Locn   Resulting value     Line  Original code line content ";" is a comment
   ~~~~   ~~~~~~~~~~~~~~~     ~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                              00047 ; Test of equivalent of BANKSEL directive          
          0000008C            00048 selbank equ TRISA
          00000080            00049 selbnk1 equ selbank & 0XF80 ; Extract bank no. ..
          00000001            00050 selbnk2 equ selbnk1 >> 7 ; .. move it to the right
          0000000C            00051 selbnk3 equ TRISA & 0XF80 >> 7 
        [ Operator precedence: >> (bit shift right) higher than & (bitwise AND) ]
          0000000C            00052 selbnk4 equ TRISA & (0XF80 >> 7) ; default
          00000001            00053 selbnk5 equ (TRISA & 0XF80) >> 7 ; as needed`
                     . . .
   006C   0021                00100 movlb  1           ; Should be same as next line
   006D   0021                00101 banksel TRISA       
Run Code Online (Sandbox Code Playgroud)