Daftar Isi:
- Langkah 1: Membangun Sirkuit
- Langkah 2: Menulis Kode Majelis
- Langkah 3: Analisis Kode Baris demi Baris
- Langkah 4: Kesimpulan
Video: Tutorial Perakitan AVR 2: 4 Langkah
2024 Pengarang: John Day | [email protected]. Terakhir diubah: 2024-01-30 09:53
Tutorial ini merupakan lanjutan dari "Tutorial AVR Assembler 1"
Jika Anda belum melalui Tutorial 1 Anda harus berhenti sekarang dan melakukan yang pertama.
Dalam tutorial ini kita akan melanjutkan studi kita tentang pemrograman bahasa assembly dari atmega328p yang digunakan di Arduino.
Anda akan perlu:
- Arduino papan tempat memotong roti atau hanya Arduino biasa seperti pada Tutorial 1
- sebuah LED
- resistor 220 ohm
- tombol tekan
- menghubungkan kabel untuk membuat sirkuit di papan tempat memotong roti Anda
- Manual Set Instruksi: www.atmel.com/images/atmel-0856-avr-instruction-s…
- Lembar Data: www.atmel.com/images/Atmel-8271-8-bit-AVR-Microco…
Koleksi lengkap tutorial saya dapat ditemukan di sini:
Langkah 1: Membangun Sirkuit
Pertama, Anda perlu membangun sirkuit yang akan kita pelajari dalam tutorial ini.
Berikut adalah cara terhubung:
PB0 (pin digital 8) - LED - R (220 ohm) - 5V
PD0 (pin digital 0) - tombol tekan - GND
Anda dapat memeriksa apakah LED Anda diorientasikan dengan benar dengan menghubungkannya ke GND, bukan PB0. Jika tidak ada yang terjadi maka balikkan orientasi dan lampu akan menyala. Kemudian sambungkan kembali ke PB0 dan lanjutkan. Gambar menunjukkan bagaimana arduino papan tempat memotong roti saya terhubung.
Langkah 2: Menulis Kode Majelis
Tulis kode berikut dalam file teks bernama pushbutton.asm dan kompilasi dengan avra seperti yang Anda lakukan di Tutorial 1.
Perhatikan bahwa dalam kode ini kami memiliki banyak komentar. Setiap kali assembler melihat titik koma, ia akan melewati sisa baris dan melanjutkan ke baris berikutnya. Ini adalah praktik pemrograman yang baik (terutama dalam bahasa assembly!) untuk banyak mengomentari kode Anda sehingga ketika Anda kembali ke sana di masa depan Anda akan tahu apa yang Anda lakukan. Saya akan banyak berkomentar di beberapa tutorial pertama sehingga kita tahu persis apa yang sedang terjadi dan mengapa. Nanti, setelah kita menjadi sedikit lebih baik dalam pengkodean perakitan, saya akan mengomentari hal-hal dengan sedikit kurang detail.
;************************************
; ditulis oleh: 1o_o7; tanggal: 23 Oktober 2014;************************************
.nolist
.include "m328Pdef.inc".list.def temp = r16; tunjuk register kerja r16 sebagai temp rjmp Init; baris pertama dieksekusi
init:
suhu ser; atur semua bit dalam temp ke 1. keluar DDRB, suhu; pengaturan sedikit sebagai 1 pada Data Direction I/O; register untuk PortB, yaitu DDRB, menetapkan bahwa; pin sebagai output, 0 akan mengatur pin itu sebagai input; jadi di sini, semua pin PortB adalah output (diatur ke 1) ldi temp, 0b11111110; memuat nomor 'langsung' ke register sementara; jika hanya ld maka argumen kedua; harus menjadi lokasi memori alih-alih keluar DDRD, temp; mv temp ke DDRD, hasilnya adalah PD0 adalah input; dan sisanya adalah output clr temp; semua bit dalam temp diatur ke 0's out PortB, temp; atur semua bit (yaitu pin) di PortB ke 0V ldi temp, 0b00000001; memuat nomor langsung ke temp out PortD, temp; pindahkan suhu ke PortD. PD0 memiliki resistor pull up; (yaitu diatur ke 5V) karena memiliki 1 di bit itu; sisanya adalah 0V sejak 0's.
Utama:
dalam suhu, PinD; PinD memegang status PortD, salin ini ke temp; jika tombol terhubung ke PD0 ini akan menjadi; 0 saat tombol ditekan, 1 jika tidak karena; PD0 memiliki resistor pull up biasanya pada 5V out PortB, temp; mengirimkan pembacaan 0 dan 1 di atas ke PortB; ini berarti kita ingin LED terhubung ke PB0,; ketika PD0 RENDAH, ia menetapkan PB0 ke RENDAH dan berubah; pada LED (karena sisi lain dari LED; terhubung ke 5V dan ini akan mengatur PB0 ke 0V jadi; arus akan mengalir) rjmp Main; loop kembali ke awal Main
Perhatikan bahwa kali ini kami tidak hanya memiliki lebih banyak komentar dalam kode kami, tetapi kami juga memiliki bagian header yang memberikan beberapa informasi tentang siapa yang menulisnya dan kapan ditulis. Sisa kode juga dipisahkan menjadi beberapa bagian.
Setelah Anda mengkompilasi kode di atas, Anda harus memuatnya ke mikrokontroler dan melihatnya berfungsi. LED akan menyala saat Anda menekan tombol dan kemudian mati lagi saat Anda melepaskannya. Saya telah menunjukkan apa yang tampak seperti dalam gambar.
Langkah 3: Analisis Kode Baris demi Baris
Saya akan melewatkan baris yang hanya berupa komentar karena tujuannya sudah jelas.
.nolist
.termasuk "m328Pdef.inc".list
Tiga baris ini termasuk file yang berisi definisi Register dan Bit untuk ATmega328P yang sedang kita program. Perintah.nolist memberitahu assembler untuk tidak menyertakan file ini dalam file pushbutton.lst yang dihasilkannya saat Anda merakitnya. Ini mematikan opsi daftar. Setelah memasukkan file, kami mengaktifkan kembali opsi daftar dengan perintah.list. Alasan kami melakukan ini adalah karena file m328Pdef.inc cukup panjang dan kami tidak perlu melihatnya di file daftar. Assembler kami, avra, tidak secara otomatis menghasilkan file daftar dan jika kami menginginkannya, kami akan merakit menggunakan perintah berikut:
avra -l pushbutton.lst pushbutton.asm
Jika Anda melakukan ini, itu akan menghasilkan file bernama pushbutton.lst dan jika Anda memeriksa file ini, Anda akan menemukan bahwa itu menunjukkan kode program Anda bersama dengan informasi tambahan. Jika Anda melihat informasi tambahan, Anda akan melihat bahwa baris dimulai dengan C: diikuti dengan alamat relatif dalam hex tempat kode ditempatkan di memori. Pada dasarnya itu dimulai pada 000000 dengan perintah pertama dan meningkat dari sana dengan setiap perintah berikutnya. Kolom kedua setelah tempat relatif dalam memori adalah kode hex untuk perintah diikuti oleh kode hex untuk argumen perintah. Kami akan membahas file daftar lebih lanjut di tutorial mendatang.
.def suhu = r16; tentukan register kerja r16 sebagai temp
Pada baris ini kita menggunakan direktif assembler ".def" untuk mendefinisikan variabel "temp" sama dengan "register kerja" r16. Kami akan menggunakan register r16 sebagai yang menyimpan nomor yang ingin kami salin ke berbagai port dan register (yang tidak dapat ditulis langsung).
Latihan 1: Coba salin bilangan biner langsung ke port atau register khusus seperti DDRB dan lihat apa yang terjadi ketika Anda mencoba merakit kode.
Register berisi satu byte (8 bit) informasi. Pada dasarnya biasanya kumpulan SR-Latches masing-masing adalah "sedikit" dan berisi 1 atau 0. Kita dapat mendiskusikan ini (dan bahkan membangun satu!) nanti dalam seri ini. Anda mungkin bertanya-tanya apa itu "register kerja" dan mengapa kami memilih r16. Kita akan membahasnya di tutorial mendatang saat kita menyelami rawa internal chip. Untuk saat ini saya ingin Anda memahami bagaimana melakukan hal-hal seperti menulis kode dan memprogram perangkat keras fisik. Kemudian Anda akan memiliki kerangka acuan dari pengalaman itu yang akan membuat memori dan register properti mikrokontroler lebih mudah dipahami. Saya menyadari bahwa sebagian besar buku teks pengantar dan diskusi melakukan ini sebaliknya tetapi saya telah menemukan bahwa bermain video game untuk sementara waktu terlebih dahulu untuk mendapatkan perspektif global sebelum membaca manual instruksi jauh lebih mudah daripada membaca manual terlebih dahulu.
rjmp Init; baris pertama dieksekusi
Baris ini adalah "lompatan relatif" ke label "Init" dan tidak terlalu diperlukan di sini karena perintah berikutnya sudah ada di Init tetapi kami menyertakannya untuk penggunaan di masa mendatang.
init:
suhu ser; atur semua bit dalam temp ke 1.
Setelah label Init kita menjalankan perintah "set register". Ini menetapkan semua 8 bit dalam register "temp" (yang Anda ingat adalah r16) menjadi 1. Jadi temp sekarang berisi 0b11111111.
keluar DDRB, suhu; pengaturan sedikit sebagai 1 pada register I/O Arah Data
; untuk PortB, yaitu DDRB, menetapkan pin tersebut sebagai output; a 0 akan menetapkan pin itu sebagai input; jadi di sini, semua pin PortB adalah output (diatur ke 1)
Register DDRB (Data Direction Register for PortB) memberi tahu pin mana pada PortB (yaitu PB0 hingga PB7) yang ditetapkan sebagai input dan mana yang ditetapkan sebagai output. Karena kami memiliki pin PB0 yang terhubung ke LED kami dan sisanya tidak terhubung ke apa pun, kami akan mengatur semua bit menjadi 1 yang berarti semuanya adalah output.
suhu ldi, 0b11111110; memuat nomor 'langsung' ke register temp
; jika hanya ld maka argumen kedua akan; harus menjadi lokasi memori
Baris ini memuat bilangan biner 0b11111110 ke dalam register temp.
keluar DDRD, suhu; mv temp ke DDRD, hasilnya adalah PD0 adalah input dan
; sisanya adalah output
Sekarang kita atur Data Direction Register untuk PortD dari temp, karena temp masih berisi 0b11111110 kita melihat bahwa PD0 akan ditunjuk sebagai pin input (karena ada 0 di tempat paling kanan) dan sisanya ditunjuk sebagai output karena ada 1 di tempat-tempat itu.
suhu clr; semua bit dalam temp diatur ke 0's
keluar PortB, suhu; atur semua bit (yaitu pin) di PortB ke 0V
Pertama kita "menghapus" register temp yang berarti mengatur semua bit ke nol. Kemudian kita salin ke register PortB yang menetapkan 0V pada semua pin tersebut. Sebuah nol pada bit PortB berarti bahwa prosesor akan menjaga pin itu pada 0V, satu pada sedikit akan menyebabkan pin itu disetel ke 5V.
Latihan 2: Gunakan multimeter untuk memeriksa apakah semua pin pada PortB benar-benar nol. Apakah sesuatu yang aneh terjadi dengan PB1? Adakah ide mengapa itu bisa terjadi? (mirip dengan Latihan 4 di bawah lalu ikuti kodenya…)Latihan 3: Hapus dua baris di atas dari kode Anda. Apakah program masih berjalan dengan benar? Mengapa?
suhu ldi, 0b00000001; memuat nomor langsung ke temp
keluar PortD, suhu; pindahkan suhu ke PortD. PD0 berada pada 5V (memiliki resistor pullup); karena memiliki 1 di bit sisanya adalah 0V. Latihan 4: Hapus dua baris di atas dari kode Anda. Apakah program masih berjalan dengan benar? Mengapa? (Ini berbeda dengan Latihan 3 di atas. Lihat diagram pin out. Apa pengaturan default DDRD untuk PD0? (Lihat halaman 90 dari lembar data
Pertama kita "memuat segera" nomor 0b00000001 ke temp. Bagian "segera" ada di sana karena kami memuat angka lurus ke atas ke temp daripada penunjuk ke lokasi memori yang berisi nomor yang akan dimuat. Dalam hal ini kita hanya akan menggunakan "ld" daripada "ldi". Kemudian kami mengirimkan nomor ini ke PortD yang menetapkan PD0 ke 5V dan sisanya ke 0V.
Sekarang kita telah mengatur pin sebagai input atau output dan kita telah mengatur status awalnya sebagai 0V atau 5V (RENDAH atau TINGGI) dan sekarang kita memasuki program "loop".
Utama: dalam suhu, PinD; PinD memegang status PortD, salin ini ke temp
; jika tombol terhubung ke PD0 maka ini akan menjadi; a 0 saat tombol ditekan, 1 jika tidak karena; PD0 memiliki resistor pull up biasanya pada 5V
Register PinD berisi status pin PortD saat ini. Misalnya, jika Anda memasang kabel 5V ke PD3, maka pada siklus clock berikutnya (yang terjadi 16 juta kali per detik karena mikrokontroler terhubung ke sinyal clock 16MHz), bit PinD3 (dari status PD3) saat ini akan menjadi 1 bukannya 0. Jadi di baris ini kita menyalin status pin saat ini ke temp.
keluar PortB, suhu; mengirimkan pembacaan 0 dan 1 di atas ke PortB
; ini berarti kita ingin LED terhubung ke PB0, jadi; ketika PD0 RENDAH, itu akan mengatur PB0 ke RENDAH dan berubah; pada LED (sisi lain LED terhubung; ke 5V dan ini akan mengatur PB0 ke 0V sehingga arus mengalir)
Sekarang kami mengirim status pin di PinD ke output PortB. Secara efektif, ini berarti bahwa PD0 akan mengirim 1 ke PortD0 kecuali tombol ditekan. Dalam hal ini karena tombol terhubung ke ground, pin akan berada di 0V dan akan mengirim 0 ke PortB0. Sekarang, jika Anda melihat diagram rangkaian, 0V pada PB0 berarti LED akan menyala karena sisi lain berada pada 5V. Jika kita tidak menekan tombol, sehingga 1 dikirim ke PB0, itu berarti kita memiliki 5V pada PB0 dan juga 5V di sisi lain dari LED sehingga tidak ada beda potensial dan tidak ada arus yang akan mengalir sehingga LED tidak akan menyala (dalam hal ini adalah LED yang merupakan dioda dan arus hanya mengalir satu arah terlepas tetapi apa pun).
rjmp Utama; loop kembali ke Mulai
Lompatan relatif ini membuat kita kembali ke label Main: dan kita memeriksa PinD lagi dan seterusnya. Memeriksa setiap 16 juta detik apakah tombol sedang ditekan dan mengatur PB0 yang sesuai.
Latihan 5: Ubah kode Anda sehingga LED Anda terhubung ke PB3 alih-alih PB0 dan lihat apakah itu berfungsi. Latihan 6: Pasang LED Anda ke GND alih-alih 5V dan ubah kode Anda sesuai dengan itu.
Langkah 4: Kesimpulan
Dalam tutorial ini kita telah menyelidiki lebih lanjut bahasa rakitan untuk ATmega328p dan mempelajari cara mengontrol LED dengan tombol tekan. Secara khusus kami mempelajari perintah berikut:
register ser menyetel semua bit register ke 1's
clr register menyetel semua bit register ke 0's
dalam register, register i/o menyalin nomor dari register i/o ke register yang berfungsi
Dalam tutorial berikutnya kita akan memeriksa struktur ATmega328p dan berbagai register, operasi, dan sumber daya yang terkandung di dalamnya.
Sebelum saya melanjutkan tutorial ini, saya akan menunggu dan melihat tingkat minat. Jika ada beberapa orang yang benar-benar menikmati belajar bagaimana kode program untuk mikroprosesor ini dalam bahasa rakitan maka saya akan melanjutkan dan membangun sirkuit yang lebih rumit dan menggunakan kode yang lebih kuat.
Direkomendasikan:
Tutorial Perakitan AVR 1: 5 Langkah
Tutorial Assembler AVR 1: Saya telah memutuskan untuk menulis serangkaian tutorial tentang cara menulis program bahasa assembly untuk Atmega328p yang merupakan mikrokontroler yang digunakan di Arduino. Jika orang tetap tertarik, saya akan terus mengeluarkannya seminggu atau lebih sampai saya kehabisan
Tutorial Perakitan AVR 6: 3 Langkah
Tutorial AVR Assembler 6: Selamat Datang di Tutorial 6! Tutorial hari ini akan singkat dimana kita akan mengembangkan metode sederhana untuk mengkomunikasikan data antara satu atmega328p dan lainnya menggunakan dua port yang menghubungkannya. Kami kemudian akan mengambil roller dadu dari Tutorial 4 dan Daftar
Tutorial Perakitan AVR 8: 4 Langkah
AVR Assembler Tutorial 8: Selamat Datang di Tutorial 8! Dalam tutorial singkat ini kita akan mengambil sedikit pengalihan dari memperkenalkan aspek-aspek baru dari pemrograman bahasa assembly untuk menunjukkan bagaimana memindahkan komponen prototyping kita ke "cetak" yang terpisah. papan sirkuit. NS
Tutorial Perakitan AVR 7: 12 Langkah
AVR Assembler Tutorial 7: Selamat Datang di Tutorial 7! Hari ini kita akan menunjukkan cara mengais keypad, dan kemudian menunjukkan cara menggunakan port input Analog untuk berkomunikasi dengan keypad. Kita akan melakukan ini menggunakan interupsi dan kabel tunggal sebagai memasukkan. Kami akan menyambungkan keypad agar
Tutorial Perakitan AVR 9: 7 Langkah
Tutorial Perakitan AVR 9: Selamat Datang di Tutorial 9.Hari ini kami akan menunjukkan cara mengontrol tampilan 7-segmen dan tampilan 4-digit menggunakan kode bahasa rakitan ATmega328P dan AVR kami. Dalam melakukan ini, kita harus mengambil pengalihan tentang cara menggunakan tumpukan