Cuprins:

PARTEA 2 - ASAMBLARE ARM GPIO - RGB - APELURI FUNCȚIONALE - Comutatoare: 6 pași
PARTEA 2 - ASAMBLARE ARM GPIO - RGB - APELURI FUNCȚIONALE - Comutatoare: 6 pași

Video: PARTEA 2 - ASAMBLARE ARM GPIO - RGB - APELURI FUNCȚIONALE - Comutatoare: 6 pași

Video: PARTEA 2 - ASAMBLARE ARM GPIO - RGB - APELURI FUNCȚIONALE - Comutatoare: 6 pași
Video: Part 2 ARM Assembly MSP432 TI RSLK Write GPIO LED Lab 6 2024, Noiembrie
Anonim
PARTEA 2 - ASAMBLARE ARMĂ GPIO - RGB - APELURI FUNCȚIONALE - Comutatoare
PARTEA 2 - ASAMBLARE ARMĂ GPIO - RGB - APELURI FUNCȚIONALE - Comutatoare

În partea 1, am învățat cum să comutăm un singur LED roșu pe placa de dezvoltare MSP432 LaunchPad de la Texas Instruments, folosind ansamblul în loc de C / C ++.

În acest Instructable, vom face ceva similar - vom controla un LED RGB care se află și pe aceeași placă.

Pe parcurs, sperăm să ne îmbunătățim cunoștințele despre asamblarea ARM și să nu ne distrăm doar aprinzând câteva LED-uri.

Pasul 1: Să sărim direct

Într-adevăr, primul videoclip spune totul. Nu mai sunt multe de adăugat.

Principalul punct al acestuia este de a conduce acasă ideea că fiecare port I / O de pe MSP432 constă dintr-un bloc de adrese „registru”, care la rândul lor constau din mai mulți biți fiecare.

Mai mult, biții sunt grupați într-un mod ortogonal. Adică bitul 0 din fiecare adresă de registru se referă la același pin I / O extern.

Am repetat ideea că este nevoie de mai multe adrese de registru pentru acel port, pentru a face ceva chiar și cu un singur bit sau pin.

Dar, în acest caz, deoarece avem de-a face cu un LED RGB, trebuie să avem de-a face cu trei biți pentru fiecare adresă de registru.

Am întărit faptul că avem nevoie de mai multe registre: registrul DIR, registrul SEL0, registrul SEL1 și registrul OUTPUT. Și câte trei biți de fiecare dată.

Pasul 2: Îmbunătățiți codul - Adăugați o funcție

Image
Image

După cum ați văzut în Pasul de mai sus, bucla principală a programului avea o mulțime de coduri repetate, și anume, când oprim LED-urile.

Deci, putem adăuga o funcție programului. Încă trebuie să apelăm această funcție de fiecare dată când dorim să oprim LED-urile, dar aceasta face ca o parte din cod să se prăbușească într-o singură declarație.

Dacă codul nostru LED-off ar fi fost mai implicat în multe alte instrucțiuni, acesta ar fi fost un adevărat economisitor de memorie.

O parte din programarea și microcontrolerele încorporate este mult mai conștientă de dimensiunea programului.

Videoclipul explică.

În esență, adăugăm o instrucțiune de ramificare la codul nostru principal și avem un alt bloc de cod care este funcția la care ne ramificăm. Și apoi, odată ce am terminat sau la sfârșitul funcției, ne întoarcem la următoarea instrucțiune din programul principal.

Pasul 3: Adăugați o întârziere de buclă ocupată

În secțiunea Declarații a codului, adăugați o constantă pentru a ușura tweek-ul pentru momentul dorit:

; orice cuvinte după punct și virgulă (';') începe un comentariu.

; codul din această parte atribuie un nume unei valori.; ai fi putut folosi și „.equ”, dar sunt ușor diferite.; „.equ” (cred) nu poate fi schimbat, în timp ce „.set” înseamnă că poți; modificați valoarea „DLYCNT” mai târziu în cod, dacă doriți.; „DLYCNT” va fi folosit ca valoare de numărătoare inversă în subrutina de întârziere. DLYCNT.set 0x30000

Adăugați o nouă funcție de întârziere:

întârziere:.asmfunc; începutul subrutinei sau funcției „întârziere”.

MOV R5, #DLYCNT; încărcați registrul central al procesorului R5 cu valoarea atribuită „DLYCNT”. dlyloop; aceasta marchează începutul buclei de întârziere. asamblorul determină adresa. SUB R5, # 0x1; scade un 1 din valoarea curentă în registrul central de procesare R5. CMP R5, # 0x0; comparați valoarea curentă în R5 la 0. BGT dlyloop; ramificați dacă valoarea în R5 este mai mare 0, pentru a eticheta (adresa) „dlyloop”. BX LR; dacă ajungem aici, înseamnă că valoarea R5 a fost 0. întoarcere din subrutină..endasmfunc; marchează sfârșitul subrutinei.

Apoi, în corpul principal, în cadrul buclei principale, invocați sau apelați acea funcție de întârziere:

; acesta este un fragment de cod, al corpului principal sau al funcției principale (vezi fișierul „main.asm”).

; aceasta este o buclă în „principal” și arată cum apelăm sau folosim acea nouă funcție „întârziere”.; „#REDON” și „#GRNON” sunt, de asemenea, declarații (constante) (vezi partea de sus a „main.asm”).; sunt doar o modalitate ușoară de a seta culoarea specificată a LED-ului RGB. buclă MOV R0, #REDON; Roșu - setează registrul central de bază R0 cu valoarea atribuită „REDON”. STRB R0, [R4]; registrul de bază R4 a fost setat anterior cu o adresă de ieșire GPIO.; scrieți ce este în R0, în adresa specificată de R4. Întârziere BL; ramificație către noua funcție „întârziere”. BL ledsoff; ramificație către funcția preexistentă „ledsoff”. BL delay; idem MOV R0, #GRNON; Verde - idem STRB R0, [R4]; si asa mai departe. BL delay BL ledsoff BL delay

