Running LED Program – A Walk Through


Pada tulisan VMLAB – Running LED, tidak ada penjelasan khusus tentang program assemblernya. Nah, pada tulisan ini akan dibahas secara mendetail (semampu saya) mengenai program Running LED pada tulisan tersebut.

; **********************************
; LED1.ASM
; Program Running LED Example
; Microcontroller: ATmega8
; Output: 8 Common-Anode LEDs on PORTB0..PORTB7
; **********************************

.include “C:\Microcontrollers\VMLAB\include\m8def.inc”

Enam baris awal program hanyalah komentar yang berisi nama file program dan sekelumit deskripsi. Biasanya ada nama programmer atau author, tapi nggak ah, nggak usah, hehehe…

Baris selanjutnya adalah sebuah directive INCLUDE yang berfungsi untuk mengikutsertakan file m8def.inc pada proses assembling. Bisa jadi direktori tempat file m8def.inc pada komputer Anda tidak sama dengan punya saya, jadi lakukan penyesuaian jika diperlukan.

File m8def.inc adalah file yang mendefinisikan register-register, alamat memori, dan lain-lain sepersis mungkin dengan yang ada di datasheet ATmega8.

Bisakah kita tidak menyertakan file m8def.inc dalam program assembler kita? Jawabnya, bisa. Akan tetapi dengan konsekuensi, Anda harus menuliskan register-register dalam bentuk alamat memorinya. Tuh, lebih repot kan? Jadi menyertakan file definisi dalam program assembler kita akan sangat membantu kita dalam menulis program.

.def acc = r16
.def temp1 = r17

Dua baris di atas ini adalah directive DEF yang berfungsi untuk memberikan nama pada register. R16 diberi nama acc (accumulator), dan R17 diberi nama temp1. Penamaan ini berfungsi untuk membuat program kita menjadi lebih mudah dibaca dan dipahami maksudnya. Penamaan disesuaikan dengan fungsi register tersebut dalam program.

Baiklah, baris program selanjutnya adalah sebagai berikut.

reset:
rjmp start
reti

reti

reset adalah label yang menyatakan alamat awal program yakni 0000. Alamat ini merupakan alamat vektor untuk RESET. Sesaat setelah proses mikrokontroler direset, maka CPU akan mengeksekusi program mulai alamat 0000.

Any question? Yes. How about CSEG and ORG Directives? I’ve seen people using ’em in their programs?

Good question! Sebenarnya kita juga bisa menuliskan program di atas sebagai berikut:

.cseg
.org 0000
rjmp start
reti

reti

CSEG (Code Segment) adalah directive untuk menyatakan alamat awal dari segmen kode. Dan ORG (Origin) adalah directive untuk menyatakan alamat absolut program atau data dalam memori. Jika directive ORG berada dalam segmen kode, maka alamat yang ditunjukkan adalah alamat dalam memori program. Jika directive ORG berada dalam segmen data (DSEG), maka alamat yang ditunjukkan adalah alamat dalam memori data (SRAM). Dan jika directive ORG berada dalam segmen EEPROM (ESEG), maka alamat yang ditunjukkan adalah alamat dalam memori EEPROM.

Dengan directive CSEG dan ORG tersebut, maka dipastikan assembler akan menempatkan instruksi RJMP START pada alamat 0000 dalam memori program.

Lha, kita kok gak pake? Begini. Nilai default segmen adalah segmen kode, sehingga tanpa directive CSEG pun, assembler akan menempatkan RJMP START pada alamat 0000 dalam memori program. Namun demikian, praktek penggunaan directive CSEG dan ORG adalah praktek yang lebih baik.

Instruksi RETI (Return from Interrupt) yang jumlahnya 18 biji adalah sekedar untuk mengisi memori program alamat 0001 hexa hingga 0012 hexa yang merupakan alamat vektor interupsi untuk ATmega8. ATmega8 memiliki total 19 vektor interupsi.

Barisan instruksi RETI tersebut untuk meyakinkan bahwa program utama akan berada pada alamat awal yang tepat. Pencantuman instruksi-instruksi RETI ini tidak harus dilakukan. Program akan tetap berjalan mulus meskipun menerjang (menempati) alamat vektor interupsi. Trus, apa gunanya? Lagi-lagi, hal tersebut adalah praktek penulisan program yang baik dan menunjukkan pemahaman tentang struktur memori program. Jadi untuk pemula sebaiknya hal ini dilakukan.

Tapi perlu ditekankan bahwa kita bisa menggunakan alamat-alamat vektor interupsi tersebut untuk keperluan lain jika diperlukan.

Nah, sekarang kita memasuki bagian program selanjutnya yakni bagian program dimana inisialisasi dilakukan.

; Awal program setelah RESET
start:

;set alamat awal STACK
ldi acc, low (ramend)
out spl, acc
ldi acc, high (ramend)
out sph, acc

