Sisällysluettelo:

AVR -kokoonpanon opetusohjelma 2: 4 vaihetta
AVR -kokoonpanon opetusohjelma 2: 4 vaihetta

Video: AVR -kokoonpanon opetusohjelma 2: 4 vaihetta

Video: AVR -kokoonpanon opetusohjelma 2: 4 vaihetta
Video: Гениальные Лайфхаки, Которые Действительно Работают ▶3 2024, Heinäkuu
Anonim
AVR -kokoonpanon opetusohjelma 2
AVR -kokoonpanon opetusohjelma 2

Tämä opetusohjelma on jatkoa "AVR Assembler Tutorial 1" -ohjelmalle

Jos et ole käynyt läpi opetusohjelmaa 1, lopeta nyt ja tee se ensin.

Tässä opetusohjelmassa jatkamme tutkimustamme Arduinon käyttämän atmega328p: n kokoonpanokielen ohjelmoinnista.

Tarvitset:

  1. leipälauta Arduino tai vain tavallinen Arduino kuten opetusohjelmassa 1
  2. LED
  3. 220 ohmin vastus
  4. painike
  5. liitäntäjohdot piirilevyn tekemiseksi leipälevyllesi
  6. Injektiosarjan käyttöohje: www.atmel.com/images/atmel-0856-avr-instruction-s…
  7. Tietolomake: www.atmel.com/images/Atmel-8271-8-bit-AVR-Microco…

Opetusohjelmien kokoelma löytyy täältä:

Vaihe 1: Piirin rakentaminen

Piirin rakentaminen
Piirin rakentaminen

Ensin sinun on rakennettava piiri, jota tutkimme tässä opetusohjelmassa.

Tässä on tapa yhdistää se:

PB0 (digitaalinen nasta 8) - LED - R (220 ohmia) - 5V

PD0 (digitaalinen nasta 0) - painike - GND

Voit tarkistaa, että LED on suunnattu oikein liittämällä se GND: hen PB0: n sijasta. Jos mitään ei tapahdu, käännä suunta ja valon pitäisi syttyä. Liitä se sitten PB0: een ja jatka. Kuvassa näkyy, miten leipälevyni arduino on kytketty.

Vaihe 2: Kokoonpanokoodin kirjoittaminen

Kokoonpanokoodin kirjoittaminen
Kokoonpanokoodin kirjoittaminen

Kirjoita seuraava koodi tekstitiedostoon nimeltä pushbutton.asm ja käännä se avran avulla kuten opetusohjelmassa 1.

Huomaa, että tässä koodissa on paljon kommentteja. Aina kun kokoonpanija näkee puolipisteen, se ohittaa loput rivistä ja siirtyy seuraavalle riville. On hyvä ohjelmointikäytäntö (etenkin kokoonpanokielellä!) Kommentoida voimakkaasti koodiasi, jotta kun palaat siihen tulevaisuudessa, tiedät mitä teit. Aion kommentoida asioita melko paljon ensimmäisissä opetusohjelmissa, jotta tiedämme tarkalleen, mitä tapahtuu ja miksi. Myöhemmin, kun meistä tulee hieman parempia kokoonpanokoodauksessa, kommentoin asioita hieman vähemmän yksityiskohtaisesti.

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

; kirjoittanut: 1o_o7; päivämäärä: 23. lokakuuta 2014; ************************************

.nolisti

.include "m328Pdef.inc".list.def temp = r16; nimetä työrekisteri r16 lämpötilaksi rjmp Init; ensimmäinen rivi suoritettu

Sen sisällä:

huonelämpötila; aseta kaikki bitit lämpötilaan 1. ulos DDRB, lämpötila; asetetaan bitiksi 1 Data Direction I/O: ssa; rekisteröi PortB, joka on DDRB, asettaa sen; pin ulostulona, 0 asettaa tämän nastan tuloksi; joten tässä kaikki PortB -nastat ovat lähtöjä (asetettu arvoon 1) ldi temp, 0b11111110; lataa "välitön" numero väliaikaiseen rekisteriin; jos se olisi vain ld, toinen argumentti; pitäisi olla muistipaikka sen sijaan ulos DDRD, temp; mv temp DDRD, tulos on, että PD0 syötetään; ja loput ovat lähtöjä clr temp; kaikki bitit lämpötilassa on asetettu 0: een ulos PortB, temp; aseta kaikki portin B bitit (eli nastat) arvoon 0V ldi temp, 0b00000001; lataa välitön numero väliaikaiseksi PortD, temp; siirrä lämpötila PortD: hen. PD0: ssa on vetovastus; (eli asetettu arvoon 5V), koska sillä on 1 tässä bitissä; loput ovat 0V 0: n jälkeen.

Pää:

lämpötilassa, PinD; PinD pitää PortD -tilan, kopioi tämä väliaikaiseen; jos painike on kytketty PD0: een, tämä on; 0, kun painiketta painetaan, 1 muutoin siitä lähtien; PD0: ssa on vetovastus, joka on normaalisti 5 V: n lähtöportissa B, lämpötila; lähettää yllä luetut 0: t ja 1: t PortB: lle; tämä tarkoittaa, että haluamme, että LED kytketään PB0: een; kun PD0 on LOW, se asettaa PB0: n LOW ja kääntyy; LEDissä (koska LEDin toinen puoli on; kytketty 5 V: een ja tämä asettaa PB0: n 0 V: ksi; virta virtaa) rjmp Main; palaa Mainin alkuun

Huomaa, että tällä kertaa meillä ei ole vain paljon enemmän kommentteja koodissamme, vaan meillä on myös otsikko -osio, joka antaa tietoja siitä, kuka sen on kirjoittanut ja milloin se on kirjoitettu. Loput koodista on myös jaettu osiin.

Kun olet koonnut yllä olevan koodin, lataa se mikrokontrolleriin ja katso, että se toimii. LED -valon pitäisi syttyä, kun painat painiketta, ja sammua uudelleen, kun päästät irti. Näytin kuvassa, miltä se näyttää.

Vaihe 3: Koodin rivi-rivi-analyysi

Ohitan rivit, jotka ovat vain kommentteja, koska niiden tarkoitus on itsestään selvä.

.nolisti

.include "m328Pdef.inc".list

Nämä kolme riviä sisältävät tiedoston, joka sisältää ohjelmoimamme ATmega328P: n rekisterit ja bittimääritykset.. Nolist -komento käskee kokoonpanijan olemaan sisällyttämättä tätä tiedostoa pushbutton.lst -tiedostoon, jonka se tuottaa kokoamisen aikana. Se poistaa luettelovaihtoehdon käytöstä. Kun olet sisällyttänyt tiedoston, otamme luettelovaihtoehdon takaisin käyttöön.list -komennolla. Syynä tähän on se, että m328Pdef.inc -tiedosto on melko pitkä, eikä meidän tarvitse nähdä sitä luettelotiedostossa. Asentajamme avra ei luo automaattisesti luettelotiedostoa, ja jos haluaisimme sellaisen, kokoisimme seuraavan komennon avulla:

avra -l painike.lst painike.asm

Jos teet tämän, se luo tiedoston nimeltä pushbutton.lst ja jos tarkastelet tätä tiedostoa, huomaat, että se näyttää ohjelmakoodisi ja lisätietoja. Jos tarkastelet lisätietoja, huomaat, että rivit alkavat C: llä: sen jälkeen heksadesimaalinen osoite, johon koodi on tallennettu muistiin. Pohjimmiltaan se alkaa 000000 ensimmäisellä komennolla ja kasvaa sieltä jokaisen seuraavan komennon jälkeen. Toinen sarake suhteellisen muistipaikan jälkeen on komennon heksadesimaalikoodi ja sen jälkeen komennon argumentin heksakoodi. Keskustelemme luettelotiedostoista tarkemmin tulevissa opetusohjelmissa.

.def lämpötila = r16; nimetä työrekisteri r16 lämpötilaksi

Tällä rivillä käytämme assembler -direktiiviä ".def" määrittämään muuttuja "temp" yhtä suureksi kuin r16 "työrekisteri". Käytämme rekisteriä r16, joka tallentaa numerot, jotka haluamme kopioida eri portteihin ja rekistereihin (joita ei voi kirjoittaa suoraan).

Harjoitus 1: Yritä kopioida binääriluku suoraan porttiin tai erityiseen rekisteriin, kuten DDRB, ja katso mitä tapahtuu, kun yrität koota koodin.

Rekisteri sisältää tavun (8 bittiä) tietoa. Pohjimmiltaan se on yleensä SR-salpojen kokoelma, joista jokainen on "bitti" ja sisältää 1 tai 0. Voimme keskustella tästä (ja jopa rakentaa sellaisen!) Myöhemmin tässä sarjassa. Saatat ihmetellä, mikä on "työrekisteri" ja miksi valitsimme r16: n. Keskustelemme siitä tulevassa opetusohjelmassa, kun sukellamme sirun sisäosien suolaan. Tällä hetkellä haluan sinun ymmärtävän, miten voit tehdä asioita, kuten kirjoittaa koodia ja ohjelmoida fyysisiä laitteita. Sitten sinulla on viitekehys kokemuksesta, joka helpottaa mikro -ohjaimen muistin ja rekisterin ominaisuuksia. Ymmärrän, että useimmat johdanto -oppikirjat ja keskustelut tekevät tämän päinvastoin, mutta olen huomannut, että videopelin pelaaminen ensin jonkin aikaa globaalin näkökulman saamiseksi ennen käyttöoppaan lukemista on paljon helpompaa kuin käyttöoppaan lukeminen ensin.

rjmp Init; ensimmäinen rivi suoritettu

Tämä rivi on "suhteellinen hyppy" otsikkoon "Init", eikä sitä todellakaan tarvita tässä, koska seuraava komento on jo Initissä, mutta sisällytämme sen tulevaa käyttöä varten.

Sen sisällä:

huonelämpötila; aseta kaikki bitit lämpötilaan 1.

Init -tunnisteen jälkeen suoritamme "set register" -komennon. Tämä asettaa kaikki rekisterin "temp" (jonka muistat r16) 8 bitin arvoksi 1. Joten lämpötila sisältää nyt 0b11111111.

ulos DDRB, lämpötila; asetetaan bitiksi 1 Data Direction I/O -rekisterissä

; PortB: lle, joka on DDRB, asettaa tämän nastan lähtöön; 0 asettaa tämän nastan tuloksi; joten tässä kaikki PortB -nastat ovat lähtöjä (asetettu arvoon 1)

Rekisteri DDRB (Data Direction Register for PortB) kertoo, mitkä PortB: n nastat (eli PB0 - PB7) on merkitty tuloksi ja mitkä lähtöksi. Koska nasta PB0 on kytketty LED -valoon ja loput eivät ole yhteydessä mihinkään, asetamme kaikki bitit arvoon 1 eli ne ovat kaikki ulostuloja.

ldi -lämpötila, 0b11111110; lataa `` välitön '' numero väliaikaiseen rekisteriin

; jos se olisi vain ld, toinen argumentti olisi; täytyy olla muistipaikka

Tämä rivi lataa binääriluvun 0b11111110 lämpörekisteriin.

ulos DDRD, lämpötila; mv temp DDRD, tulos on, että PD0 on tulo ja

; loput ovat lähtöjä

Nyt asetamme PortD: n datasuuntarekisterin lämpötilasta, koska temp sisältää edelleen 0b11111110, näemme, että PD0 nimetään tulonapiksi (koska oikeassa reunassa on 0) ja loput nimetään lähtöiksi, koska 1 on noissa paikoissa.

clr lämpötila; kaikki bitit lämpötilassa on asetettu 0: een

ulos PortB, lämpötila; aseta kaikki portin B bitit (eli nastat) arvoon 0 V.

Ensin "tyhjennä" rekisterin lämpötila, mikä tarkoittaa kaikkien bittien asettamista nollaan. Sitten kopioimme sen PortB -rekisteriin, joka asettaa 0V kaikille näille nastoille. Nolla PortB -bittissä tarkoittaa, että prosessori pitää tuon nastan 0 V: n jännitteellä, yksi bitti aiheuttaa sen, että nasta asetetaan 5 V.

Harjoitus 2: Tarkista yleismittarilla, ovatko kaikki PortB: n nastat todella nolla. Onko PB1: ssä jotain outoa? Onko tietoa miksi se voisi olla? (samanlainen kuin harjoitus 4 alla ja seuraa koodia…) Harjoitus 3: Poista yllä olevat kaksi riviä koodistasi. Toimiiko ohjelma edelleen oikein? Miksi?

ldi -lämpötila, 0b00000001; lataa välitön numero lämpötilaan

ulos PortD, lämpötila; siirrä lämpötila PortD: hen. PD0 on 5 V (on vetovoima); koska siinä on 1 tässä bitissä, loput ovat 0V. Harjoitus 4: Poista yllä olevat kaksi riviä koodistasi. Toimiiko ohjelma edelleen oikein? Miksi? (Tämä eroaa yllä olevasta harjoituksesta 3. Katso pin out -kaavio. Mikä on DDRD -oletusasetus PD0: lle? (Katso tietolomakkeen sivu 90

Ensin "lataamme välittömästi" numeron 0b00000001 lämpötilaan. "Välitön" osa on olemassa, koska lataamme suoraan ylöspäin olevaa numeroa lämpötilaan eikä osoitinta muistipaikkaan, joka sisältää ladattavan numeron. Siinä tapauksessa käytämme vain "ld": tä "ldi": n sijasta. Sitten lähetämme tämän numeron PortD: lle, joka asettaa PD0: n 5V: ksi ja loput 0V: ksi.

Nyt olemme asettaneet nastat tuloksi tai lähdöksi ja asettaneet niiden alkutiloiksi joko 0V tai 5V (LOW tai HIGH), joten siirrymme nyt ohjelman "silmukkaan".

Pää: lämpötilassa, PinD; PinD pitää PortD -tilan, kopioi tämä väliaikaiseen

; jos painike on kytketty PD0: een, tämä tapahtuu; a 0, kun painiketta painetaan, 1 muutoin sen jälkeen; PD0: ssa on vetovastus, joka on normaalisti 5V

Rekisteri PinD sisältää PortD -nastojen nykyisen tilan. Jos esimerkiksi liitit 5 V: n johdon PD3: een, seuraavalla kellojaksolla (joka tapahtuu 16 miljoonaa kertaa sekunnissa, koska mikrokontrolleri on kytketty 16 MHz: n kellosignaaliin) PinD3 -bitti (PD3: n nykyisestä tilasta) muuttuisi 1: ksi 0: n sijasta. Joten tällä rivillä kopioimme nastojen nykyisen tilan lämpötilaan.

ulos PortB, lämpötila; lähettää yllä luetut 0: n ja 1: n PortB: lle

; tämä tarkoittaa, että haluamme, että LED kytketään PB0: een, joten; kun PD0 on LOW, se asettaa PB0 -asentoon LOW ja kääntyy; LED -valossa (LEDin toinen puoli on kytketty; 5 V ja tämä asettaa PB0 arvoon 0 V, joten virta kulkee)

Nyt lähetämme PinD: n nastojen tilan PortB -lähtöön. Käytännössä tämä tarkoittaa sitä, että PD0 lähettää 1: n PortD0: lle, ellei painiketta paineta. Siinä tapauksessa, että painike on kytketty maahan, nasta on 0 V ja se lähettää 0 PortB0: lle. Jos katsot nyt piirikaaviota, 0V PB0: lla tarkoittaa, että LED -valo palaa, koska sen toinen puoli on 5V. Jos emme paina painiketta, niin että 1 lähetetään PB0: een, se tarkoittaa, että meillä on 5 V PB0: ssa ja myös 5 V LEDin toisella puolella, joten potentiaalieroa ei ole ja virtaa ei virtaa, joten LED ei pala (tässä tapauksessa se on LED, joka on diodi ja siten virta kulkee vain yhteen suuntaan riippumatta).

rjmp Main; palaa takaisin alkuun

Tämä suhteellinen hyppy palauttaa meidät takaisin Main: -tunnisteeseemme ja tarkistamme PinD: n uudelleen ja niin edelleen. Tarkistetaan joka 16. miljoonasosa sekunnin aikana, painetaanko painiketta ja asetetaan PB0 vastaavasti.

Harjoitus 5: Muokkaa koodiasi niin, että LED -valo on kytketty PB3: een PB0: n sijasta ja että se toimii.

Vaihe 4: Johtopäätös

Tässä opetusohjelmassa olemme tutkineet edelleen ATmega328p: n kokoonpanokieltä ja oppineet ohjaamaan LEDiä painikkeella. Opimme erityisesti seuraavat komennot:

ser -rekisteri asettaa kaikki rekisterin bitit arvoon 1

clr -rekisteri asettaa kaikki rekisterin bitit arvoon 0

rekisterissä, i/o -rekisteri kopioi numeron i/o -rekisteristä toimivaan rekisteriin

Seuraavassa opetusohjelmassa tarkastelemme ATmega328p: n rakennetta ja siihen sisältyviä erilaisia rekistereitä, toimintoja ja resursseja.

Ennen kuin jatkan näiden opetusohjelmien kanssa, aion odottaa ja nähdä kiinnostuksen tason. Jos on monia ihmisiä, jotka todella nauttivat oppimasta ohjelmoimaan ohjelmia tälle mikroprosessorille kokoonpanokielellä, jatkan ja rakennan monimutkaisempia piirejä ja käytän vahvempaa koodia.

Suositeltava: