2009-05-05 10 views
2

PIC 어셈블러에 전환 ... 이것은 USART에 'Q'를 넣어 작동 :은행은 내가 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에 대한 당신의 기록은 아무 것도하지 않습니다. 나는 당신이 트리스 시브를 바꾸고 싶다고 추측합니다. 그것은 뱅크에 있습니다. 1이지만 UART는 포트 B에 쓰는 핀을 제어하므로 자체적으로 아무런 효과가 없습니다. 귀하의 두 번째 예제에서는 TXSTA라고 생각하는 것을 폴링합니다.하지만 뱅크 0은 뱅크 1이 아닙니다. 잘못된 위치를 폴링하여 행운을 얻고 비트가 항상 올바른 상태가되어 루프가 종료되도록 추측하고 있습니다.

전송을 할 때 나는 먼저 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

마지막 두 줄을보십시오. PORTB 대신 TRISB를 지우기 전에 BANK1로 전환됩니다. – sybreon

+0

나는 고쳐졌다! 나는 약간의 문제를 수정하고 다시 말 하였다. 이 대답은 마찬가지로 유효하지만 ... – c0m4

5

은행 선택도 매우 이해하기 어려웠습니다.

I2C 기능을 위해 PIC12F1822를 사용하여 프로젝트를 시작합니다. 배경을 연구하는 것은 쓰레드를 묶어 버리는 것과 비슷합니다. 분명히하기 전에 많은 사람들이 고군분투해야합니다. 내가 풀어 낼 수있는 스레드 중 하나는 "BANKSEL"지시어에 대한 설명입니다.

배경. 특수 기능 레지스터 - 하위 데이터 메모리에 매핑되는 장치 작동을 지원하는 수십 개의 SFR이 있습니다. 32 개의 은행으로 조직되어있는 숫자가 너무 많기 때문에 각각 32 개의 SFR로 0에서 31까지 번호가 매겨집니다. SFR은 번호 (비트) bbbbbfffffff의 순으로 번호가 지정됩니다. 여기서 bbbbb은 은행 번호이고 fffffff은 은행의 오프셋입니다. 이들의 값은 PIC의 .INC 파일에 정의되어 있으며 시퀀스에는 많은 간격이 있습니다. 0 내지 30 뱅크의 SFR 오프셋에 대해서는 5 비트만으로 충분하지만, 31 뱅크에 대해서는 7 비트가 필요하다는 것을 유의해야한다.

이러한 SFR 중 하나에 액세스 할 때 뱅크 번호는 "MOVLB"어셈블러 명령어에 의해 설정된 BSR 레지스터에 있어야합니다. 이를 쉽게하기 위해 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