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)
我已经检查过编译器在我不看的时候没有进行任何银行切换......什么时候需要切换银行?
最好只使用BANKSEL自动进行银行转换.它是一个特殊的汇编程序指令,告诉汇编程序切换到正确的存储区.因此,如果您希望在使用之前访问PORTB,只需使用BANKSEL(PORTB).
PS:PORTB位于PIC16系列的BANK0中,而不是代码中的BANK1.
我也发现银行选择很难理解.
我正在使用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)