Videoclipul intră în detaliu.

Pasul 4: Standard de apel pentru procedura de arhitectură ARM (AAPCS)

Este probabil un moment bun pentru a introduce ceva. Este o convenție de limbaj de asamblare. Cunoscut și sub denumirea de procedura de apel standard pentru arhitectura ARM.

Există multe la acest lucru, dar este doar un standard. Nu ne împiedică să învățăm programarea ansamblului și putem adopta piese din acel standard pe măsură ce mergem, odată ce ne simțim confortabili cu unele concepte pe care le învățăm.

În caz contrar, am putea simți că bem dintr-un furtun uriaș de apă. Prea multa informatie.

Registrele de bază

Deoarece ne-am familiarizat cu registrele de bază ale MSP432, să încercăm să adoptăm acum câteva dintre aceste standarde. Ne vom conforma acestui lucru atunci când scriem următoarea funcție (porniți / dezactivați un LED).

1) Ar trebui să folosim R0 ca parametru funcțional. Dacă dorim să trecem o valoare în funcție (subrutină), ar trebui să folosim R0 pentru a face acest lucru.

2) Trebuie să folosim Registrul de legături pentru scopul propus - deține adresa care indică unde să ne întoarcem după finalizarea subrutinei.

Veți vedea cum le aplicăm.

Pasul 5: Funcția cu parametru - Funcții imbricate

Ne putem curăța codul și putem reduce cantitatea de memorie pe care o ocupă combinând secțiuni repetate într-o singură funcție. Singura diferență în corpul buclei principale este că avem nevoie de un parametru, astfel încât să putem trece diferitele culori diferite pe care vrem să le vedem de LED-ul RGB.

Aruncați o privire la videoclip pentru detalii. (scuze pentru lungime)

Pasul 6: Intrare GPIO - Adăugați comutatoare

Să-l facem mai interesant. Este timpul să adăugăm o comandă de comutare la programul nostru de asamblare.

Acest instructabil conține imagini care arată modul în care cele două comutatoare de la bord sunt conectate la MSP432.

În esență: comutatorul 1 (SW1 sau S1) este conectat la P1.1, iar comutatorul 2 (SW2 sau S2) este conectat la P1.4.

Acest lucru face lucrurile puțin interesante nu numai pentru că avem de-a face cu intrări în loc de ieșiri, ci și pentru că aceste două comutatoare ocupă sau ocupă doi biți din același bloc de adrese de registru, la fel ca și singurul LED roșu care este o ieșire.

Ne-am ocupat de comutarea singurului LED roșu în acest instructabil, așa că trebuie doar să adăugăm cod pentru a gestiona comutatoarele.

Port 1 Înregistrează blocul de adrese

Amintiți-vă că le-am tratat în instructabilul anterior, dar trebuie să includem unul nou:

  • Port 1 Adresa registru de intrare = 0x40004C00
  • Adresa registrului de ieșire port 1 = 0x40004C02
  • Adresa registrului de direcție port 1 = 0x40004C04
  • Port 1 Resistor Enable Register address = 0x40004C06
  • Port 1 Selectați 0 Adresă înregistrare = 0x40004C0A
  • Port 1 Selectați 1 Adresă de înregistrare = 0x40004C0C

Când utilizați porturile ca intrări, este bine să utilizați rezistențele interne de tragere sau de tragere ale MSP432.

Deoarece placa de dezvoltare Launchpad a conectat cele două comutatoare la masă (LOW când este apăsat), asta înseamnă că ar trebui să folosim rezistențe pull UP pentru a ne asigura că avem un HIGH înalt atunci când nu sunt apăsate.

Rezistențe de tragere în sus / de coborâre

Este nevoie de două adrese diferite de Port 1 Register pentru a lega aceste intrări de comutare la rezistențele de tragere.

1) Utilizați registrul Port 1 Resistor-Enable (0x40004C06) pentru a indica doar că doriți rezistențe (pentru acei doi biți), 2) și apoi utilizați registrul de ieșire Port 1 (0x40004C02) pentru a seta rezistențele fie ca pull-up, fie pull-down. Ar putea părea confuz că folosim un registru de ieșire la intrări. Registrul de ieșire are aproape un dublu scop.

Deci, pentru a reloca un alt mod, registrul de ieșire poate trimite fie un HIGH sau LOW către o ieșire (cum ar fi un singur LED roșu) și / sau este utilizat pentru a seta rezistențe pull-up sau pull-down pentru intrări, DAR NUMAI dacă acea caracteristică a fost activată prin registrul Resistor-Enable.

Important în cele de mai sus - atunci când trimiteți / setați un LOW sau HIGH pe orice bit de ieșire, va trebui să mențineți simultan starea de pull-up / pull-down a biților de intrare.

(videoclipul încearcă să explice)

Citirea unui bit de intrare port

  • Setați SEL0 / SEL1 pentru funcționalitatea GPIO
  • Setați registrul DIR ca intrare pentru biții de comutare, dar ca ieșire pentru LED (simultan în același octet)
  • Activați rezistențele
  • Setați-le ca rezistențe pull-up
  • Citiți portul
  • Poate doriți să filtrați valoarea citită pentru a izola doar biții de care aveți nevoie (comutatorul 1 și 2)

Recomandat: