Satura rādītājs:

AVR Assembler apmācība 2: 4 soļi
AVR Assembler apmācība 2: 4 soļi

Video: AVR Assembler apmācība 2: 4 soļi

Video: AVR Assembler apmācība 2: 4 soļi
Video: СБОРКА И ЗАПУСК 16-ЛИТРОВОГО V8 ДВИГАТЕЛЯ SCANIA. ПРОБЕГ 1.6 МЛН КМ. DC16 PDE 2024, Jūlijs
Anonim
AVR montētāja apmācība 2
AVR montētāja apmācība 2

Šī apmācība ir turpinājums "AVR Assembler Tutorial 1"

Ja neesat izgājis 1. pamācību, apstājieties un vispirms to dariet.

Šajā apmācībā mēs turpināsim studēt Arduino programmā izmantotā atmega328p montāžas valodas programmēšanu.

Jums būs nepieciešams:

  1. maizes dēlis Arduino vai vienkārši parasts Arduino, kā aprakstīts 1
  2. LED
  3. 220 omu rezistors
  4. spiedpoga
  5. savienojošie vadi, lai izveidotu ķēdi uz maizes dēļa
  6. Instrukciju komplekta rokasgrāmata: www.atmel.com/images/atmel-0856-avr-instruction-s…
  7. Datu lapa: www.atmel.com/images/Atmel-8271-8-bit-AVR-Microco…

Pilnu manu pamācību kolekciju var atrast šeit:

1. darbība: ķēdes izveide

Ķēdes veidošana
Ķēdes veidošana

Vispirms jums jāizveido ķēde, kuru mēs pētīsim šajā apmācībā.

Lūk, kā tas ir savienots:

PB0 (digitālā tapa 8) - LED - R (220 omi) - 5V

PD0 (digitālā tapa 0) - spiedpoga - GND

Jūs varat pārbaudīt, vai jūsu gaismas diode ir pareizi orientēta, pievienojot to GND, nevis PB0. Ja nekas nenotiek, mainiet orientāciju un iedegas gaisma. Pēc tam pievienojiet to PB0 un turpiniet. Attēlā redzams, kā ir savienots mans maizes dēlis arduino.

2. darbība: montāžas kodeksa rakstīšana

Montāžas kodeksa rakstīšana
Montāžas kodeksa rakstīšana

Ierakstiet šādu kodu teksta failā ar nosaukumu pushbutton.asm un apkopojiet to ar avra, kā to darījāt 1. apmācībā.

Ņemiet vērā, ka šajā kodā mums ir daudz komentāru. Katru reizi, kad montētājs redz semikolu, tas izlaidīs pārējo rindu un pāries uz nākamo rindu. Laba programmēšanas prakse (īpaši montāžas valodā!) Ir nopietni komentēt savu kodu, lai nākotnē, atgriežoties pie tā, jūs zinātu, ko darījāt. Pirmajās apmācībās es daudz komentēšu lietas, lai mēs precīzi zinātu, kas notiek un kāpēc. Vēlāk, kad mēs kļūsim mazliet labāki montāžas kodēšanā, es komentēšu lietas mazliet sīkāk.

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

; rakstīja: 1o_o7; datums: 2014. gada 23. oktobris; ************************************

.nolists

.include "m328Pdef.inc".list.def temp = r16; norādīt darba reģistru r16 par temp rjmp Init; izpildīta pirmā rinda

Tajā:

ser temp; iestatiet visus bitus temperatūrā uz 1. out DDRB, temp; iestatot mazliet kā 1 datu virziena I/O; reģistrēties PortB, kas ir DDRB, to nosaka; pin kā izvadi, 0 iestatītu šo tapu kā ievadi; tāpēc šeit visas PortB tapas ir izejas (iestatītas uz 1) ldi temp, 0b11111110; ielādējiet "tūlītējo" numuru temp reģistrā; ja tas būtu tikai ld, tad otrais arguments; būtu jābūt atmiņas vietai, nevis DDRD, temp; mv temp uz DDRD, rezultāts ir tāds, ka tiek ievadīts PD0; un pārējie ir izejas clr temp; visi temperatūras biti ir iestatīti uz 0, kas ir PortB, temp; iestatiet visus PortB bitus (t.i. tapas) uz 0V ldi temp, 0b00000001; ielādējiet tūlītēju numuru, lai izvadītu PortD, temp; pārvietojiet temp uz PortD. PD0 ir pievilkšanas rezistors; (ti, iestatīts uz 5 V), jo tam ir 1 šajā bitā; pārējie ir 0V kopš 0.

Galvenais:

temperatūrā, PinD; PinD saglabā PortD stāvokli, kopējiet to uz temp; ja poga ir pievienota PD0, tā būs; 0, nospiežot pogu, 1 citādi kopš tā laika; PD0 ir pull up rezistors tas parasti pie 5V out PortB, temp; nosūta iepriekš minētos 0 un 1 uz PortB; tas nozīmē, ka mēs vēlamies, lai gaismas diode būtu savienota ar PB0; ja PD0 ir LOW, tas nosaka PB0 uz LOW un pagriežas; uz gaismas diodes (tā kā gaismas diodes otra puse ir; savienota ar 5V, un tas iestatīs PB0 uz 0V tātad; strāva plūdīs) rjmp Main; atgriežas pie Main sākuma

Ņemiet vērā, ka šoreiz mūsu kodā ir ne tikai daudz vairāk komentāru, bet mums ir arī galvenes sadaļa, kas sniedz informāciju par to, kas to uzrakstīja un kad tas tika uzrakstīts. Arī pārējais kods ir sadalīts sadaļās.

Kad esat apkopojis iepriekš minēto kodu, tas jāielādē mikrokontrollerī un jāpārbauda, vai tas darbojas. Gaismas diodei jāiedegas, kamēr jūs nospiežat pogu, un pēc tam atkal jāizslēdzas, kad atlaižat. Es parādīju, kā tas izskatās attēlā.

3. darbība: koda analīze pa rindām

Es izlaidīšu rindas, kas ir tikai komentāri, jo to mērķis ir pašsaprotams.

.nolists

.include "m328Pdef.inc".list

Šīs trīs rindas ietver failu, kas satur mūsu programmēto ATmega328P reģistru un bitu definīcijas. Komanda.nolist liek montētājam neiekļaut šo failu failā pushbutton.lst, ko tas ražo, kad to saliekat. Tas izslēdz ierakstīšanas opciju. Pēc faila iekļaušanas mēs atkal ieslēdzam saraksta opciju ar komandu.list. Mēs to darām tāpēc, ka fails m328Pdef.inc ir diezgan garš, un mums tas tiešām nav jāredz saraksta failā. Mūsu montētājs, avra, automātiski nerada saraksta failu, un, ja mēs to vēlētos, mēs to apkopotu, izmantojot šādu komandu:

avra -l spiedpoga.lst spiedpoga.asm

Ja jūs to darāt, tas ģenerēs failu ar nosaukumu pushbutton.lst, un, izpētot šo failu, jūs atradīsit, ka tajā tiek parādīts jūsu programmas kods kopā ar papildu informāciju. Apskatot papildu informāciju, jūs redzēsit, ka rindas sākas ar C:, kam seko relatīvā adrese heksadecimālā vietā, kur kods ir ievietots atmiņā. Būtībā tas sākas ar 000000 ar pirmo komandu un palielinās no turienes ar katru nākamo komandu. Otrā kolonna aiz relatīvās vietas atmiņā ir komandas heksadecimālais kods, kam seko komandas argumenta heksadecimālais kods. Saraksta failus mēs tālāk apspriedīsim nākamajās apmācībās.

.def temp = r16; norādīt darba reģistru r16 par temp

Šajā rindā mēs izmantojam montētāja direktīvu ".def", lai mainīgo "temp" definētu kā vienādu ar r16 "darba reģistru". Mēs izmantosim reģistru r16 kā to, kurā tiek glabāti numuri, kurus vēlamies kopēt dažādās ostās un reģistros (uz kuriem nevar tieši rakstīt).

1. uzdevums: Mēģiniet kopēt bināro numuru tieši ostā vai īpašā reģistrā, piemēram, DDRB, un uzziniet, kas notiek, mēģinot apkopot kodu.

Reģistrs satur baitu (8 bitus) informācijas. Būtībā tas parasti ir SR-aizbīdņu kolekcija, un katrs no tiem ir “bits” un satur 1 vai 0. Vēlāk šajā sērijā mēs par to (un pat izveidosim!) Varam diskutēt. Jums var rasties jautājums, kas ir "darba reģistrs" un kāpēc mēs izvēlējāmies r16. Mēs to apspriedīsim nākamajā apmācībā, kad iegremdēsimies mikroshēmas iekšējā purvā. Pagaidām es vēlos, lai jūs saprastu, kā rīkoties, piemēram, rakstīt kodu un programmēt fizisko aparatūru. Tad jums būs atsauces sistēma no šīs pieredzes, kas atvieglos mikrokontrollera atmiņas un reģistra rekvizītu izpratni. Es saprotu, ka lielākā daļa ievada mācību grāmatu un diskusiju to dara otrādi, taču es atklāju, ka pirms lietošanas instrukcijas izlasīšanas vispirms kādu laiku spēlēt videospēli, lai iegūtu globālu skatījumu, ir daudz vieglāk nekā izlasīt rokasgrāmatu.

rjmp Init; izpildīta pirmā rinda

Šī rinda ir "relatīvs lēciens" uz etiķetes "Init", un šeit tā nav īsti nepieciešama, jo nākamā komanda jau ir Init, bet mēs to iekļaujam turpmākai lietošanai.

Tajā:

ser temp; iestatiet visus bitus temperatūrā uz 1.

Pēc etiķetes Init mēs izpildām komandu "set register". Tādējādi visi 8 biti reģistrā "temp" (kas, jūsuprāt, ir r16) tiek iestatīti uz 1. Tātad temp tagad satur 0b11111111.

out DDRB, temp; iestatot mazliet kā 1 datu virziena I/O reģistrā

; PortB, kas ir DDRB, nosaka šo tapu kā izvadi; a 0 iestatītu šo tapu kā ievadi; tāpēc šeit visas PortB tapas ir izejas (iestatītas uz 1)

Reģistrs DDRB (datu virziena reģistrs portam Port) norāda, kuras piespraudes portā B (t.i., PB0 līdz PB7) ir norādītas kā ieejas un kuras - kā izejas. Tā kā mums ir piesprausta PB0, kas savienota ar mūsu LED, bet pārējais nav savienots ar neko, mēs iestatīsim visus bitus uz 1, kas nozīmē, ka tie visi ir izvadi.

ldi temp, 0b11111110; ielādējiet tūlītējo numuru temp reģistrā

; ja tas būtu tikai ld, tad otrais arguments būtu; jābūt atmiņas vietai

Šī līnija ielādē bināro numuru 0b11111110 temp reģistrā.

out DDRD, temp; mv temp uz DDRD, rezultāts ir tāds, ka PD0 ir ievade un

; pārējais ir iznākums

Tagad mēs iestatām PortD datu virzienu reģistru no temp, jo temp joprojām satur 0b11111110, mēs redzam, ka PD0 tiks iecelts kā ievades tapa (jo galējā labajā vietā ir 0), bet pārējie tiek apzīmēti kā izejas, jo Šajos punktos ir 1.

clr temp; visi temperatūras biti ir iestatīti uz 0

out PortB, temp; iestatiet visus PortB bitus (t.i. tapas) uz 0V

Vispirms mēs "notīrām" reģistra temp, kas nozīmē visu bitu iestatīšanu uz nulli. Tad mēs to nokopējam PortB reģistrā, kas visiem šiem tapām nosaka 0V. Nulle PortB bitā nozīmē, ka procesors šo tapu uzturēs pie 0 V sprieguma, bet viens uz bitu - šī tapa tiks iestatīta uz 5 V.

2. vingrinājums: izmantojiet multimetru, lai pārbaudītu, vai visas PortB tapas ir nulles. Vai ar PB1 notiek kaut kas dīvains? Ir kāda ideja, kāpēc tas varētu būt? (līdzīgi kā 4. vingrinājumā zemāk, tad sekojiet kodam …) 3. uzdevums: noņemiet no koda iepriekš minētās divas rindiņas. Vai programma joprojām darbojas pareizi? Kāpēc?

ldi temp, 0b00000001; ielādējiet tūlītēju numuru līdz temp

