Domanda

Mi sto confondendo cambiando banco nell'assemblatore PIC ... Funziona per inserire una 'Q' sull'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 questo funziona altrettanto bene:

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

Ho verificato che il compilatore non esegua alcun cambio di banco quando non sto guardando ... Quando DEVO cambiare banco?

È stato utile?

Soluzione

Prima di tutto quale dispositivo foto stai usando perché questo fa una leggera differenza. Inoltre quale compilatore stai utilizzando.

Comunque il motivo per cui il tuo codice funziona è perché tutto ciò che devi fare per tx su uart è nella banca 0. Le tue scritture sulla porta b non stanno facendo nulla. Immagino che tu voglia cambiare il trisb e che sia nella banca 1 ma poiché uart ha il controllo dei pin che scrivono sulla porta B, il sé stesso non ha alcun effetto. Nel tuo secondo esempio stai eseguendo il polling di quello che pensi sia TXSTA ma quello è nella banca 0 non nella banca 1. Immagino che tu sia fortunato sondando la posizione sbagliata e il bit sia sempre nello stato corretto, quindi il ciclo termina.

Quando eseguo una trasmissione, preferisco prima vedere se l'Uart è vuoto e attendere fino a quando non lo è, quindi inviare il carattere. Non è necessario attendere che finisca la trasmissione, a meno che non si desideri utilizzare un interrupt, ad esempio, per ottenere il carattere successivo.

Quindi entrambi i pezzi di codice funzionano perché ci si trova nel banco 0 in entrambi quando si sposta TXREG. Il resto è gestito in hardware per te.

Modifica: Ora che conosco la parte in cui hai ragione, TXSTA è nella banca 1. Tu attraverso di me perché hai avuto un commento dell'indirizzo come 0x18 e dovrebbe essere 0x98. Nel primo esempio si sta eseguendo il polling del bit 1 RCSTA che è OERR e non TXSTA. Quindi, se funziona, ciò implica che OERR = 1, che è molto possibile, di solito lo deseleziono quando faccio qualcosa con la ricezione.

Altri suggerimenti

È meglio usare BANKSEL per effettuare automaticamente il cambio di banca. È una direttiva assembler speciale che dice all'assemblatore di passare al banco corretto. Quindi, se desideri accedere a PORTB, basta BANKSEL (PORTB) prima di usarlo.

PS: PORTB è in BANK0 sulla famiglia PIC16, non in BANK1 come nel tuo codice.

Anch'io ho trovato la selezione della banca molto difficile da capire.

Sto iniziando un progetto usando PIC12F1822s, per la loro funzionalità I2C. La ricerca sullo sfondo è piuttosto come districare una matassa di fili, ognuno ha bisogno di molte lotte prima che diventi chiaro. Uno dei thread che sono riuscito a estrarre è una spiegazione del "BANKSEL" direttiva.

Sfondo. Esistono diverse dozzine di SFR - Registri di funzioni speciali - che aiutano il funzionamento del dispositivo, mappati nella memoria dati inferiore. Perché ce ne sono così tanti che sono organizzati in 32 banche, numerate da 0 a 31, di 32 SFR ciascuna. Gli SFR sono numerati in sequenza nella forma (bit) bbbbbfffffff dove bbbbb è il numero di banco e fffffff è l'offset nella banca. I loro valori sono definiti nel file .INC per il PIC e ci sono molti vuoti nella sequenza. Si noti che per gli offset SFR nei banchi da 0 a 30 sono sufficienti solo cinque bit, ma per il banco 31 sono necessari sette bit.

Quando si accede a uno di questi SFR, il suo numero di banca deve essere nel registro BSR, che è impostato dal "MOVLB". istruzioni assembler. Per facilitare ciò, esiste una direttiva "BANKSEL" che può essere utilizzato prima di ogni accesso di un SFR. (In altri PIC, i bit nel registro STATUS contengono il numero di banco) Dopo aver superato i test, è possibile rimuovere tutti i BANKSEL superflui. Il mio enigma (dopo averlo stabilito finora - le informazioni nella documentazione sono scarse e sparse) è stato come funziona questa direttiva. Ovviamente viene valutato dall'assemblatore prima che venga prodotto qualsiasi codice, e questo è il mio codice di prova per verificarlo, usando EQU per fare i calcoli e spiegarlo (nota che locn è "Posizione", ovvero l'indirizzo del istruzione.):

        ;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       
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top