;========================== ; Author: Marcel Schirmer ; Date: 31.05.2025 ;========================== .nolist .include "./m328Pdef.inc" .list .def setter = R16 .def overflows = R17 .def active_led = R18 .def btn_status = R19 .def cur_direction = R20 .equ L2R = 0x01 .equ R2L = 0x04 .equ RBTN_PRESSED = 0b00000100 .equ LBTN_PRESSED = 0b00000001 .equ BOTH_PRESSED = 0b00000101 .org 0x0000 rjmp init .org 0x0020 rjmp overflow_handler .include "./macros.inc" init: ;-- ; Output Ports definieren ;---- ser setter out DDRD, setter ; Alle PortD Pins als OUTPUT ;-- ; Taster Pins definieren ;---- ; ldi setter, 0b11111010 ser setter out DDRB, setter ; PB0 und PB2 als Inputs definieren ldi setter, 0b00000101 out PORTB, setter ; Interne Pullups aktivieren clr setter out PORTB, setter ;-- ; Timer/Counter konfigurieren ;---- ldi setter, 0b00000011 out TCCR0B, setter ; CLK/1024 ergibt 250.000 Timer-Ticks/Sekunde ldi setter, 0b00000001 sts TIMSK0, setter ; Timer-Interupt aktivieren sei ; globale Interrups aktivieren ;-- ; Definiere Startzustand ;---- ldi setter, 0 out TCNT0, setter ; Timer/Counter explizit mit 0 initialisieren ldi setter, 0b00000001 out PORTD, setter ; erste LED einschalten clr btn_status ; initialer Status = kein Taster gedrückt ldi cur_direction, L2R ; initial mit Laufrichtung von links nach rechts starten loop: ;-- ; Dreh Dräumchen und lass den Timer-Interrupt die Show leiten ;---- rjmp loop overflow_handler: inc overflows cpi overflows, 246 ; bei ~980 Überläufe/Sekunde entsprechen 245 Überläufe ca. 250ms brne early_exit ; early Return wenn Schwellenwert noch nicht erreicht clr overflows ; Überlaufzähler kontrolliert zurücksetzen in btn_status, PINB ; Aktuellen Button Zustand einlesen ;-- ; Geh direkt zur Animationslogik wenn ; kein Button gedrückt ; oder ; wenn der gedrückt Button dem der aktuellen ; Animation entspricht ;---- cpi btn_status, 0 breq run_animation ; kein Button gedrückt cp cur_direction, btn_status breq run_animation ; Animation bildet aktuellen Button-Status bereit ab ;------ ;-- ; Setze definierten Start für den ; Laufrichtungswechsel ;---- check_left_btn: cpi btn_status, LBTN_PRESSED brne check_right_btn ; Linker Button wurde gedrückt ldi cur_direction, L2R in setter, PORTD cpi setter, 0 brne run_animation ; Lauflicht wurde zuvor gestopped und muss neu initialisiert werden ldi setter, 0b00000001 out PORTD, setter rjmp run_animation check_right_btn: cpi btn_status, RBTN_PRESSED brne check_both_btn ; Rechter Button wurde gedrückt ldi cur_direction, R2L in setter, PORTD cpi setter, 0 brne run_animation ; Lauflicht wurde zuvor gestopped und muss neu initialisiert werden ldi setter, 0b10000000 out PORTD, setter rjmp run_animation check_both_btn: cpi btn_status, BOTH_PRESSED brne run_animation ldi setter, 0 out PORTD, setter ;------ run_animation: cpi cur_direction, L2R brne check_r2l left_to_right active_led reti check_r2l: cpi cur_direction, R2L brne show_err_code right_to_left active_led reti early_exit: reti show_err_code: ldi setter, 0b00011000 out PORTD, setter reti