Вопрос

Меня смущает переключение банков в ассемблере PIC...Это работает для установки «Q» на usart:

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

Я проверил, что компилятор не выполняет переключение банков, когда я не смотрю...Когда НУЖНО менять банк?

Это было полезно?

Решение

Прежде всего, какое графическое устройство вы используете, потому что это имеет небольшое значение.И какой компилятор вы используете.

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

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

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

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

Другие советы

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

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

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

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

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

При доступе к одному из этих SFR его номер банка должен находиться в регистре 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       
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top