Witam
Mam nadzieje że ktoś mi wytłumaczy gdzie tkwi problem i jak go rozwiązać gdyż sam na moim etapie znajomości AVR nie moge sobie poradzić.
Uczę się asm i chcę napisac program do wyświetlania cyfr 0-9 na wyświetlaczu 7 segmentowym, cyfry mają się zmieniać po naciśnięciu przycisku +/-. Szkopuł tkwi w tym że nie wiem dlaczego w pozycji 0 po naciśnięciu - na wyświetlaczu pojawiają się jakieś hieroglify zamiast cyfry 9. Gdy wartość na wyświetlaczu jest różna od zera to po naciśnięciu - zachowanie jest prawidłowe. Domyślam się że problem tkwi w tablicy znaków zdefiniowanej na dole programu i w sposobie odwołania się do niej i detekcji zera ale nie wiem jak to zrobić żeby było dobrze. Będę bardzo wdzięczny za pomoc.
Poniżej zamieszczam program.
Mam nadzieje że ktoś mi wytłumaczy gdzie tkwi problem i jak go rozwiązać gdyż sam na moim etapie znajomości AVR nie moge sobie poradzić.
Uczę się asm i chcę napisac program do wyświetlania cyfr 0-9 na wyświetlaczu 7 segmentowym, cyfry mają się zmieniać po naciśnięciu przycisku +/-. Szkopuł tkwi w tym że nie wiem dlaczego w pozycji 0 po naciśnięciu - na wyświetlaczu pojawiają się jakieś hieroglify zamiast cyfry 9. Gdy wartość na wyświetlaczu jest różna od zera to po naciśnięciu - zachowanie jest prawidłowe. Domyślam się że problem tkwi w tablicy znaków zdefiniowanej na dole programu i w sposobie odwołania się do niej i detekcji zera ale nie wiem jak to zrobić żeby było dobrze. Będę bardzo wdzięczny za pomoc.
Poniżej zamieszczam program.
.include "2313def.inc"
#define acc r16
.cseg
.org 0x00
ldi acc, 0b11111111 ; załaduj do r16 liczbę 255 (0xff)
out DDRB, acc ; wpisanie do DDRB samych jedynek
; powoduje ustawienie pinów jako wyjście
out PORTB, acc
ldi acc, 0b1111100 ;
out DDRD, acc ; piny D0 i D1 są ustawione jako wejścia
; pozostałe jako wyjścia
ldi acc, 0b1110111
out PORTD, acc ; włączony pierwszy wyświetlacz, wejścia
; podciągnięte do zasilania
ldi acc, 127 ;
out SPL, acc ; ustawienie wskaˇnika stosu na 127
start:
ldi ZH, high(znaki << 1) ; załadowanie do rejestru Z adresu
ldi ZL, low(znaki << 1) ; tablicy z kodami znaków
sprawdz_klawisze:
lpm ; załaduj do r0 bajt z pamięci programu
mov r17, r0 ; przenieś zawartość r0 do r16
cpi r17, 0 ; sprawdˇ, czy równe zero
breq start ; jeśli tak, skocz na początek programu
sbis PIND, 0 ; jeśli pin D0 = 1, to pomiń następną instrukcję
adiw ZH:ZL, 1
sbis pind, 1 ; jeśli pin D1 = 1, to pomiń następną instrukcję
sbiw ZH:ZL, 1
out portb, r0
ldi acc, 150
rcall waitms
rjmp sprawdz_klawisze ; skocz do początku sprawdzania klawiszy
waitms:
mov r22, acc ; ustaw czas opóˇnienia
; powtórz n razy pętlę L,
; co da opóˇnienie ok. n * 1 ms
L:
; powtórz 10 razy pętlę L0,
; co da opóˇnienie ok 1ms
ldi r21, 10
L0:
; powtórz 100 razy pętlę L1,
; co da opóˇnienie ok. 100 us
ldi r20, 100
L1:
nop ; 1 cykl
dec r20 ; 1 cykl
brne l1 ; 2 cykle
; koniec pętli L1
dec r21
brne l0
; koniec pętli L0
dec r22
brne L
; koniec pętli L
ret
; Tablica z kodami znaków
znaki: .db 192,249,164,176,153,146,130,248,128,144,0