Label start adalah alamat yang dituju oleh instruksi rjmp start. Pertama-tama dilakukan pengesetan alamat puncak STACK. STACK digunakan untuk menyimpan data sementara, untuk menyimpan nilai variabel lokal, dan untuk menyimpan alamat kembali (return address) setelah pemanggilan interupsi dan subrutin. Stack Area harus didefinisikan oleh program sebelum adanya instruksi pemanggilan subrutin atau interupsi. Stack Pointer harus menunjuk pada alamat di atas 60 hexa.

Stack Pointer diimplementasikan oleh dua buah register 8-bit yang ada di area memori I/O yakni SPH (8-bit high) dan SPL (8-bit low). Pada beberapa tipe AVR, tidak terdapat SPH karena kapasitas SRAM yang kecil sehingga hanya membutuhkan SPL saja, misalnya ATtiny2313.

Instruksi LDI (Load Immediate) berfungsi untuk mengisi register (R16 – R31) dengan suatu nilai konstanta. RAMEND adalah konstanta yang didefinisikan pada file m8def.inc. Konstanta ini bernilai 045F hexa. Fungsi LOW mengembalikan 8-bit terendah dan fungsi HIGH mengembalikan 8-bit teratas dari suatu nilai/ekspresi. LOW (RAMEND) = 5F hexa, dan HIGH (RAMEND) = 04 hexa.

Instruksi OUT berfungsi menyimpan nilai register ke dalam alamat I/O. Jadi instruksi LDI dan OUT pertama berfungsi untuk mengisi SPL dengan 05F hexa (SPL = 0x5F), dan pasangan instruksi LDI dan OUT yang kedua berfungsi untuk mengisi SPH dengan 04 hexa (SPH = 0x04). Sehingga, alamat puncak STACK adalah 0x045F yang merupakan alamat teratas dari Internal RAM ATmega8.

;set PORTB0..PORTB7 sebagai output
ser acc
out ddrb, acc

Selanjutnya, program melakukan inisialisasi terhadap PORTB. Instruksi SER (Set all bits in Register) akan mengeset semua bit dalam suatu register (R16 – R31) menjadi berlogika 1. Instruksi SER ACC identik dengan instruksi LDI ACC, $FF. Sama-sama membutuhkan 1 word memori, sama-sama dieksekusi dalam 1 siklus, dan sama-sama tidak mempengaruhi Register Status (SREG).

Instruksi OUT DDRB, ACC berfungsi mengeset semua bit dalam DDRB (Data Direction Register Port B), yang berarti PORTB difungsikan sebagai output.

Ambil nafas sejenak….. Oke, kita sampai dibagian looping utama program, yakni bagian program yang akan dieksekusi berulang-ulang tanpa henti.

;awal looping utama program
forever:

;putar komposisi bit acc ke kiri dengan Carry
;Carry <- acc.7 <- .. <- acc.0 <- Carry
rol acc

Label forever menjadi penanda alamat awal dari looping program utama. Ke alamat inilah, nantinya program akan melompat secara terus-menerus.

Instruksi ROL (Rotate Left through Carry) berfungsi untuk memutar komposisi bit pada suatu register dengan melalui Carry. Bit ke-7 digeser ke Carry, dan Carry digeser ke bit ke-0. Instruksi ROLL ACC, akan memutar komposisi bit ACC (R16). Perlu diketahui bahwa pada awalnya nilai Carry adalah nol, sehingga setelah di-ROL, maka ACC yang sebelumnya bernilai 11111111B akan bernilai 11111110B dan Carry akan bernilai 1.

;apakah acc=255 ?
cpi acc, 255

Selanjutnya, nilai ACC dicek, apakah bernilai 255 (11111111B). Pengecekan dilakukan menggunakan instruksi CPI (Compare with Immediate). Instruksi ini berfungsi untuk membandingkan nilai dalam register (R16 – R31) dengan suatu nilai konstanta. Nilai dalam register tidak berubah. Jika nilai register sama dengan nilai konstanta, maka bit status ZERO akan diset berlogika 1. Jika nilai register lebih dari nilai konstanta, maka bit status CARRY akan diset berlogika 1. Akan tetapi hal itu tidak mungkin terjadi karena nilai paling besar dalam byte adalah 255. Oleh sebab itu, aman-aman saja jika dalam kasus kita ini, kita menggunakan instruksi CPI karena tidak akan merubah nilai bit status CARRY.

Mengapa mesti mempertimbangkan bit status Carry? Karena kita menggunakan Carry dalam proses pergeseran komposisi bit dalam ACC. Jika terjadi perubahan nilai CARRY, maka dapat dipastikan Running LED tidak akan berjalan sempurna. Sebenarnya hal tersebut dapat diatasi dengan menyimpan register status (SREG) ke dalam Stack menggunakan instruksi PUSH sebelum instruksi CPI untuk kemudian di POP setelah proses pembandingan selesai dilakukan. Dalam program ini, kita tidak perlu menyelamatkan register status karena dipastikan tidak berubah.

;lompat ke go_on jika acc <> 255
brne go_on

;jika acc=255, putar bit ke kiri sekali lagi
rol acc

Setelah instruksi CPI yang akan menghasilkan ZERO jika ACC=255, maka kondisi bit status ZERO ini dicek menggunakan instruksi pencabangan BRNE (Branch if Not Equal). Instruksi BRNE go_on berarti melompat ke label go_on jika ZERO=0, atau dalam hal ini ACC tidak sama dengan 255. Jika ZERO=1 (ACC sama dengan 255), maka dilakukan pergeseran sekali lagi menggunakan instruksi ROL ACC. Hal ini perlu dilakukan karena setelah 8 kali pergeseran, maka nilai ACC kembali seperti semula yakni 255 (11111111B), dan CARRY=0. Oleh karenanya perlu dilakukan pergeseran sekali lagi jika ACC bernilai 255 agar tampilan Running LED tidak terputus.

go_on:
;update tampilan LED
out portb, acc

Selanjutnya, program akan meng-update tampilan LED dengan mengeluarkan komposisi bit pada ACC ke PORTB. Sesaat setelah instruksi ini dieksekusi, maka LED dengan bit berlogika 0 akan menyala dan yang lain akan mati. Ingat, LED terhubung dengan konfigurasi Common-Anode.

;panggil subrutin delay
rcall delay

Agar tampilan Running LED nyaman dilihat, maka perlu adanya waktu tunda (delay). Penundaan dilakukan dengan memanggil subrutin delay. Dalam contoh program ini, subrutin delay hanyalah delay sederhana semata untuk keperluan simulasi. Jika diterapkan pada hardware yang sesungguhnya, maka perlu dilakukan modifikasi untuk menghasilkan waktu tunda yang sesuai.

;looping selama-lamanya
rjmp forever

Instruksi RJMP forever akan menyebabkan Program Counter kembali lagi ke awal looping program. Perulangan ini berlangsung terus-menerus sehingga menyebabkan efek Running LED.

; subrutin delay
; Warning: non-practical delay
; Used for simulation purpose only
delay:
ldi temp1, 3

satu:
dec temp1
brne satu
ret

Tidak ada yang perlu dijelaskan dalam subrutin delay, jadi penjelasan saya akhiri sampai di sini. Semoga bermanfaat.

Selamat belajar!

5 comments

  1. andhy · Agustus 28, 2009

    Mas sya ingin bs buat moving sign(running led teks) bs beritahu ga mas gmna cara buatnya n alat2nya dan program apa yg d pakai. Kalau ada bukunya blh juga sya belì.sya d jambi mas.blz k e mail sya ya mas.thanks ya mas

  2. imam · Maret 12, 2010

    assalamu’alaikum..
    salam kenal mas chandra,
    saya imam, saya newbie ni.,tentang AVR,saya ingin belajar cara menulis programnya dulu,tapi q masih bingung dengan file “m8def.inc”. apa file ini di buat sendiri, ato file ini sdh bawaan dari sofware “VMLAB”.
    terimakasih….

  3. chandramde · Maret 12, 2010

    imam:
    Wa’alaikumsalaam. Salam kenal juga, Mas Imam.
    VMLAB menggunakan AVRASM32 dari ATMEL sebagai kompiler assemblernya.
    File m8def.inc merupakan file bawaan AVRASM32.

    Jika ingin yang lebih mudah, Mas Imam bisa menggunakan GAVRASM. Silakan baca postingan berikut: https://telinks.wordpress.com/2009/01/06/gavrasm-gerds-avr-assembler/

    Selamat belajar!😀

  4. imam · Maret 13, 2010

    mas chandra, q nyoba vmlab dengan file proyek1 waktu build ada pesannya:

    ” c:\avrasm32 …….
    ! non-valid or possible causes:
    – non-valid or empty ASM file
    – filerequested in .INCLUDE directive not found ”

    mohon penjelasan dimana letak kesalahan ato solusinya
    terimakasih…

  5. chandramde · Maret 13, 2010

    imam:
    Sangat boleh jadi:
    1. File program ada yang salah ketik. Awas, sebaiknya jangan meng-copy paste dari browser! Ketik saja secara manual sekalian membiasakan diri dengan lingkungan kerja VMLAB dan Bahasa Assembler AVR.
    2. File m8def.inc tidak berada dalam lokasi/direktori yang benar. Buka Explorer dan cari lokasi dimana VMLAB terinstal di harddisk Anda. Kemudian gantilah direktori pada direktif .include “C:\Microcontrollers\VMLAB\include\m8def.inc” dengan direktori yang tepat.

    Selamat belajar!😀

Tinggalkan Balasan

Isikan data di bawah atau klik salah satu ikon untuk log in:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s