Artikel ini sengaja saya tulis sebagai awal pembelajaran bagaimana membuat sebuah program aplikasi mikrokontroler AVR (khususnya ATMega32 dengan frekuensi kristal 7,3728MHz) untuk membuat animasi LED berjalan dari pin 0 hingga 7.

Rangkaian yang digunakan ditunjukkan pada Gambar 1, sengaja LED disusun secara CA atau common Anoda, sehingga untuk menyalakan LED harus dikirimkan logika ‘0′.

Untuk kompilasi digunakan AVR Studio versi 4.0 (silahkan unduh GRATIS dari http://www.atmel.com). Program kita awali dengan beberapa macam deklarasi, keterangan sengaja saya masukkan dalam listing program untuk memudahkan pembelajaran langsung dari listingnya, perhatikan instruksi yang diawali dengan ‘.’ merupakan directive dari AVR Studio, bukan instruksi assembly mikrokontroler AVR:

;------------------------------------------
;animasi LED berjalan dalam bahasa Assembly
;untuk mikrokontroler Atmel AVR ATMega32
;frekuensi kristal 7.3728MHz
;http://agfi.staff.ugm.ac.id
;------------------------------------------
.nolist ;bagian ini
.include "m32def.inc"  ;tidak perlu ditampilkan dalam
.list                  ;berkas list

Ingat berkas “m32def.inc” kita sertakan (directive .include) karena akan digunakan pustaka ATMega32 dalam program kita, tetapi tidak perlu disertakan dalam hasil berkas LIST-nya (hasil kompilasi program) menggunakan directive .nolist dan .list.

Selanjutnya dilakukan inisialisasi awal:

;----------inisialisasi konstanta dan register
.equ led=0b01111111 ;portb-7  ON
.def temp=r16       ;temp sebagai alias untuk R16
;====== program utama ====================
.cseg
.org 0000   ;awal kode program pada alamat 0x0000

Variabel LED digunakan untuk menyimpan data yang akan dikeluarkan melalui PORTA, awalnya diisi 0b01111111, artinya LED-0 akan dinyalakan terlebih dahulu. Variabel TEMP digunakan variabel alias untuk R16 (register-16), Anda boleh menggunakan nama alias apa saja, misalnya, tahu, brokoli, wortel dan lain sebagainya (emang buat sayur yach? he he he)…

Program diawali dengan mendeklarasikan segmen kode (.cseg) dan dimulai alamat 0×0000 (.org) - ini paling logis kita siapkan di alamat tersebut, silahkan saja kalo mo diganti dengan alamat lain asalkan tidak konflik dengan kepentingan lainnya dalam program. Ragu-ragu? Ya sudah ikuti saja pake alamat 0×0000, aman dech…!

Selanjutnya kita lakukan INISIALISASI STACK:

;menyiapkan alamat SP - Stack Pointer
;harus dituliskan sebagai inisialisasi SP pada RCALL
;jika tidak dilakukan program akan macet!
    ldi temp,low(ramend)
    out spl,temp
    ldi temp,high(ramend)
    out sph,temp

Jika Anda lupa atau tidak melakukan inisialisasi stack, ada kemungkinan besar akan terjadi kemacetan pada program, artinya program seakan-akan stuck. Jika Anda menggunakan simulator semacam Proteus (yang pernah saya coba menggunakan Proteus 7.6 SP4), program akan berjalan tanpa kesalahan, namun ketika dicobakan ke rangkaian sesungguhnya program akan berhenti (stuck). Saran saya, ada baiknya tidak terlalu mengandalkan simulator mikrokontroler semacam Proteus, usahakan untuk mencoba di dunia nyata, di rangkaian sesungguhnya. Berikut cuplikan program untuk menginisialisasi stack di akhir ruang RAM (RAMEND).

Karena STACK pada ATMega32 ukuran 16bit atau 2byte, maka pengisian SP dilakukan dua kali untuk SP Low atau SPL dan SP High atau SPH. Fungsi Low() dan High() masing-masing digunakan untuk mendapatka bagian LOW atau HIGH dari variabel RAMEND yang suda tersimpan dalam “m32def.inc”. Pengisian register pada AVR tidak bisa dilakukan langsung, dalam hal ini melalui variabel TEMP baru kemudian dipindahkan ke SPL dan SPH. Hal ini berlaku juga untuk penjelasan terkait berikut ini…

Berikutnya, karena kita menggunakan mikrokontroler AVR, sudah wajib kita menentukan sebuah PORT sebagai masukan atau luaran, jika masing-masing bit pada register DDRx diberi nilai ‘1′ artinya sebagai luaran (jika ‘0′ sebagai masukan). Karena digunakan PORTA maka digunakan register DDRA (penulisan ke DDRA (out ddra,temp) tidak bisa langsung, sehingga digunakan variabel TEMP (ldi temp,0b01111111)):

;----------- inisialisasi port---------------------
    ldi   temp,0b11111111 ;set semua bit register temp
    out   ddra,temp       ;tuliskan ke register DDRA

Selanjutnya program utama dituliskan:

;--------portb telah di seting menjadi luaran ------
    ldi   temp,led ;isi register temp dengan led7
    sec            ;set carry flag (agar carry=1, LED mati)
putar:
    out   porta,temp ;kirim data ke porta (LED)
    rcall tunda      ;tunda sesaat 0.25 detik
    ror   temp       ;putar satu bit ke kanan melalui carry
    rjmp  putar      ;lompat ke label putar

Data disimpan terlebih dahulu di variabel TEMP (ldi temp,led), kemudian baru dikeluarkan ke PORTA (out porta,temp), tidak bisa langsung dikirim ke PORTA. Untuk menggeser dan memutar bit pada variabel TEMP digunakan instruksi ROR (Rotate Right Using Carry), karena melewati Carry sedangkan Carry biasanya isinya ‘0′, maka harus diberi ‘1′ dulu dengan instruksi SEC. Pengulangan dilakukan dengan melompat kembali ke label ‘putar’ menggunakan rjmp putar.

Bagian akhir dari program adalah subrutin penundaan sekitar 0.25detik (lihat pada listing program lengkap). Kok bisa ya? Ya pake saja program AVR Delay Loop Generator, sebagaimana screen shoot-nya ditunjukkan pada Gambar 2, silahkan unduh gratis di-sini.

Memang menggunakan pengulangan register, penundaan 0.25 detik tidak akan akurat, tetapi lumayan buat melakukan penundaan sesaat. Jika Anda ingin akurat, gunakan fasilitas Timer/Counter pada mikrokontroler AVR yang bersangkutan.

Program selengkapnya sebagai berikut (ingat akhiri program dengan .exit)…

;------------------------------------------
;animasi LED berjalan dalam bahasa Assembly
;untuk mikrokontroler Atmel AVR ATMega32
;frekuensi kristal 7.3728MHz
;http://agfi.staff.ugm.ac.id
;------------------------------------------
.nolist			;bagian ini
.include "m32def.inc" 	;tidak perlu ditampilkan dalam
.list			;berkas list

;----------inisialisasi konstanta dan register
.equ	led=0b01111111	;portb-7  on
.def	temp=r16	;temp sebagai alias untuk R16

;====== program utama ====================
.cseg
.org	0000			;awal kode program pada alamat 0x0000

;menyiapkan alamat SP - Stack Pointer
;harus dituliskan sebagai inisialisasi SP pada RCALL
;jika tidak dilakukan program akan macet!
	ldi temp,low(ramend)
	out spl,temp
	ldi temp,high(ramend)
	out sph,temp

;----------- inisialisasi port---------------------
	ldi	temp,0b11111111	;set semua bit register temp
	out	ddra,temp		;tuliskan ke register DDRA

;--------portb telah di seting menjadi luara ------
	ldi	temp,led	;isi register temp dengan led7
	sec			;set carry flag (agar carry=1, LED mati)
putar:
	out	porta,temp	;kirim data ke porta (LED)
	rcall	tunda		;tunda sesaat 0.25 detik
	ror	temp		;putar satu bit ke kanan melalui carry
	rjmp	putar		;lompat ke label putar

; =============================
;    delay loop generator
;     1843200 cycles:
;    untuk frek 7.3728MHz
;    penundaan 0.25 detik
; -----------------------------
; delaying 1843182 cycles:
tunda:
          ldi  R17, $12
WGLOOP0:  ldi  R18, $A1
WGLOOP1:  ldi  R19, $D3
WGLOOP2:  dec  R19
          brne WGLOOP2
          dec  R18
          brne WGLOOP1
          dec  R17
          brne WGLOOP0
; -----------------------------
; delaying 18 cycles:
          ldi  R17, $06
WGLOOP3:  dec  R17
          brne WGLOOP3
; =============================
		  ret
; =============================
.exit					;akhir program

Sedangkan dalam Bahasa C Native (menggunakan AVR Studio 4 dan GCC) ditunjukkan lengkap sebagai berikut:

//========================================
// animasi LED di PORTA
//=========================================
#include
#include 		//pustaka DELAY untuk frek 1MHz
#define PORTLED	PORTB	//penentuan alias untuk PORTB
#define DDRLED	DDRB	//penentuan alias untuk DDRB

int main (void)
{
	unsigned char temp=0x80; 		// data untuk LED
	DDRLED=0xFF;				// PORT sebagai luaran
	while(1){
		PORTLED=temp;			//tulis ke port
		_delay_ms(250);			//lakukan penundaan sesaat
		temp=(temp<<7)|(temp>>1);} 	//ROR dalam bahasa C
	return(0);
}

Silahkan Anda cermati perbedaan penulisan menggunakan Assembly dan Native C (gcc), untuk urusan penundaah digunakan fungsi _delay_ms() yang sudah didefinisikan di berkas “delay.h” dan berlaku untuk frekuensi operasional 1MHz. Sedangkan inisialisasi PORT sama seperti pada Assembly. Yang mungkin Anda pertanyakan adalah pengganti perintah ROR yaitu menggunakan instruksi “temp=(temp<<7)|(temp>>1);“, untuk ROL tinggal Anda ganti dengan “temp=(temp<<1)|(temp>>7);” dan “unsigned char temp=0×80;” menjadi “unsigned char temp=0×01;“.

Demikian penjelasan singkat saya tentang aplikasi animasi LED berjalan menggunakan bahasa assembly dan C untuk mikrokontroler AVR ATMega32. Semoga bermanfaat dan sukses selalu untuk Anda! Ingin private dengan saya untuk Belajar Mikrokontroler AVR ATMega32 menggunakan bahasa BASIC? Silahkan cermati informasinya disini.

Tags: , , , , , , , ,

23 Responses to “Animasi LED mikrokontroler ATMega32 dengan Assembly dan C”

  1. wah, saya sangat salut denga karya yang telah anda buat. sangat bagus, sepertinya saya harus belajar lebih banyak lagi, karya anda telah memberikan inspirasi bagi saya, terimakasih.

  2. @rera: terima kasih atas apresiasi-nya… alhamdulillah

  3. pak bka pelatihan DCS apa SCADA ga pak?

  4. @dhimas: sementara belum, handout-nya belum ada…

  5. bro…boleh tuh ada yang udah jadi kan, minat ne

  6. aslm, Pak Agfi

    saya pernah coba bikin program flip-flop pake assembler AVR studio tapi kenapa gak bisa terjadi looping padahal sudah dikasih sintak ini

    ldi temp,low(ramend)
    out spl,temp
    ldi temp,high(ramend)
    out sph,temp

    klo di proteus bisa lancar tapi di di hardwarenya gak jalan. mohon penjelasannya

    wslm

  7. @wahyu:
    apakah anda sudah mengganti statement .include “m32def.inc” dengan mikrokontroler yang Anda gunakan?? karena konstanta RAMEND mengambil alamat sesuai dengan mikrokontroler yang digunakan.

  8. aslm pak agfi

    sudah pak, sintak nya begini

    .include “C:\Program Files\Atmel\AVR Tools\AvrAssembler2\Appnotes\m16def.inc”
    .cseg
    .org 0×0000
    rjmp main

    main:

    ldi r16,low(RAMEND)
    out SPL,r16
    ldi r16,high(RAMEND)
    out SPH,r16

    ldi r16, 0xff
    out ddrb,r16
    out portb, r16
    rcall tunda
    ldi r16,0×00
    out portb,r16
    rcall tunda

    rjmp main

    tunda:
    inc r17
    cpi r17,0xff
    breq tunda2
    tunda1:
    inc r18
    cpi r18,0xff
    breq tunda
    rcall tunda1
    tunda2:
    ret

    saya coba berkali2 belum berhasil, gak terjadi looping (led nya nyala terus nggak berkedip…
    mohon bantuannya

    wslm

  9. @wahyu:
    salahnya disini…

    main:
    ldi r16,low(RAMEND)
    out SPL,r16
    ldi r16,high(RAMEND)
    out SPH,r16


    rjmp main <- ini loch!

    kok mulai dari paling awal lagi? coba cocokkan program Anda dengan listing program yang saya buat…

  10. pak saya mau bertanya bagaimana caranya bikin software yang dapat menampilkan hasil panghitungan temperatur dan kelembapan dari alalt/device menggunakan delphi 7.0

    terimakasih

  11. aslm pak agfi

    terimakasih atas infonya
    alhamdulillah sekarang sudah bisa looping

    wslm

  12. waohh… saya sangat salut dengan blog ini, keren.. karya anda membuka pikiran saya, yang tadinya kurang tau dengan dunia mikrokontroler akhirnya sedikit mengerti.. hehe.. bisa dipostingin juga contoh listing program trajektori mobile robot dalam mikrokontroler dengan bahasa c gk??

  13. Mantap pak. kita majukan mikrokontroler di yogyakarta.

  14. Assalamua’alaikum pak.
    saya masih baru belajar uC,
    yg ingin saya tanyakan apakah perbedaan bahasa C yg di gunakan oleh Arduino dengan bahasa C yg di gunakan pada AVR Studio dan GCC???
    jika memang ada perbedaan, bagaimana cara mengconvertnya??? baik dari Arduino ke AVR ataupun sebaliknya.
    trimakasih.
    Wassalamu’alaikum wr. wb.

  15. @hariri:
    dari segi bahasa sama-sama menggunakan avr GCC, jadi gak ada bedanya kecuali dalam fasilitas library-nya, dimana arduino sudah dilengkapi dengan library untuk memudahkan pemrograman… kira2 begitu…

  16. pak Agfi, saya mau tanya.
    Apakah bascom avr itu pake asembly ato pake C?
    trims

  17. Assalamu alaikum
    saya baru belajar atmega32, ketika saya flash program menggunakan khazama avr dak bisa, kenapa ya????????????? tlong ada solusinya.

  18. assalmualaikum .
    salam kenal pak…!
    terimaksih sudah menyertakan keterangan nya, sangat membantu.saya baru belajar mikro.

    saya mau mencoba di atmega8535…! di avrstudio udah jalan tidak ada yang eror
    mudah2an real nya jalan.

  19. bos blh ga aku minta codingan
    cara matikan lampu jarak jauh dengan menggunakan sensor getar

  20. bos blh ga aku minta codingan
    cara matikan lampu jarak jauh dengan menggunakan sensor getar
    cara nya dengan via missed calls.ke hp

  21. mas klok buat lampu brjalan bolak balik secara terus menerus gimna tu sintak bahasa C nya mas?

  22. terimakasih untuk artikelnya

Trackbacks/Pingbacks

  1. Aplikasi Pushbutton Mikrokontroler ATMega32 dengan Assembly | DSP & Embedded Electronics

Leave a Reply

You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>