Pergunta

Estou ficando confuso com a mudança de banco no PIC montador ... Isso funciona para colocar um 'Q' na 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

e isso funciona tão bom:

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

Eu verifiquei que o compilador não faz qualquer mudança de banco, quando eu não estou vendo ... Quando tem que banco switch?

Foi útil?

Solução

Primeiro qual dispositivo pic que você está usando, porque isso faz uma pequena diferença. Também qual compilador você está usando.

No entanto, a razão que seu código funciona é porque tudo o que você precisa fazer para tx ao uart é no banco 0. Suas gravações para a porta b estão fazendo nada que eu estou supondo que você quer mudar o TRISB e que está no banco 1 mas desde que o uart tem o controle dos pinos gravar na porta B auto-tem nenhum efeito. Em seu segundo exemplo você é polling o que você pensa é TXSTA mas que é no banco 0 não bancária 1. Eu estou supondo que você tem sorte por polling local errado e o bit é sempre no estado correto para que os termina de loop.

Quando eu faço uma transmissão I preferem primeiro ver se o uart está vazia e esperar até que ele é e, em seguida, enviar o caractere. Não há necessidade de esperar por ele para transmissão de chegada a menos que você quiser usar um interupt por exemplo, para obter o próximo caractere.

Assim, os dois pedaços de código de trabalho porque você está no banco 0, tanto quando você faz movwf TXREG. O resto é tratado em hardware para você.

Edit: Agora que eu sei a parte que você está correto em que TXSTA é no banco 1. Você através de mim porque você teve um comentário do endereço como 0x18 e deve ser 0x98. No primeiro exemplo você é polling RCSTA bit 1 que é o OERR não TXSTA. Então, se ele está funcionando isso implica que OERR = 1 que é muito possível que eu geralmente limpá-la quando eu faço qualquer coisa com o receber.

Outras dicas

É melhor usar apenas BANKSEL para fazer o seu banco alternando automaticamente. É um montador especial directiva, diz ao assembler para mudar para o banco correto. Então, se você deseja acessar PORTB, apenas BANKSEL (PORTB) antes de usá-lo.

PS:. PORTB está em BANK0 sobre a família PIC16, não BANK1 como em seu código

Eu selecção banco também achei muito difícil de entender.

Eu estou começando um projeto usando PIC12F1822s, por sua funcionalidade I2C. Pesquisando o fundo é um pouco como desembaraçar um novelo de fios, cada um precisa de muita luta antes de se trata clara. Um dos tópicos que conseguiram retirar é uma explicação da directiva "BANKSEL".

Fundo. Há várias dezenas de SFRs - Registra função especiais - que auxiliam no funcionamento do dispositivo, mapeado na memória de dados mais baixa. Porque há tantos que estão organizados em 32 bancos, numeradas de 0 a 31, de 32 SFRs cada. Os SFRs são numerados sequencialmente nos formulários (bits) bbbbbfffffff onde bbbbb é o número do banco e fffffff é o deslocamento no banco. Os seus valores são definidos no ficheiro .INC para o PIC, e existem muitas lacunas na sequência. Note-se que para os deslocamentos SFR em bancos 0 a 30 apenas cinco bits são suficientes, mas para o banco 31 sete bits são necessários.

Ao acessar um desses SFRs seu número bancária deve ser no registo BSR, que é definido pelo "MOVLB" instrução assembler. Para tornar isso fácil lá é uma directiva "BANKSEL" que pode ser usado antes de cada acesso de um SFR. (Em outros PICs, bits no registo de STATUS segurar o número do banco) Após o teste de sucesso, nenhum BANKSELs supérfluos pode ser removido. Meu quebra-cabeça (depois de estabelecer isso até agora - as informações contidas na documentação é escassa e dispersa) foi como funciona este directiva. É, naturalmente, avaliada pelo montador antes de qualquer código é produzido, e este é meu código de teste para verificá-la, usando EQU fazer os cálculos, e explicá-lo (nota locn é "Localização" ou seja, o endereço da instrução .):

        ;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       
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top