2009-05-05 6 views
2

Я путаюсь банковским переключением в PIC ассемблере ... Это работает для сдачи «Q» на USART:Bank переключение в 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

Сначала вы используете устройство pic, потому что это делает небольшую разницу. Также, какой компилятор вы используете.

Однако причина, по которой ваш код работает, заключается в том, что все, что вам нужно сделать для tx в uart, находится в банке 0. Ваши записи в порт b ничего не делают, я предполагаю, что вы хотите переключить trisb и что находится в банке 1, но поскольку uart имеет контроль над штырями, записывающими в порт B, он сам не имеет эффекта. В вашем втором примере вы опросили то, что считаете TXSTA, но это в банке 0, а не в банке 1. Я предполагаю, что вам повезло, опросив неправильное место, и бит всегда находится в правильном состоянии, поэтому цикл завершается.

Когда я делаю передачу, я предпочитаю сначала увидеть, пуст ли uart и ждать, пока он есть, и затем отправьте символ. Не нужно ждать, пока он закончит передачу, если вы не хотите использовать interupt, например, чтобы получить следующий символ.

Итак, обе части кода работают, потому что вы находитесь в банке 0 в обоих случаях, когда вы делаете movwf TXREG. Остальное обрабатывается в аппаратном обеспечении для вас.

Редактировать: Теперь, когда я знаю часть, вы правы в том, что TXSTA находится в банке 1. Вы прошли через меня, потому что у вас был комментарий адреса как 0x18, и он должен быть 0x98. В первом примере вы опросили RCSTA бит 1, который является OERR, а не TXSTA. Поэтому, если он работает, это означает, что OERR = 1, что очень возможно, я обычно очищаю его, когда я что-то делаю с приемом.

+0

Компилятор: MPASM; Чип: 16F876A. TXSTA находится в банке 1 согласно руководству. Я считаю это правильным ответом. – c0m4

7

Лучше всего использовать BANKSEL для автоматического переключения вашего банка. Это специальная ассемблерная директива, которая указывает ассемблеру переключиться на правильный банк. Поэтому, если вы хотите получить доступ к PORTB, просто BANKSEL (PORTB), прежде чем использовать его.

PS: PORTB находится в BANK0 в семействе PIC16, а не BANK1, как в вашем коде.

+0

Благодарим за отзыв о BANKSEL. А также BANK1 используется только для TXSTA в моем коде. PORTB - это BANK0, как вы говорите. – c0m4

+0

Посмотрите на последние 2 строки. Он переключается на BANK1 перед очисткой TRISB вместо PORTB. – sybreon

+0

Я стою исправленный! Я исправил и перефразировал вопрос немного. Этот ответ так же важен, хотя ... – c0m4

5

Я тоже нашел банк выбор очень трудно понять.

Я запускаю проект, используя PIC12F1822s, для своих функций I2C. Изучение фона скорее похоже на распутывание мотка нитей, каждый из которых нуждается в большой борьбе, прежде чем станет ясно. Одним из потоков, которые я смог вытащить, является объяснение директивы «BANKSEL».

Фон. Существует несколько десятков SFR - специальных регистров функций, которые помогают в работе устройства, отображаются в нижней памяти данных. Поскольку их так много, они организованы в 32 банка, от 0 до 31, из 32 SFR каждый. SFR нумеруются последовательно в форме (биты) bbbbbfffffff где bbbbb - номер банка и fffffff - смещение в банке. Их значения определены в файле .INC для ПОС, и в последовательности есть много пробелов. Обратите внимание, что для смещений SFR в банках от 0 до 30 достаточно всего пяти битов, но для банка 31 необходимы семь бит.

При обращении к одному из этих SFR его номер банка должен быть в регистре BSR, который задается инструкцией ассемблера MOVLB. Для упрощения существует директива «BANKSEL», которая может использоваться перед каждым доступом SFR. (В других 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

Nice детектив работы. Мне это очень нравится! – c0m4