Jika Anda memiliki dan sudah membaca atau mempelajari buku saya (Belajar Mikrokontroler AT89C51/52/55), tentunya Anda masih inget dengan program pertama yang saya tulis dengan tujuan untuk menghidupkan dan mematikan LED secara flip-flop atau bergantian yang terpasang di P1. Berikut saya sertakan lagi program ASM-nya:

;-- BAB3_01.ASM -----------------------------------------------------------
;
; Lampu flip-flop pada Port 1
;
;--------------------------------------------------------------------------
        ORG   0H        ; program ditempatkan pada lokasi 0000H
;
MULAI:  MOV   P1,#10101010B     ; LED P1.4 s/d P1.7 nyala (heksa= #0FH)
        ACALL DELAY             ; lakukan penundaan sesaat (sub. DELAY)
        MOV   P1,#01010101B     ; LED P1.0 s/d P1.3 nyala (heksa= #0F0H)
        ACALL DELAY             ; lakukan penundaan sesaat (sub. DELAY)
        SJMP  MULAI             ; ulangi lagi dari awal
;
;-subrutin DELAY-----------------------------------------------------------
;
; subrutin ini hanya sekedar melakukan penundaan sesaat dengan cara
; mengulangi proses (pengurangan isi register) hingga dicapai suatu
; kondisi tertentu
;
;--------------------------------------------------------------------------
DELAY:  MOV   R0,#5H            ; Isi Register R0 dengan 5 (5x ulang)
DELAY1: MOV   R1,#0FFH          ; Isi Register R1 dengan 255 (255x ulang
DELAY2: MOV   R2,#0             ; Isi register R2 dengan 0 (256x ulang)
        DJNZ  R2,$              ; R2=R2-1, jika R2 belum 0 ulangi lagi
        DJNZ  R1,DELAY2         ; R1=R1-1, jika R1 belum 0 ulangi DELAY2
        DJNZ  R0,DELAY1         ; R0=R0-1, jika R0 belum 0 ulangi DELAY1
        RET                     ; Kembali ke pemanggil subrutin DELAY

        END

Kali ini saya tulis dalam Bahasa C menggunakan kompiler MikroC untuk mikrokontroler AT89S8252 dengan frekuensi kristal 12 MHz. Berikut program dalam Bahasa C-nya…

void main() {
     P1 = 0b10101010;
     Delay_ms(500);
     P1 = 0b01010101;
     Delay_ms(500);
}

Saat disimulasikan maupun dicoba hasilnya sama persis, kecuali masalah tundaan yang berbeda, tetapi konsepnya sama semua yaitu menghidupkan dan mematikan lampu LED secara flip-flop (atau bergantian). Namun apa yang terjadi dengan hasil kompilasi program Bahasa C-nya, mau tahu? Jangan kaget, inilah hasilnya:

_main:
    MOV 129, #128
;bab3_01.c,1 ::         void main() {
;bab3_01.c,2 ::         P1 = 0b10101010;
    MOV 144, #170
;bab3_01.c,3 ::         Delay_ms(500);
    MOV R5, 2
    MOV R6, 255
    MOV R7, 255
    NOP
    DJNZ R7, -3
    DJNZ R6, -7
    DJNZ R5, -11
    MOV R6, 255
    MOV R7, 255
    NOP
    DJNZ R7, -3
    DJNZ R6, -7
    MOV R6, 141
    MOV R7, 255
    NOP
    DJNZ R7, -3
    DJNZ R6, -7
    MOV R7, 8
    NOP
    DJNZ R7, -3
    NOP
    NOP
;bab3_01.c,4 ::         P1 = 0b01010101;
    MOV 144, #85
;bab3_01.c,5 ::         Delay_ms(500);
    MOV R5, 2
    MOV R6, 255
    MOV R7, 255
    NOP
    DJNZ R7, -3
    DJNZ R6, -7
    DJNZ R5, -11
    MOV R6, 255
    MOV R7, 255
    NOP
    DJNZ R7, -3
    DJNZ R6, -7
    MOV R6, 141
    MOV R7, 255
    NOP
    DJNZ R7, -3
    DJNZ R6, -7
    MOV R7, 8
    NOP
    DJNZ R7, -3
    NOP
    NOP
;bab3_01.c,6 ::         }
    SJMP #254
; end of _main

Wow, ternyata pemanggilan fungsi Delay_ms(500) di-implementasikan begitu saja, tidak ada pengubahan ke dalam bentuk sub-rutin, sehingga bisa Anda bayangkan begitu panjang programnya, padahal penggunaan Delay_ms(500) 2 kali menghasilkan 2 rentetan instruksi yang sama persis! Serta bukan menggunakan pewaktu tetapi permainan register di dalam AT89. Bagaimana kalau program Bahasa C-nya saya ubah menjadi…

void tunda_donk() {
     Delay_ms(500);
}
void main() {
     P1 = 0b10101010;
     tunda_donk();
     P1 = 0b01010101;
     tunda_donk();
}

Hasilnya? Ini dia, berbeda dengan sebelumnya…

_tunda_donk:
;bab3_01a.c,1 ::         void tunda_donk() {
;bab3_01a.c,2 ::         Delay_ms(500);
    MOV R5, 2
    MOV R6, 255
    MOV R7, 255
    NOP
    DJNZ R7, -3
    DJNZ R6, -7
    DJNZ R5, -11
    MOV R6, 255
    MOV R7, 255
    NOP
    DJNZ R7, -3
    DJNZ R6, -7
    MOV R6, 141
    MOV R7, 255
    NOP
    DJNZ R7, -3
    DJNZ R6, -7
    MOV R7, 8
    NOP
    DJNZ R7, -3
    NOP
    NOP
;bab3_01a.c,3 ::         }
    RET
; end of _tunda_donk

_main:
    MOV 129, #128
;bab3_01a.c,4 ::         void main() {
;bab3_01a.c,5 ::         P1 = 0b10101010;
    MOV 144, #170
;bab3_01a.c,6 ::         tunda_donk();
    LCALL _tunda_donk+0
;bab3_01a.c,7 ::         P1 = 0b01010101;
    MOV 144, #85
;bab3_01a.c,8 ::         tunda_donk();
    LCALL _tunda_donk+0
;bab3_01a.c,9 ::         }
    SJMP #254
; end of _main

Sekarang terbentuklah subrutin dalam ASM-nya, sehingga tidak ada 2 rentetan istruksi yang sama seperti ditemukan sebelumnya. Hal-hal seperti inilah yang harus kita perhatikan jika menuliskan program untuk mikrokontroler (apa saja) menggunakan bahasa Tingkat Tinggi (seperti C, BASIC, dll) agar bisa diperoleh program yang optimal dan baik. Keunikan lain dari Bahasa C vs Assembly bisa Anda di artikel “C vs Assembly MCS-51: Kasus unik Aritmetika!“.

Semoga bermanfaat!

Tags: , ,

19 Responses to “C vs Assembly MCS-51: Kasus LED Flip-flop”

  1. Pendapat saya pribadi,-

    Memang tidak semua aplikasi bisa maksimal dengan bahasa tingkat tinggi, walaupun menggunakan kompiler dengan optimasi terbaikpun seperti (keil uVision, IAR Workbench) yang notabennya adalah kompiler terbaik untuk keluarga 8051 tidak selalu menghasilkan kode dengan mapping memori dan kombinasi instruksi yang sempurna, apalagi yang sekelas SDCC (^_^)”..

    Tetapi.. untuk aplikasi yang membutuhkan memori kode yang besar atau aplikasi rumit dan kompleks yang membutuhkan sistem multi tasking maka bahasa tingkat tinggi yang paling mendekati bahasa tingkat rendah yang di pakai (sebagian besar C) Seperti RTOS yang sudah mendapat standar afiation seperti uCOSII, nutOS, ThreadX atau yang lain menggunakan bahasa C.

    menurut saya tinggal aplikasi yang dikerjakan. Jadi untuk implementasi nyata dalam aplikasi kecil yang tidak terlalu rumit dan panjang akan saya kerjakan dengan bahasa assembly, dan kalo programnya terlalu panjang dan rumit.. ampun dah” apalagi dikejar deadline.. ya pake C.

    bagi saya, untuk memulai lebih baik menggunakan bahasa assembly dulu karena juga sembari belajar arsitektur dan ntar kalo dah lumayan baru belajar bahasa C.
    Itu kalo saya, hidup adalah pilihan..
    seperti mencari istri..
    sampai sekarang belon dapet-dapet (@.@)” hiks”
    cariin mas Agfi.. :)

  2. kode pertama yg diexpand lebih baik karena lebih cepat meskipun membutuhkan kode lebih banyak
    instruksi CALL lebih lambat karena perlu mensave parameter , FP, IP dan waktu return perlu di POP lagi
    menjadikan fungsi seperti makro oleh compiler selalu lebih baik terutama untuk fungsi yg pendek apalagi bila berada dalam loop

  3. Lupakan aja dulu cari istri itu pak.. Ini lebih menarik dari sekedar cari istri. hehe hheeee..

  4. asslm, pak mau tanya bgaimana kalau mau bikin program dengan judul ‘Mengambil data ADC dan menampilkannya ke Led’?makasih atas bantuannya

  5. eko (2677 ELINS)
    June 7th, 2009 at 1:23 pm

    asslmkum
    pak minta materi kuliah AT89…

  6. pak,satu perintah dalam bahasa C sih dilakukan berapa lama?
    terima kasih…

  7. mas. bisa minta tolong kirimin cara membaca kaypad matrik 4×4 dan di tampilin pada 4 buah 7segmen?????

    mohon banget ya,
    saya dah buat tapi tampilanya sama pada ke-empat 7segmenya..
    biar bisa kayak register geser pake assembly gimana ya carannya????????????????????????????????????

    mohon kirim ka :: pande_cherry@yahoo.co.id

  8. saya ingin tanya, program apa yg dipakai untuk simulator micro atmel dengan bahasa mcs-51…, jd programnya ditaruh dikomputer trus lednya dipasang di port komputer, trus programnya diketik dan di run lednya akan bisa mengikuti program.. thanks please balas ke email saya

  9. @bayu:
    silahkan gunakan Proteus VSM (http://www.labcenter.co.uk)

  10. asslmkm pak! mau nanya bisa minta tolong kirimin program tuk menyalakan LED dlm bhs assembler yg melalui port printer dan tanpa IC.terima kasih pak! wss

  11. @dono:
    silahkan merujuk menggunakan buku saya “Belajar Bahasa Assembly menggunakan Emu8086″, konsep2 dasarnya ada disana, informasi dan pemesanan bukunya disini.

  12. aslmkm semua….
    saya mau nnya program assembly untuk dot matrik ada ga..???
    law ada tlong tampilkan,, tengkyu bnyak.,,,,,

  13. SAYA MINTA DICARIKAN FUNGSI DARI CRS FF

  14. trims… semuanya…? mau buat tambahan bahan praktek nee…?

  15. ada yang punya program buat bikin timer catur di mcs51 ga??
    pake 4 segment

  16. hmm… kalo mau bikin runing led gimana caranya?..

  17. master agfi..mo nanya….?
    bagaimana cara mensiasati program asm….jika ada instruksi jmp dalam subrutin yg diakhiri ret
    contoh;
    csr:
    setb sw_jam
    setb ring
    jnb sw_jam,zz
    jnb ring,xx
    sjmp yy
    zz:
    ajmp cek_sw ;perintah ini hrs kluar dr subrutin ini tnp
    balik lagi ke subrutin ini
    xx:
    ajmp cek_ring
    clr led_sw
    yy: ret

    sy dah coba subrutin tsb,…tp stelah di hardwarekan kadang2 hang…

    mohon pencerahanya…
    thx

  18. Assalaamu’alaikum..
    Om, minta tolong dong..
    bisa buat coding blinking tuk 1 buah led dalam bentuk asm, tapi inputan nya atau perintah menjalankannya melalui modul bluetooth Hc-05 yg di hubungkan ke MCS-51.. ya misalkan kita jalankan melalui hp android gitu..

    agak di bantu ya om,..
    terima kasih..

Trackbacks/Pingbacks

  1. Memulai Belajar Mikrokontroler - Quick, Easy and Harmless!

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>