Sommario:

PARTE 2 - MONTAGGIO DEL BRACCIO GPIO - RGB - CHIAMATE DI FUNZIONE - Interruttori: 6 Step
PARTE 2 - MONTAGGIO DEL BRACCIO GPIO - RGB - CHIAMATE DI FUNZIONE - Interruttori: 6 Step

Video: PARTE 2 - MONTAGGIO DEL BRACCIO GPIO - RGB - CHIAMATE DI FUNZIONE - Interruttori: 6 Step

Video: PARTE 2 - MONTAGGIO DEL BRACCIO GPIO - RGB - CHIAMATE DI FUNZIONE - Interruttori: 6 Step
Video: Che fortuna 2024, Dicembre
Anonim
PARTE 2 - MONTAGGIO DEL BRACCIO GPIO - RGB - CHIAMATE DI FUNZIONE - Interruttori
PARTE 2 - MONTAGGIO DEL BRACCIO GPIO - RGB - CHIAMATE DI FUNZIONE - Interruttori

Nella Parte 1, abbiamo imparato come attivare un singolo LED rosso sulla scheda di sviluppo MSP432 LaunchPad di Texas Instruments, utilizzando l'assembly invece del C/C++.

In questo Instructable, faremo qualcosa di simile: controlleremo un LED RGB che si trova anche sulla stessa scheda.

Lungo la strada, speriamo di approfondire la nostra conoscenza dell'assemblaggio ARM e non solo divertirci ad accendere alcuni LED.

Passaggio 1: saltiamo dentro

Davvero, il primo video dice tutto. Non c'è molto altro da aggiungere.

Il punto principale è portare a casa l'idea che ogni porta I/O sull'MSP432 sia costituita da un blocco di indirizzi di "registro", che a loro volta consistono di diversi bit ciascuno.

Inoltre, i bit sono raggruppati in modo ortogonale. Cioè, il bit 0 di ogni indirizzo di registro fa riferimento allo stesso pin I/O esterno.

Abbiamo ripetuto l'idea che occorrono diversi indirizzi di registro per quella porta, per fare qualcosa anche con un solo bit o pin.

Ma che in questo caso, trattandosi di un LED RGB, dobbiamo occuparci di tre bit per ogni indirizzo di registro.

Abbiamo ribadito che abbiamo bisogno di diversi registri: il registro DIR, il registro SEL0, il registro SEL1 e il registro OUTPUT. E tre bit ogni volta.

Passaggio 2: migliora il codice: aggiungi una funzione

Image
Image

Come hai visto nel passaggio precedente, il ciclo principale del programma aveva un sacco di codice ripetuto, vale a dire, quando spegniamo i LED.

Quindi possiamo aggiungere una funzione al programma. Dobbiamo ancora chiamare quella funzione ogni volta che vogliamo spegnere i LED, ma causa il collasso di parte del codice in una singola istruzione.

Se il nostro codice LED-off fosse stato più coinvolto con molte più istruzioni, questo sarebbe stato un vero risparmio di memoria.

Parte della programmazione embedded e dei microcontrollori è essere molto più consapevoli delle dimensioni del programma.

Il video spiega.

In sostanza, aggiungiamo un'istruzione di ramificazione al nostro codice principale e abbiamo un altro blocco di codice che è la funzione a cui eseguiamo il salto. E poi, una volta terminato, o alla fine della funzione, torniamo all'istruzione successiva all'interno del programma principale.

Passaggio 3: aggiungere un ritardo di ciclo occupato

Nella sezione Dichiarazioni del codice, aggiungi una costante per semplificare il tweek per la tempistica desiderata:

; qualsiasi parola dopo un punto e virgola (';') avvia un commento.

; il codice in questa parte assegna un nome ad un valore.; avresti anche potuto usare '.equ' ma sono leggermente diversi.; '.equ' (credo) non può essere modificato, mentre '.set' significa che puoi; modificare il valore di 'DLYCNT' successivamente nel codice, se lo si desidera.;'DLYCNT' verrà utilizzato come valore di conto alla rovescia nella subroutine di ritardo. DLYCNT.set 0x30000

Aggiungi una nuova funzione di ritardo:

ritardo:.asmfunc; l'inizio della subroutine o funzione 'ritardo'.

MOV R5, #DLYCNT; caricare il registro R5 della CPU core con il valore assegnato a 'DLYCNT'. dlyloop; questo segna l'inizio del ciclo di ritardo. l'assemblatore determina l'indirizzo. SUB R5, #0x1; sottrarre un 1 dal valore corrente nel registro R5 della CPU principale. CMP R5, #0x0; confronta il valore corrente in R5 con 0. BGT dlyloop; branch se il valore in R5 è maggiore di 0, a label(address) 'dlyloop'. BXLR; se siamo arrivati a questo punto, significa che il valore di R5 era 0. ritorno dalla subroutine..endasfunc; segna la fine del sottoprogramma.

Quindi nel corpo principale, all'interno del ciclo principale, invoca o chiama quella funzione di ritardo:

; questo è un frammento di codice, del corpo principale o della funzione principale (vedi file 'main.asm').

; questo è un ciclo in 'main' e mostra come chiamiamo o usiamo quella nuova funzione 'delay'.; anche '#REDON' e '#GRNON' sono dichiarazioni (costanti) (vedi all'inizio di 'main.asm').; sono solo un modo semplice per impostare il colore specificato del LED RGB. loop MOV R0, #REDON;Red - imposta il registro core della CPU R0 con il valore assegnato a 'REDON'. STRB R0, [R4];il registro principale R4 era precedentemente impostato con un indirizzo di uscita GPIO.;scrivi cosa c'è in R0, nell'indirizzo specificato da R4. BL delay;diramazione alla nuova funzione 'delay'. BL ledsoff;ramo alla funzione 'ledsoff' preesistente. BL delay;idem MOV R0, #GRNON;Green - idem STRB R0, [R4]; e così via. Ritardo BL Led BL spenti Ritardo BL

Il video entra nel dettaglio.

Passaggio 4: standard di chiamata di procedura dell'architettura ARM (AAPCS)

Probabilmente è un buon momento per introdurre qualcosa. È una convenzione sul linguaggio assembly. Conosciuto anche come Procedure Call Standard per l'architettura ARM.

C'è molto in questo, ma è solo uno standard. Non ci impedisce di imparare la programmazione assembly e possiamo adottare pezzi di quello standard mentre procediamo, una volta che ci sentiamo a nostro agio con alcuni concetti che stiamo imparando.

Altrimenti, potremmo sentirci come se stessimo bevendo da un enorme tubo dell'acqua. Troppe informazioni.

Registri principali

Poiché abbiamo acquisito familiarità con i registri principali dell'MSP432, proviamo ora ad adottare alcuni di questi standard. Ci atterremo a questo quando scriveremo la funzione successiva (accendere/spegnere un LED).

1) Dovremmo usare R0 come parametro di funzione. Se desideriamo passare un valore nella funzione (subroutine), dovremmo usare R0 per farlo.

2) Dobbiamo usare il Link Register per lo scopo previsto: contiene l'indirizzo che indica dove tornare dopo che la subroutine è stata completata.

Vedrai come li applichiamo.

Passaggio 5: funzione con parametro - Funzioni nidificate

Possiamo ripulire il nostro codice e ridurre la quantità di memoria che occupa combinando sezioni ripetute in un'unica funzione. L'unica differenza nel corpo del ciclo principale è che abbiamo bisogno di un parametro in modo da poter passare i vari colori diversi che vogliamo vedere del LED RGB.

Dai un'occhiata al video per i dettagli. (scusate per la lunghezza)

Passaggio 6: ingresso GPIO - Aggiungi interruttori

Rendiamolo più interessante. È ora di aggiungere un po' di controllo degli interruttori al nostro programma di assemblaggio.

Questo Instructable ha immagini che mostrano come i due switch di bordo sono collegati all'MSP432.

In sostanza: l'interruttore 1 (SW1 o S1) è collegato a P1.1 e l'interruttore 2 (SW2 o S2) è collegato a P1.4.

Questo rende le cose un po' interessanti non solo perché abbiamo a che fare con ingressi invece che con uscite, ma anche perché questi due interruttori occupano o occupano due bit dello stesso blocco di indirizzi di registro come fa il singolo LED rosso che è un'uscita.

Ci siamo occupati di attivare/disattivare il singolo LED rosso in questo Instructable, quindi abbiamo solo bisogno di aggiungere il codice per gestire gli interruttori.

Blocco indirizzo registro porta 1

Ricorda che li abbiamo trattati nel precedente Instructable, ma dobbiamo includerne uno nuovo:

  • Indirizzo del registro di ingresso porta 1 = 0x40004C00
  • Indirizzo registro uscita porta 1 = 0x40004C02
  • Indirizzo del registro di direzione della porta 1 = 0x40004C04
  • Abilita resistore porta 1 Indirizzo registro = 0x40004C06
  • Porta 1 Selezionare 0 Indirizzo registro = 0x40004C0A
  • Porta 1 Seleziona 1 Indirizzo registro = 0x40004C0C

Quando si utilizzano le porte come ingressi, è consigliabile utilizzare i resistori pull-up o pull-down interni dell'MSP432.

Poiché la scheda di sviluppo del Launchpad ha collegato i due interruttori a massa (LOW quando premuti), ciò significa che dovremmo usare resistori di pull UP per assicurarci di avere un ALTO solido quando non vengono premuti.

Resistenze pull up/pull down

Sono necessari due diversi indirizzi di registro della porta 1 per collegare gli ingressi degli interruttori ai resistori di pull-up.

1) Utilizzare il registro di abilitazione resistore della porta 1 (0x40004C06) per indicare solo che si desidera resistori (per quei due bit), 2) e quindi utilizzare il registro di uscita della porta 1 (0x40004C02) per impostare i resistori come pull-up o pull-down. Potrebbe sembrare confuso che stiamo utilizzando un registro di uscita sugli ingressi. Il registro Output ha quasi un duplice scopo.

Quindi, per riformulare in un altro modo, il registro di uscita può inviare un ALTO o un BASSO a un'uscita (come il singolo LED rosso) e / o è usato per impostare resistori di pull-up o pull-down per gli ingressi, MA SOLO se quella funzione è stata abilitata tramite il registro Resistor-Enable.

Importante in quanto sopra: quando si invia/imposta un BASSO o ALTO a qualsiasi bit di uscita, è necessario mantenere contemporaneamente lo stato di pull-up/pull-down dei bit di input.

(il video cerca di spiegare)

Lettura di un bit di ingresso della porta

  • Imposta SEL0 / SEL1 per la funzionalità GPIO
  • Imposta il registro DIR come ingresso per i bit di commutazione, ma come uscita per il LED (contemporaneamente nello stesso byte)
  • Abilita resistori
  • Impostali come resistori di pull-up
  • Leggi il porto
  • Potresti voler filtrare il valore letto per isolare solo i bit di cui hai bisogno (switch 1 e 2)

Consigliato: