Turinys:

AVR surinkėjo pamoka 2: 4 žingsniai
AVR surinkėjo pamoka 2: 4 žingsniai

Video: AVR surinkėjo pamoka 2: 4 žingsniai

Video: AVR surinkėjo pamoka 2: 4 žingsniai
Video: 4 pamoka - kaip pajungti LCD1602 ekraną 2024, Liepa
Anonim
AVR surinkėjo pamoka 2
AVR surinkėjo pamoka 2

Ši pamoka yra „AVR Assembler Tutorial 1“tęsinys

Jei dar neperžiūrėjote 1 vadovo, turėtumėte sustoti ir tai padaryti pirmiausia.

Šioje pamokoje mes tęsime „Arduino“naudojamo „atmega328p“surinkimo kalbos programavimo tyrimą.

Jums reikės:

  1. duonos lentą „Arduino“arba tiesiog įprastą „Arduino“, kaip nurodyta 1 pamokoje
  2. šviesos diodas
  3. 220 omų rezistorius
  4. mygtukas
  5. jungiamieji laidai, skirti grandinei gaminti ant jūsų duonos lentos
  6. Instrukcijų rinkinio vadovas: www.atmel.com/images/atmel-0856-avr-instruction-s…
  7. Duomenų lapas: www.atmel.com/images/Atmel-8271-8-bit-AVR-Microco…

Visą mano vadovėlių kolekciją rasite čia:

1 žingsnis: sukurkite grandinę

Grandinės kūrimas
Grandinės kūrimas

Pirmiausia turite sukurti grandinę, kurią mes mokysimės šioje pamokoje.

Štai kaip jis prijungtas:

PB0 (skaitmeninis kaištis 8) - LED - R (220 omų) - 5V

PD0 (skaitmeninis kaištis 0) - mygtukas - GND

Galite patikrinti, ar jūsų šviesos diodas yra tinkamai nukreiptas, prijungdami jį prie GND, o ne prie PB0. Jei nieko neatsitiks, pakeiskite kryptį ir lemputė turėtų užsidegti. Tada vėl prijunkite jį prie PB0 ir tęskite. Paveikslėlyje parodyta, kaip prijungtas mano duonos skydas arduino.

2 žingsnis: Surinkite surinkimo kodeksą

Surinkimo kodekso rašymas
Surinkimo kodekso rašymas

Įrašykite šį kodą į tekstinį failą, pavadintą pushbutton.asm, ir sukompiliuokite jį naudodami avra, kaip tai darėte 1 pamokoje.

Atkreipkite dėmesį, kad šiame kodekse turime daug komentarų. Kiekvieną kartą, kai surinkėjas pamato kabliataškį, jis praleis likusią eilutės dalį ir pereis prie kitos eilutės. Gera programavimo praktika (ypač surinkimo kalba!) Smarkiai komentuoti savo kodą, kad ateityje grįžę prie jo žinotumėte, ką darėte. Pirmosiose pamokose aš daug ką komentuosiu, kad tiksliai žinotume, kas vyksta ir kodėl. Vėliau, kai tik mes šiek tiek geriau mokėsime surinkti kodavimą, aš pakomentuosiu dalykus šiek tiek smulkiau.

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

; parašė: 1o_o7; data: 2014 m. spalio 23 d.; ***********************************

.nolistas

.įtraukti „m328Pdef.inc“.list.def temp = r16; paskirti darbo registrą r16 kaip temp rjmp Init; įvykdyta pirmoji eilutė

Inicija:

ser temp; nustatykite visus bitus temperatūroje į 1. iš DDRB, temp; duomenų krypties įvesties/išvesties bitų nustatymas 1; užsiregistruokite „PortB“, kuris yra DDRB, tai nustato; kaištis kaip išvestis, 0 nustatytų tą kaištį kaip įvestį; taigi čia visi PortB kaiščiai yra išėjimai (nustatyti į 1) ldi temp, 0b11111110; įkelkite „tiesioginį“numerį į laikiną registrą; jei tai būtų tik ld, tada antrasis argumentas; turėtų būti atminties vieta, o ne DDRD, temp; mv temp į DDRD, rezultatas yra tas, kad įvedamas PD0; o likusieji yra išėjimai clr temp; visi bitai, esantys temp, yra nustatyti į 0 išvestį PortB, temp; nustatykite visus „PortB“bitus (t. y. kaiščius) į 0V ldi temp, 0b00000001; įkelti tiesioginį numerį, kad pašalintumėte PortD, temp; perkelti temp į PortD. PD0 turi ištraukiamąjį rezistorių; (t. y. nustatytas į 5 V), nes tame bite yra 1; likusios yra 0V nuo 0.

Pagrindinis:

esant temperatūrai, PinD; PinD turi PortD būseną, nukopijuokite ją į temp; jei mygtukas prijungtas prie PD0, tai bus; 0, kai mygtukas yra paspaustas, 1 kitaip; PD0 turi ištraukiamąjį rezistorių, paprastai esant 5 V išvesties prievadui B, temp; siunčia aukščiau perskaitytus 0 ir 1 į „PortB“; tai reiškia, kad norime, kad šviesos diodas būtų prijungtas prie PB0; kai PD0 yra LOW, jis nustato PB0 į LOW ir sukasi; ant šviesos diodo (kadangi kita šviesos diodo pusė yra; prijungta prie 5 V ir tai nustatys PB0 į 0 V taip; srovė tekės) rjmp Main; grįžta į „Main“pradžią

Atkreipkite dėmesį, kad šį kartą mūsų kodekse yra ne tik daug daugiau komentarų, bet ir antraštės skiltis, kurioje pateikiama informacija apie tai, kas ją parašė ir kada ji buvo parašyta. Likusi kodo dalis taip pat yra padalinta į skyrius.

Surinkę aukščiau pateiktą kodą, turite jį įkelti į mikrovaldiklį ir pamatyti, ar jis veikia. Šviesos diodas turėtų įsijungti, kai spaudžiate mygtuką, o tada vėl išsijungti, kai paleidžiate. Parodžiau, kaip tai atrodo paveikslėlyje.

3 žingsnis: eilučių eilutės kodo analizė

Praleisiu eilutes, kurios yra tik komentarai, nes jų tikslas yra savaime suprantamas.

.nolistas

.include "m328Pdef.inc".list

Šios trys eilutės apima failą, kuriame yra mūsų programuojamo ATmega328P registras ir bitų apibrėžimai. Komanda.nolist liepia surinkėjui neįtraukti šio failo į failą pushbutton.lst, kurį jis sukuria jį surinkus. Tai išjungia sąrašo parinktį. Įtraukę failą, mes vėl įjungiame sąrašo parinktį naudodami komandą.list. Tai darome todėl, kad failas m328Pdef.inc yra gana ilgas ir mums tikrai nereikia jo matyti sąrašo faile. Mūsų surinkėjas „avra“automatiškai nesukuria sąrašo failo, o jei norėtume, surinktume naudodami šią komandą:

avra -l mygtukas.lst mygtukas.asm

Jei tai padarysite, jis sugeneruos failą, pavadintą pushbutton.lst, ir, ištyrę šį failą, pamatysite, kad jame rodomas jūsų programos kodas ir papildoma informacija. Jei pažvelgsite į papildomą informaciją, pamatysite, kad eilutės prasideda C:, o po to - santykinis adresas šešioliktainėje vietoje, kur kodas įrašytas į atmintį. Iš esmės jis prasideda nuo 000000 su pirmąja komanda ir didėja nuo kiekvienos kitos komandos. Antrasis stulpelis po santykinės vietos atmintyje yra komandos šešioliktainis kodas, po kurio nurodomas komandos argumentas. Sąrašo failus toliau aptarsime būsimuose vadovėliuose.

.def temp = r16; paskirti darbo registrą r16 kaip temp

Šioje eilutėje mes naudojame surinkėjo direktyvą „.def“, kad kintamąjį „temp“apibrėžtume kaip lygų r16 „darbo registrui“. Mes naudosime registrą r16 kaip tą, kuriame saugomi numeriai, kuriuos norime nukopijuoti į įvairius prievadus ir registrus (į kuriuos negalima tiesiogiai įrašyti).

1 pratimas: pabandykite nukopijuoti dvejetainį numerį tiesiai į prievadą arba specialų registrą, pvz., DDRB, ir pažiūrėkite, kas atsitiks, kai bandysite surinkti kodą.

Registre yra baitas (8 bitai) informacijos. Iš esmės tai paprastai yra SR fiksatorių rinkinys, kiekvienas iš jų yra „bitas“ir jame yra 1 arba 0. Vėliau mes galime apie tai (ir net sukurti!) Vėliau šioje serijoje. Jums gali būti įdomu, kas yra „darbo registras“ir kodėl mes pasirinkome r16. Mes tai aptarsime būsimoje pamokoje, kai pasinersime į mikroschemos vidų liūną. Kol kas noriu, kad jūs suprastumėte, kaip daryti tokius dalykus kaip rašyti kodą ir programuoti fizinę aparatinę įrangą. Tada turėsite atskaitos sistemą iš šios patirties, kuri padės lengviau suprasti mikrovaldiklio atmintį ir registro savybes. Suprantu, kad dauguma įvadinių vadovėlių ir diskusijų tai daro atvirkščiai, tačiau pastebėjau, kad prieš kurį laiką žaisti vaizdo žaidimą, kad gautumėte visapusišką požiūrį, yra daug lengviau nei perskaityti vadovą.

rjmp Init; įvykdyta pirmoji eilutė

Ši eilutė yra „santykinis šuolis“į etiketę „Init“ir čia tikrai nereikalinga, nes kita komanda jau yra „Init“, tačiau ją įtraukiame ateityje.

Inicija:

ser temp; nustatykite visus bitus temperatūroje į 1.

Po „Init“etiketės vykdome komandą „set register“. Tai nustato visus 8 bitus registre „temp“(kuris, jūsų manymu, yra r16) į 1. Taigi temperatūroje dabar yra 0b11111111.

iš DDRB, temp; duomenų krypties įvesties/išvesties registre nustatykite šiek tiek kaip 1

; „PortB“, kuris yra DDRB, nustato tą kaištį kaip išvestį; a 0 nustatytų tą kaištį kaip įvestį; Taigi čia visi „PortB“kaiščiai yra išėjimai (nustatyta į 1)

Registras DDRB („PortB“duomenų krypčių registras) nurodo, kurie „PortB“kaiščiai (t. Y. PB0 – PB7) yra įvesti, o kurie - kaip išėjimai. Kadangi kaištis PB0 prijungtas prie mūsų šviesos diodo, o likusieji nėra prijungti prie nieko, mes nustatysime visus bitus į 1, tai reiškia, kad jie visi yra išėjimai.

ldi temp, 0b11111110; įkelkite „tiesioginį“numerį į laikiną registrą

; jei tai būtų tik ld, antrasis argumentas būtų; turi būti atminties vieta

Ši eilutė įkelia dvejetainį skaičių 0b11111110 į temp registrą.

iš DDRD, temp; mv temp į DDRD, rezultatas yra tas, kad PD0 yra įvestis ir

; likusi dalis yra išėjimai

Dabar mes nustatome „PortD“duomenų krypties registrą iš temp, nes temp vis dar yra 0b11111110, matome, kad PD0 bus įvestas kaip įvesties kaištis (nes dešinėje yra 0), o likusi dalis yra išvestis, nes yra 1 tose vietose.

clr temp; visi temperatūros bitai nustatyti į 0

išėjimas PortB, temp; nustatykite visus „PortB“bitus (t. y. kaiščius) į 0 V.

Pirmiausia „išvalome“registro temp, o tai reiškia, kad visi bitai turi būti nustatyti į nulį. Tada nukopijuojame tai į „PortB“registrą, kuriame visuose kaiščiuose nustatomas 0V. Nulis „PortB“bite reiškia, kad procesorius išlaikys tą kaištį esant 0 V įtampai, o vienas ant kito - tas kaištis bus nustatytas į 5 V.

2 pratimas: naudokite multimetrą, kad patikrintumėte, ar visi „PortB“kaiščiai yra nuliniai. Ar su PB1 vyksta kažkas keisto? Ar turite idėjų, kodėl taip gali būti? (panašiai kaip 4 pratimas, tada sekite kodą …) 3 pratimas: pašalinkite dvi aukščiau esančias eilutes iš savo kodo. Ar programa vis dar veikia tinkamai? Kodėl?

ldi temp, 0b00000001; nedelsiant įkelkite numerį į temp

išėjimas PortD, temp; perkelti temp į PortD. PD0 yra esant 5 V įtampai (turi ištraukimo rezistorių); kadangi jo bitų skaičius yra 1, likusi dalis yra 0 V. 4 pratimas: pašalinkite dvi aukščiau esančias eilutes iš savo kodo. Ar programa vis dar veikia tinkamai? Kodėl? (Tai skiriasi nuo 3 pratimo aukščiau. Žr. Ištraukimo diagramą. Koks yra numatytasis PD0 DDRD nustatymas? (Žr. Duomenų lapo 90 puslapį

Pirmiausia „nedelsiant“įkeliame skaičių 0b00000001 į temp. „Neatidėliotina“dalis yra, nes mes įkeliame tiesioginį skaičių į temp, o ne rodyklę į atminties vietą, kurioje yra įkeliamas skaičius. Tokiu atveju mes tiesiog naudosime „ld“, o ne „ldi“. Tada mes siunčiame šį numerį į „PortD“, kuris nustato PD0 į 5 V, o likusį - į 0 V.

Dabar mes nustatėme kaiščius kaip įvestį ar išvestį, o pradines būsenas nustatėme kaip 0V arba 5V (LOW arba HIGH), todėl dabar įeiname į savo programos „kilpą“.

Pagrindinis: esant temp, PinD; „PinD“turi „PortD“būseną, nukopijuokite ją į temp

; jei mygtukas prijungtas prie PD0, tai bus; a 0, kai mygtukas yra paspaustas, 1 kitaip; PD0 turi ištraukiamąjį rezistorių, paprastai esant 5 V įtampai

„PinD“registre yra dabartinė „PortD“kaiščių būsena. Pvz., Jei prie PD3 prijungėte 5 V laidą, tada kito laikrodžio ciklo metu (kuris vyksta 16 milijonų kartų per sekundę, nes mikrovaldiklis prijungtas prie 16 MHz laikrodžio signalo) PinD3 bitą (iš dabartinės PD3 būsenos) taptų 1, o ne 0. Taigi šioje eilutėje nukopijuojame dabartinę kaiščių būseną į temp.

išėjimas PortB, temp; siunčia aukščiau perskaitytus 0 ir 1 į „PortB“

; tai reiškia, kad norime, kad šviesos diodas būtų prijungtas prie PB0, taigi; kai PD0 yra LOW, jis nustatys PB0 į LOW ir pasuks; ant šviesos diodo (kita šviesos diodo pusė prijungta; prie 5 V ir tai nustatys PB0 į 0 V, kad tekėtų srovė)

Dabar „PinD“kaiščių būseną siunčiame į „PortB“išvestį. Iš tikrųjų tai reiškia, kad PD0 siunčia 1 į PortD0, nebent paspaudžiamas mygtukas. Tokiu atveju, kadangi mygtukas yra prijungtas prie žemės, kaištis bus 0 V įtampoje ir jis nusiųs 0 į „PortB0“. Dabar, jei pažvelgsite į schemą, 0V PB0 reiškia, kad šviesos diodas šviečia, nes kita jo pusė yra 5 V. Jei nespaudžiame mygtuko, kad 1 būtų siunčiamas į PB0, tai reikštų, kad turime 5V ant PB0, taip pat 5V kitoje šviesos diodo pusėje, todėl nėra jokio potencialo skirtumo ir srovė nebus tekėjusi. Šviesos diodas nešviečia (šiuo atveju tai yra šviesos diodas, kuris yra diodas, todėl srovė teka tik viena kryptimi, neatsižvelgiant į tai).

rjmp Pagrindinis; grįžta į pradžią

Šis santykinis šuolis sugrąžina mus į pagrindinę etiketę: mes dar kartą patikriname „PinD“ir pan. Kas 16 milijonųjų sekundžių patikrinimas, ar mygtukas spaudžiamas, ir atitinkamai nustatyti PB0.

5 pratimas: pakeiskite kodą, kad jūsų šviesos diodas būtų prijungtas prie PB3, o ne PB0, ir įsitikinkite, kad jis veikia. 6 pratimas: prijunkite savo šviesos diodą prie GND, o ne 5 V ir atitinkamai pakeiskite kodą.

4 žingsnis: Išvada

Šioje pamokoje mes toliau ištyrėme „ATmega328p“surinkimo kalbą ir sužinojome, kaip valdyti šviesos diodą mygtuku. Visų pirma mes išmokome šias komandas:

ser registras nustato visus registro bitus į 1

clr register nustato visus registro bitus į 0

registre, i/o registras nukopijuoja numerį iš i/o registro į darbo registrą

Kitame vadove mes išnagrinėsime ATmega328p struktūrą ir įvairius registrus, operacijas ir išteklius.

Prieš tęsdamas šias pamokas, aš palauksiu ir pamatysiu susidomėjimo lygį. Jei yra daug žmonių, kuriems iš tikrųjų patinka mokytis koduoti šio mikroprocesoriaus programas surinkimo kalba, aš tęsiu ir kursiu sudėtingesnes grandines ir naudosiu tvirtesnį kodą.

Rekomenduojamas: