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

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

有帮助吗?

解决方案

首先关闭哪个pic设备,因为这确实会产生细微差别。 您还在使用哪种编译器。

然而,你的代码工作的原因是因为你需要对tx执行ux的所有操作都在bank 0.你对端口b的写操作什么都没做我猜你想要切换trisb而那是在bank 1中但由于uart控制了写入端口B的引脚,因此它本身没有任何效果。在你的第二个例子中,你正在轮询你认为TXSTA,但是在银行0而不是银行1.我猜你通过轮询错误的位置而得到幸运,并且该位总是处于正确状态,因此循环终止。

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

因此,当您执行movRf TXREG时,两个代码都有效,因为您在两个代码中都处于存储区0中。其余部分由硬件处理。

编辑: 现在我知道你正确的部分是TXSTA在银行1.你通过我,因为你有一个地址的评论为0x18,它应该是0x98。在第一个示例中,您轮询RCSTA位1,即OERR而不是TXSTA。因此,如果它正在工作,这意味着OERR = 1这是非常可能的,当我对接收做任何事情时,我通常会清除它。

其他提示

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

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

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

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

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

当访问这些SFR中的一个时,其Bank号必须在BSR寄存器中,该寄存器由“MOVLB”设置。汇编指令。为了方便起见,有一个指令“BANKSEL”。可以在每次访问SFR之前使用。 (在其他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       
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top