Witam!
Zbudowałem prosty układ i chciałbym na nim nauczyć się dobrze obsługiwać i synchronizować przerwania. Jego głównym założeniem będzie liczenie co jedną sekundę do 99 na dwóch wyświetlaczach siedmiosegmentowych(obsługa "multipleksacją") z dodatkowymi opcjami(odebrać coś z komputera itp). Pisałem w C a z assemblerem dopiero zaczynam dlatego proszę o pomoc w poniższym programie:
Debugowałem powyższy program i nie wiem jak poradzić sobie ze zsynchronizowaniem przerwań. Puki co zasada ma być prosta PD4 i PD5 ma się zmieniać z 0 -> 1 z częstotliwością ok 150Hz(nie posiadam oscyloskopu żeby się przekonać czy tyle naprawdę jest) zaś cały PORTB ma zmieniać swoją wartość na przeciwną co jedną sekundę. Problem w tym że gdy jestem w jednym przerwaniu drugie jest ignorowane. Jak temu zaradzić tak żeby wszystko się ładnie wykonało?
I jeszcze jedno... Aby otrzymać przerwanie timer1_compA co jedną sekundę policzyłem tak:
fosc/preskaler = 1000000/1024 = 976Hz
daje to czas ok 1.024m/s
1.024 * 976 = 1sek <- w przybliżeniu
Dlatego zrobiłem takie przypisanie:
Niestety zmiana stanu następuje zdecydowanie szybciej. Dlaczego? Czyżbym przeoczył coś w nocie katalogowej?
Zbudowałem prosty układ i chciałbym na nim nauczyć się dobrze obsługiwać i synchronizować przerwania. Jego głównym założeniem będzie liczenie co jedną sekundę do 99 na dwóch wyświetlaczach siedmiosegmentowych(obsługa "multipleksacją") z dodatkowymi opcjami(odebrać coś z komputera itp). Pisałem w C a z assemblerem dopiero zaczynam dlatego proszę o pomoc w poniższym programie:
.include "tn2313def.inc"
;-----definicje---------------------
.def tmp = r16
.def tmp2 = r17
;-----wektory przerwan--------------
.cseg
.org 0x00
rjmp reset
.org 0x04
rjmp timer1_compA
.org 0x0D
rjmp timer0_compA
;-----------------------------------
reset:
ldi tmp, 0x72
out DDRD, tmp
ldi tmp, 0xFF
out DDRB, tmp ;konfiguracja PORTB i PORTD
ldi tmp, 0x10
out PORTD, tmp ;wstepne ustawienie multipleksacji
ldi tmp, RAMEND
out SPL, tmp ;ustawienie stosu
ldi tmp, 0x01
out TCCR0B, tmp
out TCCR1B, tmp ;preskaler
ldi tmp, 0x41
out TIMSK, tmp ;wlaczenie przerwania compA dla obu timerow
ldi tmp, 0x06
out OCR0A, tmp ;comp0A = 6
ldi tmp, 0xD0
out OCR1AL, tmp
ldi tmp, 0x03
out OCR1AH, tmp ;comp1A = 976
sei
end:
rjmp end
;-----------------------------------
timer0_compA:
ldi tmp, 0x00
out TCNT0, tmp
in tmp, PORTD
ldi tmp2, 0x30
eor tmp, tmp2
out PORTD, tmp
reti
timer1_compA:
ldi tmp, 0x00
out TCNT1H, tmp
out TCNT1L, tmp
in tmp,PORTB
ldi tmp2, 0xFF
eor tmp, tmp2
out PORTB, tmp
reti
Debugowałem powyższy program i nie wiem jak poradzić sobie ze zsynchronizowaniem przerwań. Puki co zasada ma być prosta PD4 i PD5 ma się zmieniać z 0 -> 1 z częstotliwością ok 150Hz(nie posiadam oscyloskopu żeby się przekonać czy tyle naprawdę jest) zaś cały PORTB ma zmieniać swoją wartość na przeciwną co jedną sekundę. Problem w tym że gdy jestem w jednym przerwaniu drugie jest ignorowane. Jak temu zaradzić tak żeby wszystko się ładnie wykonało?
I jeszcze jedno... Aby otrzymać przerwanie timer1_compA co jedną sekundę policzyłem tak:
fosc/preskaler = 1000000/1024 = 976Hz
daje to czas ok 1.024m/s
1.024 * 976 = 1sek <- w przybliżeniu
Dlatego zrobiłem takie przypisanie:
ldi tmp, 0xD0
out OCR1AL, tmp
ldi tmp, 0x03
out OCR1AH, tmp
Niestety zmiana stanu następuje zdecydowanie szybciej. Dlaczego? Czyżbym przeoczył coś w nocie katalogowej?