如何在PIC 汇编器中切换存储区?

问题描述 投票:2回答:3

我对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

而且效果很好:

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

[我已经检查了编译器,当我不观看时不进行任何库切换...何时需要切换库?

assembly switch-statement pic bank
3个回答
3
投票

首先使用的是哪种图片设备,因为那确实有所不同。以及您使用的是哪个编译器。

但是您的代码起作用的原因是,您需要执行的所有操作以将tart传送到uart都在bank 0中。您对端口b的写操作无济于事,我想您要切换trisb且位于bank 1中,但是由于uart可以控制写入端口B的引脚,因此它本身无效。在第二个示例中,您正在轮询您认为是TXSTA的东西,但它位于存储区0中而不是存储区1中。我猜测通过轮询错误的位置您会很幸运,并且该位始终处于正确的状态,因此循环终止。

[我进行传输时,我更喜欢先查看uart是否为空,等到它为空后再发送char。除非您想使用例如Interupt来获取下一个字符,否则无需等待它完成传输。

所以这两段代码都可以工作,因为当您执行movwf TXREG时,您都处于bank 0。其余的都由硬件处理。

编辑:现在,我知道TXSTA在银行1中的部分是正确的。通过我,是因为您对地址的注释为0x18,它应该为0x98。在第一个示例中,您将轮询RCSTA位1,即OERR而不是TXSTA。因此,如果工作正常,则意味着OERR = 1,这很可能在我对接收执行任何操作时将其清除。


7
投票

最好只使用BANKSEL来自动进行银行切换。这是一个特殊的汇编程序指令,它告诉汇编程序切换到正确的库。因此,如果您想访问PORTB,请在使用前访问BANKSEL(PORTB)。

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


5
投票

我也发现银行选择非常难以理解。

我正在使用PIC12F1822来启动项目,因为它们具有I2C功能。研究背景就像弄乱了一个线程,每个人都需要很多努力才能弄清楚。我设法引出的线程之一是“ BANKSEL”指令的说明。

背景。有几十个SFR(特殊功能寄存器),它们映射到较低的数据存储器中,用于帮助器件的操作。因为数量太多,它们被组织成32个Bank,编号为0到31,每个32个SFR。 SFR以(位)bbbbbfffffff的形式顺序编号,其中bbbbb是存储体编号,fffffff是存储体中的偏移量。它们的值在PIC的.INC文件中定义,并且序列中有很多空白。请注意,对于存储体0到30中的SFR偏移,仅5位就足够了,但是对于存储体31则需要7位。

访问这些SFR之一时,其组号必须位于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       
© www.soinside.com 2019 - 2024. All rights reserved.