#define __SFR_OFFSET 0
#include <avr/io.h>
.global main
.global TIMER1_COMPA_vect
; --- GLOBAL REGISTER ---
; r17 = Status Target (1: Drone/Hijau, 2: Rudal/Merah)
; r19 = Counter Urutan (0: hijau, 1: merah)
; r25 = Flag tombol ditekan (0: belum, 1: sudah)
; r24 = Counter tick Timer (tiap tick = 1 detik, target = 2)
.section .text
; === INTERRUPT VECTOR TABLE ===
.org 0x0000
rjmp main
.org 0x0016
rjmp TIMER1_COMPA_vect ; Timer1 Compare Match A vector
.org 0x0034
main:
; Setup Stack Pointer
ldi r16, hi8(RAMEND)
out SPH, r16
ldi r16, lo8(RAMEND)
out SPL, r16
; Setup I/O
sbi DDRB, 0 ; PB0 Output → LED Merah
sbi DDRB, 1 ; PB1 Output → LED Hijau
cbi DDRD, 2 ; PD2 Input → Tombol
sbi PORTD, 2 ; Aktifkan Pull-Up PD2
; Setup UART 9600 Baud
clr r16
sts UCSR0A, r16
sts UBRR0H, r16
ldi r16, 103
sts UBRR0L, r16
ldi r16, (1<<RXEN0)|(1<<TXEN0)
sts UCSR0B, r16
ldi r16, (1<<UCSZ00)|(1<<UCSZ01)
sts UCSR0C, r16
; === Setup Timer1 CTC Mode ===
; Target: interrupt setiap 1 detik
; Rumus: OCR1A = (F_CPU / (Prescaler * Target_Hz)) - 1
; OCR1A = (16.000.000 / (256 * 1)) - 1 = 62499
;
; TCCR1A = 0 (CTC mode, no PWM output)
; TCCR1B = WGM12 | CS12 (CTC mode, prescaler 256)
clr r16
sts TCCR1A, r16
ldi r16, (1<<WGM12)|(1<<CS12)
sts TCCR1B, r16
; Set OCR1A = 62499 = 0xF423
ldi r16, 0xF4
sts OCR1AH, r16
ldi r16, 0x23
sts OCR1AL, r16
; Reset TCNT1
clr r16
sts TCNT1H, r16
sts TCNT1L, r16
; Enable Timer1 Compare Match A Interrupt
ldi r16, (1<<OCIE1A)
sts TIMSK1, r16
; Inisialisasi register
ldi r19, 0 ; Urutan mulai dari hijau
clr r25 ; Flag tombol = 0
clr r24 ; Tick counter = 0
; Enable Global Interrupt
sei
loop_utama:
cbi PORTB, 0
cbi PORTB, 1
clr r25 ; Reset flag tombol
clr r24 ; Reset tick counter Timer
cpi r19, 1
breq set_rudal
set_drone:
ldi r17, 1
sbi PORTB, 1 ; LED Hijau ON
inc r19
rjmp tunggu_dan_cek
set_rudal:
ldi r17, 2
sbi PORTB, 0 ; LED Merah ON
ldi r19, 0
tunggu_dan_cek:
; Tunggu sampai r24 == 2 (2 tick = 2 detik)
; Selama menunggu, ISR Timer bisa increment r24
; dan tombol bisa dicek setiap saat
tunggu_loop:
; Cek tombol secara polling di dalam tunggu_loop
sbis PIND, 2 ; Skip jika tombol tidak ditekan (HIGH)
ldi r25, 1 ; Tombol ditekan (LOW) → set flag
; Cek apakah sudah 2 detik
cpi r24, 2
brlo tunggu_loop ; Belum 2 detik, terus tunggu
; 2 detik selesai → evaluasi
cpi r25, 1
brne cek_missed
cpi r17, 2
breq hit_rudal ; Merah + ditekan = BERHASIL
rjmp hit_drone ; Hijau + ditekan = SALAH TEMBAK
cek_missed:
cpi r17, 2
breq missed_rudal
rjmp loop_utama
missed_rudal:
ldi r30, lo8(msg_gagal)
ldi r31, hi8(msg_gagal)
call uart_print
rjmp loop_utama
hit_rudal:
ldi r30, lo8(msg_sukses)
ldi r31, hi8(msg_sukses)
call uart_print
rjmp loop_utama
hit_drone:
ldi r30, lo8(msg_gagal)
ldi r31, hi8(msg_gagal)
call uart_print
rjmp loop_utama
; === ISR TIMER1 COMPARE MATCH A ===
; Dipanggil otomatis setiap 1 detik oleh hardware Timer1
; TCNT1 otomatis di-reset ke 0 karena mode CTC
TIMER1_COMPA_vect:
inc r24 ; Tambah tick counter (+1 detik)
reti
; === UART PRINT ===
uart_print:
lpm r18, Z+
cpi r18, 0
breq print_end
uart_wait:
lds r16, UCSR0A
sbrs r16, UDRE0
rjmp uart_wait
sts UDR0, r18
rjmp uart_print
print_end:
ret
msg_sukses:
.asciz "INTERCEPT BERHASIL!\r\n"
msg_gagal:
.asciz "MISSED TARGET!\r\n"