Skip to main content

8. Contoh Kode Assembly ADC

8.1 Kode Lengkap

Berikut adalah contoh kode Assembly AVR untuk membaca ADC dari pin ADC0 menggunakan referensi internal 2.56V dan prescaler CLK/128:

#define __SFR_OFFSET 0x00
#include "avr/io.h"
;------------------------
.global main

main:
    LDI R20, 0xFF
    OUT DDRD, R20       ; Set Port D sebagai output (low byte hasil ADC)
    OUT DDRB, R20       ; Set Port B sebagai output (high byte hasil ADC)
    SBI DDRC, 0         ; Set pin PC0 sebagai input untuk ADC0

    ;-- Inisialisasi ADC --
    LDI R20, 0xC0       ; REFS1:REFS0 = 11 → Internal 2.56V
                        ; ADLAR = 0 → Right-justified
                        ; MUX4:MUX0 = 00000 → ADC0
    STS ADMUX, R20

    LDI R20, 0x87       ; ADEN = 1 → Enable ADC
                        ; ADPS2:ADPS0 = 111 → Prescaler CLK/128
    STS ADCSRA, R20

;-- Loop pembacaan ADC --
read_ADC:
    LDI R20, 0xC7       ; Set ADSC = 1 untuk memulai konversi
    STS ADCSRA, R20

wait_ADC:
    LDS R21, ADCSRA     ; Baca status register ADCSRA
    SBRS R21, 4         ; Skip jump jika ADIF (bit 4) = 1 (konversi selesai)
    RJMP wait_ADC       ; Loop tunggu sampai ADIF set

    ;-- Reset ADIF flag --
    LDI R17, 0xD7       ; Set ADIF = 1 agar controller bisa reset flag
    STS ADCSRA, R17

    ;-- Baca hasil konversi --
    LDS R18, ADCL       ; Baca low-byte dari ADCL (WAJIB dibaca dulu)
    LDS R19, ADCH       ; Baca high-byte dari ADCH

    ;-- Output hasil --
    OUT PORTD, R18      ; Kirim low-byte ke Port D
    OUT PORTB, R19      ; Kirim high-byte ke Port B

    RJMP read_ADC       ; Ulangi pembacaan

8.2 Penjelasan Kode

Bagian Inisialisasi:

LDI R20, 0xC0
STS ADMUX, R20
  • 0xC0 dalam biner = 1100 0000
  • REFS1=1, REFS0=1 → Tegangan referensi internal 2.56V
  • ADLAR=0 → Right-justified output
  • MUX4:MUX0 = 00000 → Membaca pin ADC0 (A0)
  • Bagian ini hanya dijalankan sekali saat inisialisasi.
LDI R20, 0x87
STS ADCSRA, R20
  • 0x87 dalam biner = 1000 0111
  • ADEN=1 → ADC diaktifkan
  • ADPS2:ADPS0 = 111 → Prescaler CLK/128 (125 kHz pada 16 MHz)

Bagian Pembacaan (Loop):

LDI R20, 0xC7
STS ADCSRA, R20
  • 0xC7 dalam biner = 1100 0111
  • ADEN=1, ADSC=1 → Mulai satu siklus konversi
  • ADPS tetap sama (CLK/128)
wait_ADC:
    LDS R21, ADCSRA
    SBRS R21, 4
    RJMP wait_ADC
  • Polling loop: terus membaca ADCSRA dan mengecek bit 4 (ADIF)
  • SBRS = Skip if Bit in Register Set → jika ADIF=1 (konversi selesai), skip RJMP
  • Selama ADIF=0 (konversi belum selesai), terus loop
LDI R17, 0xD7
STS ADCSRA, R17
  • Reset flag ADIF dengan cara menulis nilai 1 ke bit ADIF
  • Ini diperlukan agar konversi berikutnya bisa terdeteksi kembali
LDS R18, ADCL
LDS R19, ADCH
OUT PORTD, R18
OUT PORTB, R19
  • Baca ADCL terlebih dahulu (wajib), baru ADCH
  • Kirim hasilnya ke Port D (low-byte) dan Port B (high-byte)
  • Karena right-justified: ADCH hanya berisi 2 bit (bit 9 dan 8)