2009-05-05 64 views
2

我通過銀行開關在PIC彙編感到困惑切換...這適用於把一個「Q」的USART:銀行在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

首先關閉哪個圖片設備,因爲這確實會略有不同。 你還使用哪種編譯器。

然而,你的代碼工作的原因是因爲你需要做的一切,以tx到uart是在銀行0。你寫入端口b沒有做什麼,我猜你想切換trisb,並在銀行1但由於uart控制了寫入端口B的引腳,所以它自己沒有任何影響。在你的第二個例子中,你在輪詢你認爲是TXSTA,但是在銀行0而不是銀行1中。我猜測你通過輪詢錯誤的位置而得到幸運,並且該位總是處於正確的狀態,因此循環終止。

當我進行傳輸時,我更願意先看看uart是否爲空,然後等待它,然後發送字符。除非你想用Interupt來獲取下一個字符,否則不需要等待它完成傳輸。

所以這兩個代碼段工作,因爲你在兩個當你做movwf TXREG時在銀行0。其餘部分由硬件處理。

編輯: 現在我知道你是正確的那部分TXSTA是在銀行1。你通過我,因爲你有一個地址評論爲0x18,它應該是0x98。在第一個例子中,您輪詢RCSTA位1,它是OERR而不是TXSTA。所以如果它正在工作,這意味着OERR = 1,這是非常可能的,當我對接收進行任何操作時,我通常會清除它。

7

最好只使用班克斯銀行自動切換銀行。這是一個特殊的彙編程序指令,告訴彙編程序切換到正確的庫。所以,如果你想在使用PORTB之前訪問PORTB,只需使用BANKSEL(PORTB)。

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

+0

感謝您對BANKSEL的建議。而且BANK1僅用於我的代碼中的TXSTA。正如你所說,PORTB是BANK0。 – c0m4 2009-05-05 12:28:51

+0

看最後2行。它在清除TRISB而不是PORTB之前切換到BANK1。 – sybreon 2009-05-05 12:31:04

+0

我站好了!我已經修正並稍微修改了這個問題。這個答案雖然有效,但... – c0m4 2009-05-05 13:53:15

5

我也發現銀行選擇很難理解。

我正在啓動一個使用PIC12F1822的項目來實現I2C功能。研究背景更像是解開一連串的線索,每個人在清楚之前都需要大量的努力。我設法解決的一個線索是對「BANKSEL」指令的解釋。

背景。有幾十個特殊功能寄存器 - 特殊功能寄存器 - 有助於器件的操作,映射到較低的數據存儲器中。因爲有這麼多它們被組織成32個銀行,編號0到31,每個32個SFR。 SFR按照形式(位)順序編號(位)bbbbbfffffff其中bbbbb是銀行編號和fffffff是銀行的抵消額。它們的值在PIC的.INC文件中定義,並且序列中有很多空白。請注意,對於存儲區0至30中的SFR偏移,只需5位就足夠了,但對於存儲區31,需要7位。

訪問其中一個SFR時,其Bank編號必須位於由「MOVLB」彙編程序指令設置的BSR寄存器中。爲了簡化操作,可以在每次訪問SFR之前使用指令「BANKSEL」。 (在其他PIC中,狀態寄存器中的位包含存儲區號)成功測試後,可以刪除多餘的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