out PortD, temp; pārvietojiet temp uz PortD. PD0 ir pie 5 V (ir pullup rezistors); jo tam ir 1 šajā bitā, pārējie ir 0V. 4. uzdevums: noņemiet no koda iepriekš minētās divas rindiņas. Vai programma joprojām darbojas pareizi? Kāpēc? (Tas atšķiras no iepriekšējā 3. uzdevuma. Skatiet izvilkšanas diagrammu. Kāds ir PD0 noklusējuma DDRD iestatījums? (Skatiet datu lapas 90. lpp.)

Vispirms mēs "nekavējoties ielādējam" numuru 0b00000001 līdz temp. “Tūlītējā” daļa ir pieejama, jo mēs ielādējam skaitli uz augšu, nevis temp, nevis rādītāju uz atmiņas vietu, kurā ir ielādējamais numurs. Tādā gadījumā mēs vienkārši izmantosim "ld", nevis "ldi". Tad mēs nosūtām šo numuru uz PortD, kas nosaka PD0 uz 5V un pārējo uz 0V.

Tagad mēs esam iestatījuši tapas kā ievadi vai izvadi, un mēs esam iestatījuši to sākotnējos stāvokļus kā 0V vai 5V (LOW vai HIGH), un tagad mēs ievadām mūsu programmas "cilpu".

Galvenais: temp, PinD; PinD saglabā PortD stāvokli, kopējiet to uz temp

; ja poga ir savienota ar PD0, tad tā būs; a 0, nospiežot pogu, 1 citādi kopš tā laika; PD0 ir pievilkšanas rezistors, parasti tas ir pie 5 V.

Reģistrs PinD satur pašreizējo PortD tapu stāvokli. Piemēram, ja PD3 pievienojāt 5V vadu, tad nākamajā pulksteņa ciklā (kas notiek 16 miljonus reižu sekundē, jo mikrokontrolleris ir savienots ar 16MHz pulksteņa signālu) PinD3 bitu (no pašreizējā PD3 stāvokļa) kļūtu par 1, nevis 0. Tātad šajā rindā mēs kopējam tapas pašreizējo stāvokli temp.

out PortB, temp; nosūta iepriekš minētos 0 un 1 uz PortB

; tas nozīmē, ka mēs vēlamies, lai gaismas diode būtu savienota ar PB0, tātad; kad PD0 ir LOW, tas iestatīs PB0 uz LOW un pagriezīsies; uz gaismas diodes (gaismas diodes otra puse ir pievienota; līdz 5 V, un tas iestatīs PB0 uz 0 V, lai strāva plūst)

Tagad mēs nosūtām PinD tapu stāvokli uz PortB izeju. Faktiski tas nozīmē, ka PD0 nosūtīs 1 uz PortD0, ja vien netiks nospiesta poga. Tādā gadījumā, tā kā poga ir savienota ar zemi, šī tapa būs pie 0 V sprieguma un nosūtīs 0 uz PortB0. Tagad, ja paskatās uz shēmas shēmu, 0V uz PB0 nozīmē, ka gaismas diode spīdēs, jo tā otrā pusē ir 5 V. Ja mēs nenospiežam pogu, lai 1 tiktu nosūtīts uz PB0, tas nozīmētu, ka mums ir 5V uz PB0 un arī 5V gaismas diodes otrā pusē, un tāpēc nav potenciālu atšķirību un neplūst strāva, un tāpēc Gaismas diode nedeg (šajā gadījumā tas ir gaismas diode, kas ir diode, un tāpēc strāva plūst tikai vienā virzienā neatkarīgi no tā, neatkarīgi no tā).

rjmp Galvenais; atgriežas cilnē Sākt

Šis relatīvais lēciens atgriežas pie mūsu etiķetes Galvenais: mēs vēlreiz pārbaudām PinD un tā tālāk. Katru 16 miljono sekundes daļu pārbauda, vai poga tiek nospiesta, un attiecīgi iestatot PB0.

5. uzdevums: mainiet savu kodu, lai jūsu gaismas diode būtu savienota ar PB3, nevis PB0, un pārbaudiet, vai tā darbojas. 6. uzdevums: pievienojiet savu LED GND, nevis 5V un attiecīgi mainiet savu kodu.

4. solis. Secinājums

Šajā apmācībā mēs esam tālāk izpētījuši ATmega328p montāžas valodu un uzzinājuši, kā vadīt LED ar spiedpogu. Jo īpaši mēs iemācījāmies šādas komandas:

ser reģistrs visus reģistra bitus iestata uz 1

clr reģistrs visus reģistra bitus iestata uz 0

reģistrā i/o reģistrs kopē numuru no i/o reģistra uz darba reģistru

Nākamajā apmācībā mēs pārbaudīsim ATmega328p struktūru un tajā esošos dažādus reģistrus, darbības un resursus.

Pirms turpināt šīs apmācības, es gaidīšu un redzēšu interesi. Ja ir vairāki cilvēki, kuriem patiešām patīk mācīties, kā kodēt programmas šim mikroprocesoram montāžas valodā, tad es turpināšu un būvēšu sarežģītākas shēmas un izmantošu stabilāku kodu.

Ieteicams: