PICアセンブラーでのバンク切り替え
-
05-07-2019 - |
質問
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デバイスを使用しているのかは、わずかな違いがあるためです。 また、どのコンパイラを使用しています。
ただし、コードが機能する理由は、tartに送信するために必要なことはすべてバンク0にあるためです。ポートbへの書き込みは何も実行していないため、trisbを切り替えたいと思います。しかし、artはポートBに書き込むピンを制御しているため、効果はありません。 2番目の例では、TXSTAと思われるものをポーリングしていますが、それはバンク1ではなくバンク0にあります。間違った場所をポーリングすると幸運になり、ビットは常に正しい状態になり、ループが終了します。
送信を行うとき、最初にuartが空であるかどうかを確認し、空になるまで待ってから文字を送信します。たとえば次の文字を取得するために割り込みを使用する場合を除き、送信が完了するのを待つ必要はありません。
したがって、movwf TXREGを実行するときに両方のバンク0にいるため、両方のコードが機能します。残りはハードウェアで処理されます。
編集: TXSTAがバンク1にあるという点で、あなたが正しい部分がわかったので、アドレスのコメントが0x18であり、0x98である必要があるので、あなたを通して私を通して。最初の例では、TXSTAではなくOERRであるRCSTAビット1をポーリングしています。したがって、それが機能している場合、これは非常に可能性のあるOERR = 1を意味し、受信で何かをするときに通常クリアします。
他のヒント
銀行の切り替えを自動的に行うには、BANKSELを使用するのが最善です。これは、正しいバンクに切り替えるようにアセンブラーに指示する特別なアセンブラーディレクティブです。したがって、PORTBにアクセスする場合は、使用する前にBANKSEL(PORTB)だけを使用してください。
PS:PORTBは、コードのBANK1ではなく、PIC16ファミリのBANK0にあります。
銀行の選択も非常に理解しにくいと感じました。
I2C機能のために、PIC12F1822を使用してプロジェクトを開始しています。背景を研究することは、糸のかせをほどくようなものであり、それぞれが明らかになる前に多くの苦労が必要です。私が何とか引き出したスレッドの1つは、「BANKSEL」の説明です。ディレクティブ。
背景。下位データメモリにマップされたデバイスの動作を支援する数十個のSFR(特殊機能レジスタ)があります。多数あるため、それぞれ32 SFRの0〜31の番号が付けられた32のバンクに編成されています。 SFRには、形式(ビット) bbbbbfffffff で順番に番号が付けられます。 bbbbb は銀行番号、 fffffff は銀行のオフセットです。それらの値はPICの.INCファイルで定義されており、シーケンスには多くのギャップがあります。バンク0〜30のSFRオフセットには5ビットだけで十分ですが、バンク31には7ビットが必要です。
これらのSFRの1つにアクセスするとき、そのバンク番号はBSRレジスタに存在する必要があります。BSRレジスタは" MOVLB"によって設定されます。アセンブラー命令。これを簡単にするために、指令" BANKSEL"があります。これは、SFRの各アクセスの前に使用できます。 (他のPICでは、STATUSレジスタのビットにバンク番号が保持されます)テストが成功した後、余分なBANKSELを削除できます。私のパズル(これまでのところこれを確立した後-ドキュメントの情報はまばらで散在しています)は、このディレクティブがどのように機能するかでした。もちろん、コードが生成される前にアセンブラによって評価されます。これは、EQUを使用して計算を行い、説明するためのテストコードです(locnは「場所」、つまり、指示。):
;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