2009-05-05 11 views
2

に切り替え...これはUSARTで「Q」を置くために働く:銀行は、私はPICのアセンブラでバンク切り替えによって混乱していますPICアセンブラ

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 

私が見ていないときにコンパイラがバンク切り替えをしていないことを確認しました。いつバンクを切り替える必要がありますか?

答えて

3

最初にどの画像機器を使用しているのかは、わずかな違いがあります。 また、どのコンパイラを使用していますか。

しかし、あなたのコードがうまくいく理由は、あなたがUARTに送ってもらう必要があるすべてが銀行0にあるからです。ポートbへの書き込みは何もしていません。私はあなたがトリスbを切り替えたいと思っています。 1であるが、UARTはポートBへの書き込みを制御しているので、自己効力はない。あなたの2番目の例では、TXSTAだと思っているもののポーリングしていますが、バンク1ではなくバンク0にあります。間違った場所をポーリングすることによって運が良ければ、ビットは常に正しい状態になり、ループが終了します。

私が送信するとき、私は最初にuartが空であるかどうかを確認し、それがあるまで待ってからcharを送信することを好みます。あなたが次のチャーを得るためにインターハンドを使いたいのでなければ、それが送信を終了するのを待つ必要はありません。

movwf TXREGを実行しているときに両方ともバンク0になっているので、両方のコードが動作します。残りはハードウェアで処理されます。

編集: TXSTAが銀行1に入っているという点で私はあなたが正しいと分かっています。あなたはアドレスのコメントが0x18であり、0x98でなければならないので私を通っています。最初の例では、TXSTAではないOERRであるRCSTAビット1をポーリングしています。だからもしこれが働いているなら、これはOERR = 1が非常に可能であることを暗示します。

+0

コンパイラ:MPASM;チップ:16F876A。 TXSTAはマニュアルに従ってバンク1にあります。私はこれを正しい答えとしてマークしています。 – c0m4

7

銀行取引を自動的に切り替えるには、BANKSELを使用することをお勧めします。アセンブラが正しいバンクに切り替えるように指示する特別なアセンブラ指示文です。したがって、PORTBにアクセスする場合は、BANKSEL(PORTB)を使用する前にアクセスしてください。

PS:PORTBはPIC16ファミリのBANK0にあり、コードのようにBANK1ではありません。

+0

BANKSELのヒントをありがとう。また、BANK1は自分のコードでTXSTAにのみ使用されます。 PORTBはあなたが言うようにBANK0です。 – c0m4

+0

最後の2行を見てください。 PORTBではなくTRISBをクリアする前にBANK1に切り替わります。 – sybreon

+0

私は訂正しました!私は少し質問を修正して言い換えました。この回答はまったく有効です。 – c0m4

5

私はあまりにも理解しにくい銀行の選択を見つけました。

I2C機能のために、PIC12F1822を使用してプロジェクトを開始しています。背景を調べることは、スレッドの束を解きほぐすのと同じように、明らかになるまでにはそれぞれ多くの苦労が必要です。私が引き出したスレッドの1つは、 "BANKSEL"指示の説明です。

背景。デバイスの動作を支援する数十種類のSFR(特殊機能レジスタ)が、より低いデータメモリにマップされています。非常に多くの銀行が32の銀行に編成されているので、それぞれ32のSFRの0から31まで番号が付けられています。 SFRは番号(ビット)bbbbbfffffffの順に番号が付けられます。ここで、bbbbbは銀行番号で、fffffffは銀行のオフセットです。それらの値はPICの.INCファイルで定義されており、シーケンスには多くのギャップがあります。バンク0〜30のSFRオフセットでは5ビットで十分であるが、バンク31では7ビットが必要であることに留意されたい。

これらのSFRの1つにアクセスする場合、そのバンク番号は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  
+0

ニース探偵仕事。私はこれが大好き! – c0m4

関連する問題