Mundarija:

AVR Assembler qo'llanmasi 2: 4 qadam
AVR Assembler qo'llanmasi 2: 4 qadam

Video: AVR Assembler qo'llanmasi 2: 4 qadam

Video: AVR Assembler qo'llanmasi 2: 4 qadam
Video: MKS SGEN L V1.0 - A4988 Stepper Drivers 2024, Iyul
Anonim
AVR Assembler qo'llanmasi 2
AVR Assembler qo'llanmasi 2

Bu darslik "AVR Assembler Tutorial 1" ning davomi

Agar siz 1 -darsdan o'tmagan bo'lsangiz, hozir to'xtab, avval buni qilishingiz kerak.

Ushbu qo'llanmada biz Arduino -da ishlatiladigan atmega328p -ning montaj tilini dasturlashni o'rganishni davom ettiramiz.

Sizga kerak bo'ladi:

  1. non paneli Arduino yoki oddiy Arduino 1 -darsda bo'lgani kabi
  2. LED
  3. 220 ohmli qarshilik
  4. bosish tugmasi
  5. non panelidagi sxemani tuzish uchun ulash simlari
  6. Qo'llanma to'plami: www.atmel.com/images/atmel-0856-avr-instruction-s…
  7. Ma'lumotlar jadvali: www.atmel.com/images/Atmel-8271-8-bit-AVR-Microco…

Mening darsliklarimning to'liq to'plamini bu erda topishingiz mumkin:

1 -qadam: O'chirish tizimini yaratish

O'chirish davri
O'chirish davri

Avval siz ushbu qo'llanmada biz o'rganadigan sxemani tuzishingiz kerak.

Mana u bilan bog'lanish usuli:

PB0 (raqamli pin 8) - LED - R (220 ohm) - 5V

PD0 (raqamli pin 0) - tugma - GND

Siz LEDni PB0 o'rniga GND ga ulash orqali to'g'ri yo'naltirilganligini tekshirishingiz mumkin. Hech narsa bo'lmasa, yo'nalishni o'zgartiring va yorug'lik yonishi kerak. Keyin uni PB0 ga qayta ulang va davom eting. Rasmda mening arduino paneli qanday ulanganligi ko'rsatilgan.

2 -qadam: Assambleya kodini yozish

Assambleya kodini yozish
Assambleya kodini yozish

Quyidagi kodni pushbutton.asm nomli matnli faylga yozing va 1 -darsda bo'lgani kabi avra bilan kompilyatsiya qiling.

E'tibor bering, ushbu kodda bizda ko'plab sharhlar mavjud. Har safar montajchi nuqta -vergulni ko'rsa, u chiziqning qolgan qismini o'tkazib yuboradi va keyingi qatorga o'tadi. Kelgusida unga qaytsangiz, nima qilayotganingizni bilib olish uchun o'z kodingizni izohlab berish yaxshi dasturlash amaliyotidir (ayniqsa montaj tilida!). Men nima bo'layotganini va nima uchun sodir bo'layotganini aniq bilishimiz uchun, birinchi darsliklarda men ko'p narsalarni sharhlamoqchiman. Keyinchalik, biz kodlashni biroz yaxshilaganimizdan so'ng, men narsalarni biroz batafsilroq izohlayman.

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

; muallif: 1o_o7; sana: 2014 yil 23 oktyabr; **********************************

.nolist

.include "m328Pdef.inc".list.def temp = r16; r16 ishchi reestrini temp rjmp Init sifatida belgilang; birinchi qator bajarilgan

Boshlash:

ser harorat; barcha bitlarni 1 ga sozlang. DDRB, harorat; Ma'lumotlar yo'nalishi I/U bo'yicha 1 ni biroz sozlash; DDRB bo'lgan PortB uchun ro'yxatdan o'ting; pin sifatida chiqish, 0 bu pinni kirish sifatida o'rnatadi; shuning uchun bu erda hamma PortB pinlari chiqish (1 ga o'rnatilgan) ldi temp, 0b11111110; "darhol" raqamini temp registriga yuklang; agar u faqat ld bo'lsa, ikkinchi dalil; xotira joyi bo'lishi kerak, buning o'rniga DDRD, temp; mv temp DDRD, natijada PD0 kiritiladi; qolganlari esa clr temp chiqishlari; tempdagi barcha bitlar 0 ning PortB, tempiga o'rnatiladi; PortBdagi barcha bitlarni (ya'ni pinlarni) 0V ldi temp, 0b00000001 ga o'rnating; PortD, tempni tezlashtirish uchun darhol raqamni yuklang; haroratni PortD -ga o'tkazing. PD0 tortishish qarshiligiga ega; (ya'ni 5V ga o'rnatilgan), chunki u bitda 1 ga ega; qolganlari 0dan beri 0V.

Asosiy:

haroratda, PinD; PinD PortD holatini saqlaydi, uni tempga nusxalash; agar tugma PD0 ga ulangan bo'lsa, bu shunday bo'ladi; Tugma bosilganda 0, aks holda 1; PD0 tortishish qarshiligiga ega, u odatda PortB 5V haroratda; yuqoridagi 0 va 1 ko'rsatkichlarini PortBga yuboradi; bu shuni anglatadiki, biz LEDni PB0 ga ulangan bo'lamiz; PD0 LOW bo'lsa, u PB0 ni LOW holatiga qo'yadi va aylantiradi; LEDda (LEDning boshqa tomoni 5V ga ulangan va bu PB0 ni 0V ga o'rnatadi; oqim oqadi) rjmp Asosiy; Main boshiga qaytadi

E'tibor bering, bu safar biz nafaqat o'z kodimizda ko'proq sharhlar, balki uni kim yozgani va qachon yozilgani haqida ma'lumot beradigan sarlavha bo'limiga ham egamiz. Kodning qolgan qismi ham bo'limlarga ajratilgan.

Yuqoridagi kodni tuzganingizdan so'ng, uni mikrokontrollerga yuklashingiz va uning ishlayotganini ko'rishingiz kerak. LED tugmachani bosganingizda yonishi kerak, keyin qo'yib yuborganingizda yana o'chadi. Men rasmda qanday ko'rinishini ko'rsatdim.

3-qadam: Kodni bosqichma-bosqich tahlil qilish

Men shunchaki sharhlar qatorini o'tkazib yuboraman, chunki ularning maqsadi o'z-o'zidan ravshan.

.nolist

. "m328Pdef.inc".list qo'shish

Bu uchta qatorda biz dasturlashtirayotgan ATmega328P uchun Ro'yxatdan o'tish va Bit ta'riflari bo'lgan fayl mavjud.. Nolist buyrug'i assambleyaga bu faylni siz yig'ganingizda ishlab chiqaradigan pushbutton.lst fayliga kiritmaslikni buyuradi. Bu ro'yxatga olish variantini o'chirib qo'yadi. Faylni qo'shgandan so'ng.list buyrug'i bilan ro'yxat variantini qaytadan yoqamiz. Buning sababi shundaki, m328Pdef.inc fayli juda uzun va biz uni ro'yxat faylida ko'rishga hojat yo'q. Bizning yig'uvchi, avra, avtomatik ravishda ro'yxat faylini yaratmaydi va agar xohlasak, biz quyidagi buyruq yordamida yig'amiz:

avra -l tugmachasi.lst tugmachasi.asm

Agar shunday qilsangiz, u pushbutton.lst deb nomlangan faylni yaratadi va agar siz ushbu faylni tekshirsangiz, u sizning dastur kodingizni qo'shimcha ma'lumot bilan birga ko'rsatishini ko'rasiz. Agar siz qo'shimcha ma'lumotlarga qarasangiz, satrlar C: bilan boshlanganini, so'ngra kod xotiraga joylashtirilgan o'n oltilik nisbiy manzilni ko'rasiz. Asosan u 000000 da birinchi buyruq bilan boshlanadi va har bir keyingi buyruq bilan o'sadi. Xotiradagi nisbiy joydan keyingi ikkinchi ustun - bu buyruqning o'n oltilik kodi, so'ngra buyruq argumenti uchun o'n oltilik kod. Kelgusi darslarda ro'yxat fayllarini muhokama qilamiz.

.def harorati = r16; r16 ishchi reestrini harorat sifatida belgilang

Bu satrda biz "temp" o'zgaruvchisini r16 "ishchi registri" ga teng deb belgilash uchun ".def" assembler ko'rsatmasidan foydalanamiz. Biz har xil portlar va registrlarga nusxa ko'chirmoqchi bo'lgan raqamlarni saqlaydigan r16 registrini ishlatamiz (to'g'ridan -to'g'ri yozib bo'lmaydi).

1 -mashq: Ikkilik raqamni to'g'ridan -to'g'ri portga yoki DDRB kabi maxsus registrga ko'chirishga harakat qiling va kodni yig'ishga harakat qilganingizda nima bo'lishini ko'ring.

Registrda bayt (8 bit) ma'lumot mavjud. Asosan, bu odatda SR-Latchlar to'plami bo'lib, ularning har biri "bit" dir va 1 yoki 0 ni o'z ichiga oladi. Biz buni keyinroq bu seriyada muhokama qilishimiz mumkin (va hatto bitta!). Siz "ishchi registr" nima va nima uchun r16 ni tanladik deb qiziqishingiz mumkin. Biz buni kelgusi o'quv qo'llanmasida, chipning ichki qismi botqog'iga tushganimizda muhokama qilamiz. Hozircha men sizdan kod yozish va jismoniy uskunalarni dasturlash kabi narsalarni qanday qilishni tushunishingizni istayman. Shunda sizda mikrokontrollerning xotirasi va ro'yxatga olish xususiyatlarini tushunishni osonlashtiradigan tajribadan foydalaniladi. Men tushunaman, aksariyat kirish darsliklari va munozaralar buni boshqacha tarzda amalga oshiradi, lekin men ko'rsatmalarni o'qishdan oldin global nuqtai nazarga ega bo'lish uchun video o'yinni bir muncha vaqt o'ynash, avval qo'llanmani o'qishdan ko'ra osonroq ekanligini angladim.

rjmp boshlang'ich; birinchi qator bajarilgan

Bu satr "Init" yorlig'iga "nisbiy o'tish" bo'lib, bu erda kerak emas, chunki keyingi buyruq allaqachon Init -da, lekin biz uni kelajakda ishlatish uchun qo'shamiz.

Boshlash:

ser harorat; barcha bitlarni 1 ga sozlang.

Init yorlig'idan so'ng biz "registrni o'rnatish" buyrug'ini bajaramiz. Bu "temp" registridagi 8 bitning barchasini (siz eslayotgan r16) 1 -ga o'rnatadi. Shunday qilib, temp hozirda 0b11111111 ni o'z ichiga oladi.

DDRB, harorat; Ma'lumotlar yo'nalishining kirish -chiqish registrida 1 ni biroz o'rnating

; PortB uchun, ya'ni DDRB, bu pinni chiqish sifatida o'rnatadi; 0 bu pinni kirish sifatida o'rnatadi; shuning uchun bu erda barcha PortB pinlari chiqishdir (1 ga o'rnatilgan)

DDRB reestri (PortB uchun ma'lumotlar yo'nalishi reestri) PortBdagi qaysi pinlar (ya'ni PB0 dan PB7gacha) kirish sifatida belgilanishi va chiqish sifatida ko'rsatilishini bildiradi. Bizda LEDga PB0 pin ulangan, qolganlari esa hech narsaga ulanmaganligi uchun biz barcha bitlarni 1 ga o'rnatamiz, ya'ni ularning hammasi chiqishdir.

ldi temp, 0b11111110; "darhol" raqamini temp registriga yuklang

; agar u faqat ld bo'lsa, ikkinchi dalil bo'lardi; xotira uchun joy bo'lishi kerak

Bu satr 0b11111110 ikkilik raqamini temp registriga yuklaydi.

DDRD, harorat; mv temp DDRD, natijada PD0 kirish va

; qolganlari chiqishlar

Endi biz PortD uchun Ma'lumotlar Yo'naltiruvchi Ro'yxatdan o'tish kitobini tempdan o'rnatamiz, chunki temp hali ham 0b11111110 ni o'z ichiga oladi, biz PD0 -ni kirish pimi sifatida belgilashini ko'ramiz (chunki o'ng burchakda 0), qolganlari esa chiqish sifatida belgilanadi. Bu joylarda 1 ta.

clr temp; tempdagi barcha bitlar 0 ga o'rnatiladi

PortB, temp; PortBdagi barcha bitlarni (ya'ni pinlarni) 0V ga o'rnating

Avval biz registr tempini "tozalaymiz", ya'ni barcha bitlarni nolga o'rnatamiz. Keyin biz buni PortB reestriga ko'chiramiz, u bu pinlarning barchasida 0V ni o'rnatadi. PortB bitidagi nol protsessor bu pinni 0V da ushlab turishini bildiradi, bittasi esa bu pin 5V ga o'rnatiladi.

2 -mashq: PortBdagi barcha pinlar nolga tengligini tekshirish uchun multimetrdan foydalaning. PB1 bilan g'alati narsa bormi? Nima uchun bunday bo'lishi mumkinligi haqida har qanday fikr bormi? (quyida 4 -mashqga o'xshash, keyin kodga amal qiling …) 3 -mashq: kodingizdan yuqoridagi ikkita qatorni olib tashlang. Dastur hali ham to'g'ri ishlayaptimi? Nima uchun?

ldi temp, 0b00000001; haroratga darhol raqamni yuklang

PortD, temp; haroratni PortD -ga o'tkazing. PD0 5Vda (tortish qarshiligiga ega); chunki u 1 -bitga ega, qolganlari 0V. 4 -mashq: Kodingizdan yuqoridagi ikkita qatorni olib tashlang. Dastur hali ham to'g'ri ishlayaptimi? Nima uchun? (Bu yuqoridagi 3 -mashqdan farq qiladi. Chiqish sxemasiga qarang. PD0 uchun standart DDRD sozlamasi nima? (Ma'lumotlar varag'ining 90 -betiga qarang)

Avval tempga 0b00000001 raqamini "zudlik bilan yuklaymiz". "Zudlik bilan" qismi bor, chunki biz ko'rsatgichni yuklash uchun raqamni o'z ichiga olgan xotira joyiga emas, balki tempga to'g'ri yuklaymiz. Bunday holda, biz "ldi" o'rniga "ld" dan foydalanamiz. Keyin biz bu raqamni PortD ga yuboramiz, u PD0 ni 5V ga, qolganini 0V ga o'rnatadi.

Endi biz pinlarni kirish yoki chiqish sifatida o'rnatdik va biz ularning dastlabki holatlarini 0V yoki 5V (LOW yoki HIGH) qilib o'rnatdik va endi biz o'z dasturimizga "loop" ga kiramiz.

Asosiy: haroratda, PinD; PinD PortD holatini saqlaydi, uni tempga nusxalash

; agar tugma PD0 ga ulangan bo'lsa, bu shunday bo'ladi; a tugma bosilganda 0, aks holda 1; PD0 tortishish qarshiligiga ega, odatda 5V

PinD reestri PortD pinlarining hozirgi holatini o'z ichiga oladi. Masalan, agar siz PD3 -ga 5V simni ulagan bo'lsangiz, keyingi soat tsiklida (bu bizda 16 MGts chastotali signalga ulangan mikrokontroller bo'lgani uchun sekundiga 16 million marta sodir bo'ladi) PinD3 biti (PD3ning hozirgi holatidan) 0 o'rniga 1 bo'ladi. Shunday qilib, bu satrda biz pinlarning hozirgi holatini tempga ko'chiramiz.

PortB, temp; yuqoridagi 0 va 1 ko'rsatkichlarini PortBga yuboradi

; bu shuni anglatadiki, biz LEDni PB0 ga ulashni xohlaymiz, shuning uchun; PD0 LOW bo'lsa, u PB0 ni LOW holatiga qo'yadi va aylanadi; LEDda (LEDning boshqa tomoni 5V ga ulangan va bu PB0 ni 0V ga o'rnatadi, shuning uchun oqim oqadi)

Endi biz PinD -dagi pinlarning holatini PortB chiqishiga yuboramiz. Bu shuni anglatadiki, agar tugma bosilmasa PD0 1 PortD0 ga yuboradi. Bunday holda, tugma erga ulanganligi sababli, pin 0V bo'ladi va u PortB0 ga 0 yuboradi. Endi, agar siz sxemaga qarasangiz, PB0da 0V LED yonadi, chunki uning boshqa tomoni 5V. Agar biz tugmachani bosmasak, PB0 ga 1 yuborilsa, bu bizda PB0da 5V, shuningdek LEDning boshqa tomonida 5V bo'ladi va shuning uchun potentsial farq yo'q va oqim oqmaydi va shuning uchun LED yonmaydi (bu holda bu diodli LED, shuning uchun oqim faqat bir yo'nalishda oqadi).

rjmp Asosiy; Boshlang'ichga qaytadi

Bu nisbiy sakrash bizni Asosiy: yorliqqa qaytaradi va biz yana PinDni tekshiramiz va hokazo. Tugma bosiladimi yoki yo'qligini har 16 milliondan bir soniyada tekshirish va shunga mos ravishda PB0 ni sozlash.

5 -mashq: O'zingizning kodingizni LEDni PB0 o'rniga PB3 ga ulangan holda o'zgartiring va uning ishlashini ko'ring. 6 -mashq: LEDni 5V o'rniga GND ga ulang va shunga mos ravishda kodingizni o'zgartiring.

4 -qadam: Xulosa

Ushbu qo'llanmada biz ATmega328p uchun yig'ish tilini batafsil o'rganib chiqdik va LEDni tugma bilan boshqarishni o'rgandik. Xususan, biz quyidagi buyruqlarni o'rgandik:

ser register registrning barcha bitlarini 1 ga o'rnatadi

clr register registrning barcha bitlarini 0 ga o'rnatadi

ro'yxatga olish kitobida kirish -chiqish registri raqamni kirish -chiqish registridan ishchi registrga ko'chiradi

Keyingi o'quv qo'llanmada biz ATmega328p tuzilishini va undagi turli registrlar, operatsiyalar va resurslarni ko'rib chiqamiz.

Bu darsliklarni davom ettirishdan oldin men kutaman va qiziqish darajasini ko'raman. Agar assotsiatsiya tilida ushbu mikroprotsessor uchun dasturlarni kodlashni o'rganishni yoqtiradigan odamlar ko'p bo'lsa, men davom etaman va murakkabroq sxemalarni tuzaman va mustahkam koddan foydalanaman.

Tavsiya: