Sisukord:

AVR Assembleri õpetus 2: 4 sammu
AVR Assembleri õpetus 2: 4 sammu

Video: AVR Assembleri õpetus 2: 4 sammu

Video: AVR Assembleri õpetus 2: 4 sammu
Video: MKS SGEN L V1.0 - A4988 Stepper Drivers 2024, November
Anonim
AVR Assembleri õpetus 2
AVR Assembleri õpetus 2

See õpetus on jätk "AVR Assembleri juhendajale 1"

Kui te pole 1. õpetust läbinud, peaksite kohe peatuma ja kõigepealt seda tegema.

Selles õpetuses jätkame Arduino's kasutatava atmega328p koostamiskeele programmeerimise uurimist.

Sa vajad:

  1. leivalaud Arduino või lihtsalt tavaline Arduino nagu juhendis 1
  2. LED
  3. 220 oomi takisti
  4. nupp
  5. ühenduskaablid vooluringi tegemiseks oma leivaplaadil
  6. Süstimiskomplekti kasutusjuhend: www.atmel.com/images/atmel-0856-avr-instruction-s…
  7. Andmeleht: www.atmel.com/images/Atmel-8271-8-bit-AVR-Microco…

Minu õpetuste täieliku kogu leiate siit:

Samm: vooluringi ehitamine

Ringraja ehitamine
Ringraja ehitamine

Kõigepealt peate konstrueerima vooluringi, mida me selles õpetuses uurime.

Siin on ühendusviis:

PB0 (digitaalne tihvt 8) - LED - R (220 oomi) - 5V

PD0 (digitaalne tihvt 0) - nupp - GND

Saate kontrollida, kas teie LED on õigesti orienteeritud, ühendades selle PB0 asemel GND -ga. Kui midagi ei juhtu, pöörake suunda ümber ja tuli peaks põlema. Seejärel ühendage see uuesti PB0 -ga ja jätkake. Pildil on näha, kuidas minu leivalaud arduino on ühendatud.

2. samm: koostamiskoodeksi kirjutamine

Koostamisseadustiku kirjutamine
Koostamisseadustiku kirjutamine

Kirjutage järgmine kood tekstifaili nimega pushbutton.asm ja kompileerige see avra abil, nagu tegite juhendis 1.

Pange tähele, et selles koodis on meil palju kommentaare. Iga kord, kui monteerija näeb semikoolonit, jätab see ülejäänud rea vahele ja läheb järgmisele reale. Hea programmeerimistava (eriti montaažikeeles!) On oma koodi tugevalt kommenteerida, et tulevikus selle juurde naastes saaksite teada, mida tegite. Ma kommenteerin asju esimestel õpetustel üsna palju, et me teaksime täpselt, mis toimub ja miks. Hiljem, kui oleme montaaži kodeerimises natuke paremad, kommenteerin asju natuke vähem üksikasjalikult.

;************************************

; kirjutas: 1o_o7; kuupäev: 23. oktoober 2014; ************************************

.nolist

.kaasa "m328Pdef.inc".list.def temp = r16; määrake tööregister r16 temp rjmp Init; esimene rida täidetud

Selles:

ser temp; seadke kõik bitid temperatuuriks 1. välja DDRB, temp; andmesuuna sisend/väljundi bitiks 1 seadistamine; registreeruge PortB -le, mis on DDRB, määrab selle; pin väljundina, 0 määraks selle tihvti sisendiks; nii et siin on kõik PortB tihvtid väljundid (seatud väärtusele 1) ldi temp, 0b11111110; laadige "kohe" number temp registrisse; kui see oleks lihtsalt ld, siis teine argument; peaks olema mälupesa asemel DDRD, temp; mv temp DDRD -le, tulemus on see, et sisend on PD0; ja ülejäänud on väljundid clr temp; kõik bitid tempis on seatud 0 -le välja PortB, temp; seadistage kõik PortB bitid (st tihvtid) väärtusele 0V ldi temp, 0b00000001; laadige kohe number, et tempD PortD, temp; teisaldage temp portD. PD0 -l on tõmbetakistus; (st seatud väärtusele 5V), kuna sellel bitil on 1; ülejäänud on 0 -st alates 0 -st.

Peamine:

temp, PinD; PinD omab PortD olekut, kopeerige see temp; kui nupp on ühendatud PD0 -ga, on see nii; 0, kui nuppu vajutatakse, 1 muul ajal; PD0 -l on tõmbetakistus, see on tavaliselt 5 V väljundis PortB, temp; saadab ülaltoodud 0 -d ja 1 -d PortB -le; see tähendab, et soovime, et LED oleks ühendatud PB0 -ga; kui PD0 on LOW, seab PB0 LOW ja pöörab; LED -il (kuna LED -i teine pool on; ühendatud 5V -ga ja see seab PB0 väärtuseks 0V, nii et vool voolab) rjmp Main; pöördub tagasi Maini algusesse

Pange tähele, et seekord on meie koodis mitte ainult palju rohkem kommentaare, vaid ka päisejaotis, mis annab teavet selle kohta, kes selle kirjutas ja millal see kirjutati. Ülejäänud kood on samuti jagatud osadeks.

Pärast ülaltoodud koodi koostamist laadige see mikrokontrollerile ja veenduge, et see töötab. LED peaks süttima, kui vajutate nuppu ja seejärel uuesti välja lülituma, kui lahti lasete. Näitasin pildil, kuidas see välja näeb.

3. samm: koodi rida-rida analüüs

Jätan need read, mis on pelgalt kommentaarid, kuna nende eesmärk on iseenesestmõistetav.

.nolist

.include "m328Pdef.inc".list

Need kolm rida sisaldavad faili, mis sisaldab meie programmeeritava ATmega328P registrit ja biti määratlusi. Käsk.nolist käsib monteerijal mitte lisada seda faili pushbutton.lst faili, mille ta selle kokkupanemisel toodab. See lülitab kirjevaliku välja. Pärast faili kaasamist lülitame kirjevaliku uuesti käsuga.list sisse. Põhjus, miks me seda teeme, on see, et fail m328Pdef.inc on üsna pikk ja me ei pea seda loendifailis nägema. Meie kokkupanija, avra, ei loo automaatselt loendifaili ja kui me seda sooviksime, kogume järgmise käsu abil:

avra -l surunupp.lst nupp.asm

Kui te seda teete, loob see faili nimega pushbutton.lst ja kui seda faili uurite, leiate, et see näitab teie programmi koodi koos lisateabega. Kui vaatate lisateavet, näete, et read algavad tähega C:, millele järgneb suhteline aadress kuueteistkümnendikus, kus kood mällu paigutatakse. Põhimõtteliselt algab see esimese käsuga kell 000000 ja suureneb sealt iga järgmise käsuga. Teine veerg pärast suhtelist kohta mälus on käsu heksakood, millele järgneb käsu argumendi heksakood. Loendifailide üle arutame tulevastes õpetustes.

.def temp = r16; määrake tööregister r16 temp

Selles reas kasutame kokkupanija direktiivi ".def", et määratleda muutuja "temp" võrdseks r16 "tööregistriga". Kasutame registrit r16, mis salvestab numbrid, mida soovime erinevatesse sadamatesse ja registritesse kopeerida (mida ei saa otse kirjutada).

Harjutus 1: proovige kopeerida kahendarv otse porti või spetsiaalsesse registrisse nagu DDRB ja vaadake, mis juhtub, kui proovite koodi kokku panna.

Register sisaldab baiti (8 bitti) teavet. Põhimõtteliselt on see tavaliselt SR-riivide kogum, millest igaüks on "natuke" ja sisaldab 1 või 0. Me võime seda (ja isegi ehitada!) Hiljem selles seerias arutada. Teil võib tekkida küsimus, mis on "töötav register" ja miks me valisime r16. Arutame seda tulevases õpetuses, kui sukeldume kiibi sisemusse. Praegu tahan, et te mõistaksite, kuidas teha selliseid asju nagu koodi kirjutamine ja füüsilise riistvara programmeerimine. Siis saate sellest kogemusest viiteraami, mis muudab mikrokontrolleri mälu ja registri omadused kergemini arusaadavaks. Mõistan, et enamik sissejuhatavaid õpikuid ja arutelusid teeb seda vastupidi, kuid olen avastanud, et enne kasutusjuhendi lugemist on enne mõnda aega videomängu mängimine globaalse perspektiivi saamiseks palju lihtsam kui käsiraamatu esmane lugemine.

rjmp Init; esimene rida täidetud

See rida on "suhteline hüpe" sildile "Init" ja pole siin tegelikult vajalik, kuna järgmine käsk on juba Initis, kuid lisame selle edaspidiseks kasutamiseks.

Selles:

ser temp; seadke kõik bitid temperatuuriks 1.

Pärast sildi Init käivitame käsu "seatud register". See seab kõik registri "temp" 8 bitti (mis teie mäletamist mööda on r16) väärtuseks 1. Nii et temp sisaldab nüüd 0b11111111.

välja DDRB, temp; seadistades andmesuuna I/O registris bitiks 1

; PortB jaoks, mis on DDRB, seab selle nööpnõela väljundiks; a 0 määraks selle tihvti sisendiks; nii et siin on kõik PortB tihvtid väljundid (seatud väärtusele 1)

Registris DDRB (portaali Port Data Direction Register) öeldakse, millised PortB tihvtid (st PB0 kuni PB7) on sisendiks määratud ja millised väljundiks. Kuna meie tihvt PB0 on ühendatud meie LED -iga ja ülejäänud pole millegagi ühendatud, seame kõik bitid 1 -le, mis tähendab, et need on kõik väljundid.

ldi temp, 0b11111110; laadige "kohe" number temp registrisse

; kui see oleks lihtsalt ld, siis teine argument oleks; peab olema mälupesa

See rida laadib binaarnumbri 0b11111110 temp -registrisse.

välja DDRD, temp; mv temp DDRD -le, tulemus on see, et PD0 on sisend ja

; ülejäänud on väljundid

Nüüd määrasime PortD jaoks andmesuuna registri tempist, kuna temp sisaldab endiselt 0b11111110, näeme, et PD0 määratakse sisendpoldiks (kuna parempoolses kohas on 0) ja ülejäänud on määratud väljunditeks, kuna 1 on nendes kohtades.

clr temp; kõik temperatuuribittid on seatud 0 -le

välja PortB, temp; seadistage kõik PortB bitid (st tihvtid) väärtusele 0V

Esiteks "tühjendame" registri temp, mis tähendab kõigi bittide nullimist. Seejärel kopeerime selle PortB registrisse, mis seab kõigile nendele tihvtidele 0V. Null PortB -bitil tähendab, et protsessor hoiab seda tihvti 0 V juures, üks bitti põhjustab selle pinge seadistamise 5 V.

Harjutus 2: kasutage multimeetrit, et kontrollida, kas kõik PortB tihvtid on tegelikult null. Kas PB1 -ga toimub midagi imelikku? On aimu, miks see nii võib olla? (sarnaselt harjutusega 4 allpool, siis järgige koodi …) Harjutus 3: eemaldage koodist ülaltoodud kaks rida. Kas programm töötab ikka õigesti? Miks?

ldi temp, 0b00000001; laadige kohe number temp

välja PortD, temp; teisaldage temp portD. PD0 on 5 V juures (omab tõmbetakistit); kuna sellel bitil on 1, siis ülejäänud on 0V. Harjutus 4: eemaldage koodist ülaltoodud kaks rida. Kas programm töötab ikka õigesti? Miks? (See erineb ülaltoodud harjutusest 3. Vaadake väljalõikamise skeemi. Mis on PD0 vaikeseade DDRD? (Vt andmelehe lk 90

Esiteks "laadime kohe" numbri 0b00000001 temp. "Vahetu" osa on olemas, kuna laadime otse üles tõstetud numbrit temperatuurile, mitte kursorit mälukohta, mis sisaldab laaditavat numbrit. Sel juhul kasutaksime lihtsalt "ld", mitte "ldi". Seejärel saadame selle numbri PortD -le, mis määrab PD0 väärtuseks 5 V ja ülejäänud väärtuseks 0 V.

Nüüd oleme määranud tihvtid sisendiks või väljundiks ning seadistanud nende esialgsed olekud kas 0V või 5V (LOW või HIGH) ja siseneme nüüd oma programmi "loop".

Peamine: temp, PinD; PinD omab PortD olekut, kopeerige see temp

; kui nupp on ühendatud PD0 -ga, siis see on see; a 0, kui nuppu vajutatakse, 1 muidu pärast seda; PD0 -l on tõmbetakistus, see on tavaliselt 5 V juures

Register PinD sisaldab PortD tihvtide praegust olekut. Näiteks kui ühendasite 5V juhtme PD3 külge, siis järgmisel kellaajal (mida juhtub 16 miljonit korda sekundis, kuna meil on mikrokontroller ühendatud 16MHz taktsignaaliga) PinD3 bit (PD3 hetkeseisust) muutuks 1 asemel 0. Seega kopeerime selles reas tihvtide hetkeseisu temp.

välja PortB, temp; saadab ülaltoodud 0 -d ja 1 -d PortB -le

; see tähendab, et me tahame, et LED oleks ühendatud PB0 -ga, nii; kui PD0 on LOW, seab see PB0 väärtuseks LOW ja pöörleb; LED -i peal (LED -i teine pool on ühendatud; 5V -ni ja see seab PB0 väärtuseks 0V, nii et vool voolab)

Nüüd saadame PinD tihvtide oleku PortB väljundisse. Tegelikult tähendab see, et PD0 saadab porti 1 D1, kui nuppu ei vajutata. Sel juhul, kui nupp on maandusega ühendatud, on tihvt 0 V pingel ja see saadab 0 PortB0 -le. Kui vaatate vooluahelat, siis 0V PB0 -l tähendab, et LED -tuli helendab, kuna selle teine pool on 5 V juures. Kui me nuppu ei vajuta, nii et 1 saadetakse PB0 -le, tähendab see, et meil on 5 V toiteallikas PB0 ja ka 5 V LED -i teisel küljel ja seega pole potentsiaalseid erinevusi ja voolu ei voola ja nii LED ei sütti (antud juhul on tegemist dioodiga ja seega voolab vool ainult ühes suunas, olenemata sellest).

rjmp Main; pöördub tagasi algusesse

See suhteline hüpe viib meid tagasi meie sildile Main: ja kontrollime uuesti PinD -d jne. Kontrollitakse iga 16 miljoni sekundi järel, kas nuppu vajutatakse, ja seadistage PB0 vastavalt.

Harjutus 5: muutke oma koodi nii, et teie LED oleks ühendatud PB3 -ga, mitte PB0 -ga ja veenduge, et see töötab. Harjutus 6: ühendage oma LED 5V asemel GND -ga ja muutke oma koodi vastavalt.

4. samm: järeldus

Selles õpetuses oleme täiendavalt uurinud ATmega328p kokkupanekukeelt ja õppinud, kuidas juhtida LED -i nupuga. Eelkõige õppisime järgmisi käske:

ser register seab registri kõik bitid väärtuseks 1

clr register määrab registri kõik bitid väärtuseks 0

registris kopeerib i/o register numbri i/o registrist töötavasse registrisse

Järgmises õpetuses uurime ATmega328p struktuuri ja selles sisalduvaid erinevaid registreid, toiminguid ja ressursse.

Enne nende õpetustega jätkamist ootan ja näen huvi taset. Kui on palju inimesi, kes naudivad tegelikult õppimist selle mikroprotsessori programmide koostamise keeles kodeerimiseks, siis jätkan ja konstrueerin keerukamaid vooluahelaid ja kasutan tugevamat koodi.

Soovitan: