Isi kandungan:

Tutorial Penyusun AVR 2: 4 Langkah
Tutorial Penyusun AVR 2: 4 Langkah

Video: Tutorial Penyusun AVR 2: 4 Langkah

Video: Tutorial Penyusun AVR 2: 4 Langkah
Video: How to Change your Generator's Voltage Regulator (AVR) 2024, Julai
Anonim
Tutorial Penyusun AVR 2
Tutorial Penyusun AVR 2

Tutorial ini adalah kesinambungan dari "AVR Assembler Tutorial 1"

Sekiranya anda belum mengikuti Tutorial 1, anda harus berhenti sekarang dan melakukannya terlebih dahulu.

Dalam tutorial ini, kami akan meneruskan kajian pengaturcaraan bahasa pemasangan atmega328p yang digunakan di Arduino.

Anda perlu:

  1. papan roti Arduino atau hanya Arduino biasa seperti dalam Tutorial 1
  2. LED
  3. perintang 220 ohm
  4. butang tekan
  5. menyambung wayar untuk membuat litar di papan roti anda
  6. Manual Set Instuction: www.atmel.com/images/atmel-0856-avr-instruction-s…
  7. Lembar Data: www.atmel.com/images/Atmel-8271-8-bit-AVR-Microco…

Koleksi lengkap tutorial saya boleh didapati di sini:

Langkah 1: Membina Litar

Membina Litar
Membina Litar

Mula-mula anda perlu membina litar yang akan kita pelajari dalam tutorial ini.

Inilah cara penyambungannya:

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

PD0 (pin digital 0) - butang tekan - GND

Anda boleh memastikan bahawa LED anda berorientasikan dengan betul dengan menyambungkannya ke GND dan bukannya PB0. Sekiranya tidak ada yang berlaku, ubah arah dan arah cahaya harus menyala. Kemudian sambungkan semula ke PB0 dan teruskan. Gambar menunjukkan bagaimana arduino papan roti saya disambungkan.

Langkah 2: Menulis Kod Perhimpunan

Menulis Kod Perhimpunan
Menulis Kod Perhimpunan

Tuliskan kod berikut dalam fail teks yang disebut pushbutton.asm dan susun dengan avra seperti yang anda lakukan di Tutorial 1.

Perhatikan bahawa dalam kod ini kita mempunyai banyak komen. Setiap kali penghimpun melihat titik koma, ia akan melewati baris yang lain dan terus ke baris seterusnya. Merupakan amalan pengaturcaraan yang baik (terutama dalam bahasa pemasangan!) Untuk banyak mengulas kod anda sehingga apabila anda kembali menggunakannya pada masa akan datang, anda akan mengetahui apa yang anda lakukan. Saya akan mengulas banyak perkara dalam beberapa tutorial pertama supaya kita tahu dengan tepat apa yang berlaku dan mengapa. Kemudian, setelah kita menjadi lebih baik dalam pengkodan pemasangan, saya akan mengulas perkara dengan lebih terperinci.

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

; ditulis oleh: 1o_o7; tarikh: 23 Okt 2014; ************************************

.nolist

.masuk "m328Pdef.inc".list.def temp = r16; tentukan daftar kerja r16 sebagai temp rjmp Init; baris pertama dilaksanakan

Di dalamnya:

ser temp; tetapkan semua bit dalam temp ke 1's. keluar DDRB, temp; menetapkan sedikit sebanyak 1 pada Data / Direction I / O; mendaftar untuk PortB, yang merupakan DDRB, menetapkan bahawa; pin sebagai output, 0 akan menetapkan pin itu sebagai input; jadi di sini, semua pin PortB adalah output (set ke 1) ldi temp, 0b11111110; memuatkan nombor `segera 'ke daftar temp; sekiranya ia hanya hujah kedua; harus menjadi lokasi memori dan bukannya DDRD, temp; temp mv ke DDRD, hasilnya ialah PD0 adalah input; dan selebihnya adalah output clr temp; semua bit dalam temp diset ke PortB 0, temp; tetapkan semua bit (iaitu pin) di PortB ke suhu 0V ldi, 0b00000001; memuatkan nombor segera untuk keluar PortD, temp; pindahkan temp ke PortD. PD0 mempunyai perintang penarik; (iaitu ditetapkan ke 5V) kerana ia mempunyai 1 dalam bit itu; selebihnya 0V sejak 0-an.

Utama:

dalam temp, PinD; PinD memegang keadaan PortD, salin ini ke temp; jika butang disambungkan ke PD0 ini akan menjadi; 0 apabila butang ditekan, 1 sebaliknya kerana; PD0 mempunyai resistor tarik ke atas biasanya pada 5B keluar PortB, temp; menghantar bacaan 0 dan 1 di atas ke PortB; ini bermaksud kita mahu LED disambungkan ke PB0,; apabila PD0 RENDAH, ia menetapkan PB0 menjadi RENDAH dan bertukar; pada LED (kerana sisi lain LED; disambungkan ke 5V dan ini akan menetapkan PB0 hingga 0V jadi; arus akan mengalir) rjmp Utama; gelung kembali ke permulaan Utama

Perhatikan bahawa kali ini kita tidak hanya mempunyai lebih banyak komen dalam kod kita, tetapi kita juga mempunyai bahagian tajuk yang memberikan beberapa maklumat mengenai siapa yang menulisnya dan kapan ia ditulis. Selebihnya kod juga dipisahkan menjadi beberapa bahagian.

Selepas anda menyusun kod di atas, anda harus memasukkannya ke mikrokontroler dan melihatnya berfungsi. LED harus menyala semasa anda menekan butang dan kemudian mematikan semula apabila anda melepaskannya. Saya telah menunjukkan seperti apa dalam gambar.

Langkah 3: Analisis Kod demi baris Kod

Saya akan melangkau garis-garis yang hanya komen kerana tujuannya jelas.

.nolist

.masuk senarai "m328Pdef.inc"

Ketiga baris ini merangkumi fail yang mengandungi definisi Daftar dan Bit untuk ATmega328P yang sedang kami atur. Perintah.nolist memberitahu assembler untuk tidak memasukkan fail ini dalam fail pushbutton.lst yang dihasilkannya semasa anda memasangnya. Ia mematikan pilihan penyenaraian. Setelah memasukkan fail, kami menghidupkan kembali pilihan penyenaraian dengan arahan.list. Sebab kami melakukan ini adalah kerana fail m328Pdef.inc cukup panjang dan kami tidak perlu melihatnya dalam fail senarai. Penyusun kami, avra, tidak menghasilkan fail senarai secara automatik dan jika kami menginginkannya, kami akan mengumpulkannya menggunakan perintah berikut:

avra -l pushbutton.lst pushbutton.asm

Sekiranya anda melakukannya, ia akan menghasilkan fail yang dipanggil pushbutton.lst dan jika anda memeriksa fail ini, anda akan mendapati bahawa ia menunjukkan kod program anda bersama dengan maklumat tambahan. Sekiranya anda melihat maklumat tambahan, anda akan melihat bahawa garis bermula dengan huruf C: diikuti dengan alamat relatif dalam hex di mana kod tersebut diletakkan dalam memori. Pada dasarnya ia bermula pada 000000 dengan perintah pertama dan meningkat dari sana dengan setiap arahan berikutnya. Lajur kedua setelah tempat relatif dalam memori adalah kod hex untuk perintah diikuti oleh kod hex untuk argumen perintah. Kami akan membincangkan fail senarai lebih lanjut dalam tutorial akan datang.

.def temp = r16; tentukan daftar kerja r16 sebagai temp

Pada baris ini kita menggunakan arahan assembler ".def" untuk menentukan pemboleh ubah "temp" sama dengan r16 "register kerja." Kami akan menggunakan register r16 sebagai yang menyimpan nombor yang ingin kami salin ke pelbagai port dan register (yang tidak boleh ditulis secara langsung).

Latihan 1: Cuba salin nombor perduaan terus ke port atau daftar khas seperti DDRB dan lihat apa yang berlaku semasa anda cuba mengumpulkan kod tersebut.

Daftar mengandungi bait (8 bit) maklumat. Pada dasarnya ia adalah koleksi SR-Latches masing-masing adalah "bit" dan mengandungi 1 atau 0. Kami mungkin membincangkan ini (dan bahkan membina satu!) Nanti dalam siri ini. Anda mungkin tertanya-tanya apa itu "daftar kerja" dan mengapa kami memilih r16. Kami akan membincangkannya dalam tutorial yang akan datang ketika kami menyelami inti cip. Buat masa ini saya ingin anda memahami bagaimana melakukan perkara seperti menulis kod dan memprogramkan perkakasan fizikal. Maka anda akan mempunyai kerangka rujukan dari pengalaman itu yang akan menjadikan memori dan sifat pendaftaran mikrokontroler lebih mudah difahami. Saya menyedari bahawa kebanyakan buku teks dan perbincangan memperkenalkan ini sebaliknya tetapi saya mendapati bahawa bermain permainan video untuk sementara waktu untuk mendapatkan perspektif global sebelum membaca manual arahan jauh lebih mudah daripada membaca manual terlebih dahulu.

rjmp Init; baris pertama dilaksanakan

Garis ini adalah "lompatan relatif" ke label "Init" dan tidak semestinya diperlukan di sini kerana arahan seterusnya sudah ada di Init tetapi kami memasukkannya untuk kegunaan masa depan.

Di dalamnya:

ser temp; tetapkan semua bit dalam temp ke 1's.

Setelah label Init kita menjalankan perintah "set register". Ini menetapkan semua 8 bit dalam "temp" register (yang anda ingat adalah r16) hingga 1. Jadi temp sekarang mengandungi 0b11111111.

keluar DDRB, temp; menetapkan sedikit sebanyak 1 pada daftar Data / Direction I / O

; untuk PortB, yang merupakan DDRB, menetapkan pin itu sebagai output; a 0 akan menetapkan pin itu sebagai input; jadi di sini, semua pin PortB adalah output (set ke 1)

Daftar DDRB (Data Direction Register for PortB) memberitahu pin mana di PortB (iaitu PB0 hingga PB7) ditetapkan sebagai input dan yang ditetapkan sebagai output. Oleh kerana kami mempunyai pin PB0 yang disambungkan ke LED kami dan selebihnya tidak disambungkan ke apa-apa, kami akan menetapkan semua bit ke 1 yang bermaksud semuanya adalah output.

ldi temp, 0b11111110; muatkan nombor `segera 'ke daftar temp

; jika ia hanya maka hujah kedua akan; mesti menjadi lokasi ingatan

Garis ini memuatkan nombor binari 0b11111110 ke dalam daftar temp.

keluar DDRD, temp; mv temp to DDRD, hasilnya PD0 adalah input dan

; selebihnya adalah output

Sekarang kita menetapkan Daftar Arah Data untuk PortD dari temp, kerana temp masih berisi 0b11111110 kita melihat bahawa PD0 akan ditetapkan sebagai pin input (kerana ada 0 di tempat paling kanan) dan selebihnya ditetapkan sebagai output kerana ada 1 di tempat-tempat itu.

clr temp; semua bit dalam temp ditetapkan pada 0

keluar PortB, temp; tetapkan semua bit (iaitu pin) di PortB ke 0V

Mula-mula kita "membersihkan" suhu register yang bermaksud menetapkan semua bit ke sifar. Kemudian kami menyalinnya ke daftar PortB yang menetapkan 0V pada semua pin tersebut. Nol pada bit PortB bermaksud bahawa pemproses akan menyimpan pin itu pada 0V, satu pada bit akan menyebabkan pin itu ditetapkan ke 5V.

Latihan 2: Gunakan multimeter untuk memeriksa sama ada semua pin di PortB sebenarnya sifar. Adakah sesuatu yang pelik berlaku dengan PB1? Ada idea mengapa itu berlaku? (serupa dengan Latihan 4 di bawah, kemudian ikuti kodnya …) Latihan 3: Keluarkan dua baris di atas dari kod anda. Adakah program masih berjalan dengan betul? Kenapa?

ldi temp, 0b00000001; muatkan nombor segera ke temp

keluar PortD, temp; pindahkan temp ke PortD. PD0 berada pada 5V (mempunyai perintang penarik); kerana ia mempunyai 1 dalam bit itu selebihnya adalah 0V. Latihan 4: Keluarkan dua baris di atas dari kod anda. Adakah program masih berjalan dengan betul? Kenapa? (Ini berbeza dengan Latihan 3 di atas. Lihat gambarajah pin out. Apakah tetapan DDRD lalai untuk PD0? (Lihat halaman 90 lembaran data

Mula-mula kita "memuat segera" nombor 0b00000001 ke temp. Bahagian "segera" ada kerana kita memuatkan angka lurus ke temp dan bukannya penunjuk ke lokasi memori yang mengandungi nombor untuk dimuat. Sekiranya kita hanya menggunakan "ld" dan bukan "ldi". Kemudian kami menghantar nombor ini ke PortD yang menetapkan PD0 hingga 5V dan selebihnya menjadi 0V.

Sekarang kami telah menetapkan pin sebagai input atau output dan kami telah menetapkan keadaan awalnya sebagai 0V atau 5V (RENDAH atau TINGGI) dan oleh itu kami memasuki program "loop" kami.

Utama: dalam temp, PinD; PinD memegang keadaan PortD, salin ini ke suhu

; jika butang disambungkan ke PD0 maka ini akan menjadi; a 0 apabila butang ditekan, 1 sebaliknya kerana; PD0 mempunyai resistor pull up biasanya pada 5V

PinD daftar mengandungi keadaan pin PortD terkini. Sebagai contoh, jika anda memasang wayar 5V ke PD3, maka pada kitaran jam seterusnya (yang berlaku 16 juta kali sesaat kerana kita mempunyai mikrokontroler yang disambungkan hingga isyarat jam 16MHz) bit PinD3 (dari keadaan semasa PD3) akan menjadi 1 dan bukannya 0. Oleh itu, dalam baris ini kita menyalin keadaan pin semasa ke temp.

keluar PortB, temp; menghantar bacaan 0 dan 1 di atas ke PortB

; ini bermaksud kita mahu LED disambungkan ke PB0, jadi; apabila PD0 RENDAH, ia akan menetapkan PB0 ke RENDAH dan bertukar; pada LED (sebelah lain LED disambungkan; ke 5V dan ini akan menetapkan PB0 hingga 0V sehingga arus mengalir)

Sekarang kita menghantar keadaan pin dalam PinD ke output PortB. Berkesan, ini bermaksud PD0 akan menghantar 1 ke PortD0 kecuali butang ditekan. Sekiranya butang disambungkan ke tanah pin itu akan berada pada 0V dan ia akan menghantar 0 ke PortB0. Sekarang, jika anda melihat gambarajah litar, 0V pada PB0 bermaksud LED akan menyala kerana sisi lain berada pada 5V. Sekiranya kita tidak menekan butang, sehingga 1 dikirim ke PB0, itu berarti kita mempunyai 5V pada PB0 dan juga 5V di sisi lain LED dan oleh itu tidak ada perbezaan potensi dan arus tidak akan mengalir dan LED tidak akan menyala (dalam kes ini adalah LED yang merupakan dioda dan arus hanya mengalir satu arah tanpa mengira apa pun).

rjmp Utama; gelung kembali ke Mula

Lompatan relatif ini mengembalikan kami ke label Utama: kami dan kami menyemak PinD sekali lagi dan seterusnya. Memeriksa setiap 16 juta detik sama ada butang ditekan dan menetapkan PB0 dengan sewajarnya.

Latihan 5: Ubah kod anda supaya LED anda disambungkan ke PB3 dan bukannya PB0 dan lihat ia berfungsi. Latihan 6: Pasangkan LED anda ke GND dan bukannya 5V dan ubah kod anda dengan sewajarnya.

Langkah 4: Kesimpulannya

Dalam tutorial ini, kami telah menyelidiki lebih lanjut bahasa pemasangan untuk ATmega328p dan belajar bagaimana mengawal LED dengan butang tekan. Secara khusus kami mempelajari arahan berikut:

ser register menetapkan semua bit register menjadi 1's

clr register menetapkan semua bit register ke 0's

dalam daftar, daftar i / o menyalin nombor dari daftar i / o ke daftar yang berfungsi

Dalam tutorial seterusnya kita akan memeriksa struktur ATmega328p dan pelbagai daftar, operasi, dan sumber yang terdapat di dalamnya.

Sebelum saya meneruskan tutorial ini, saya akan menunggu dan melihat tahap minatnya. Sekiranya terdapat sebilangan orang yang benar-benar menikmati belajar bagaimana membuat kod program untuk mikropemproses ini dalam bahasa pemasangan maka saya akan meneruskan dan membina litar yang lebih rumit dan menggunakan kod yang lebih mantap.

Disyorkan: