Witam
Piszę program, który ma mierzyć długość impulsu podawanego z zew. źródła jakim jest odbiornik RC, częstotliwość impulsów to 50Hz, a ich długość mieści sie w przedziale 1ms-2ms. To mój pierwszy program na AVR w którym obsługuje przerwania zew. i mam pewien problem, program już napisałem, sprawdziłem go na symulatorze i wydaje się działać poprawnie, tylko że musiałem ręcznie ustawiać flagę od przerwania INT0, po wgraniu do procesora nic sie nie dzieje tak jakby w ogóle nie było reakcji na sygnał. Nie wiem czy dobrze ustawiłem procesor, ale z tego co zrozumiałem z noty katalogowej to chyba tak ma być, poniżej zamieszczam część kodu:
Tak wygląda ustawienie procesora i tu właśnie nie wiem czy wszystko ustawiłem tak jak należy, sygnał wchodzi na nóżkę PD2 czyli INT0, przerwanie ma zostać wygenerowane podczas zbocza narastającego.
A tu jest obsługa tego przerwania:
W obsłudze przerwania włączam licznik T0 który liczy czas, i zmieniam typ reakcji na sygnał na zbocze opadające, które z kolei wyłącza T0 i z powrotem zmienia reakcje na zbocze narastające. Dokładność tego pomiaru nie jest aż tak znacząca bo muszę rozpoznać tylko czy sygnał jest mniejszy niż 1.5ms czy większy.
Procesor działa na wew. rezonatorze 1MHz, co daje chyba 1us na wykonanie jednego rozkazu, czy się mylę? Tak pokazywał symulator.
Może ktoś wie w czym tkwi problem i pomoże mi go rozwiązać?
Dziękuje i pozdrawiam
Łukasz
Piszę program, który ma mierzyć długość impulsu podawanego z zew. źródła jakim jest odbiornik RC, częstotliwość impulsów to 50Hz, a ich długość mieści sie w przedziale 1ms-2ms. To mój pierwszy program na AVR w którym obsługuje przerwania zew. i mam pewien problem, program już napisałem, sprawdziłem go na symulatorze i wydaje się działać poprawnie, tylko że musiałem ręcznie ustawiać flagę od przerwania INT0, po wgraniu do procesora nic sie nie dzieje tak jakby w ogóle nie było reakcji na sygnał. Nie wiem czy dobrze ustawiłem procesor, ale z tego co zrozumiałem z noty katalogowej to chyba tak ma być, poniżej zamieszczam część kodu:
;----------------------------------- Światła ----------------------------------------------
.nolist ;
.include "m8def.inc" ;
.list ;
.listmac ;
;--------------------------------------------------------------------------------------------
.def ACC = r16 ; r16 teraz ma nazwę acc
.def wskaznik = r17
.def ACC2 = r21
.def ACC3 = r28
;--------------------------------------------------------------------------------------------
;-------------------- Początek segmentu kodu (Code Segment) ---------------------------------
.cseg ;
.org 0 ;
rjmp ResetProcessor ;
;----------------- Tabela wektorów przerwań (Interrupt Vectors) ----------------
.org 0x001
rjmp Sygnal ;INT0
.org 0X002
rjmp Przerwanie ;INT1
.org 0x003
rjmp Przerwanie ;TIMER2-COMP
.org 0x004
rjmp Przerwanie ;TIMER2-OVF
.org 0x005
rjmp Przerwanie ;TIMER1-CAPT
.org 0x006
rjmp Przerwanie ;TIMER1-COMPA
.org 0x007
rjmp Przerwanie ;TIMER1-COMPB
.org 0x008
rjmp Przerwanie ;TIMER1-OVF
.org 0x009
rjmp Przerwanie ;TIMER0-OVF
.org 0x00A
rjmp Przerwanie ;SPI-STC
.org 0x00B
rjmp Przerwanie ;USART-RXC
.org 0x00C
rjmp Przerwanie ;USART-UDRE
.org 0x00D
rjmp Przerwanie ;USART-TXC
.org 0x00E
rjmp Przerwanie ;ADCC
.org 0x00F
rjmp Przerwanie ;EE_RDY
.org 0x010
rjmp Przerwanie ;ANA_COMP
.org 0x011
rjmp Przerwanie ;TWI
.org 0x012
rjmp Przerwanie ;SPM_RDY
Przerwanie:
reti
;---------------------------------------------------------------------------------------------
;-----------------------------Ustawienia portów----------------------------------------------
ResetProcessor: ;
cli ; zablokowanie przerwań
ldi ACC,HIGH(RAMEND) ; inicjacja stosu
out SPH,ACC ; programowego
ldi ACC,LOW(RAMEND)
out SPL,ACC
ldi ACC,0x40 ;ustawienie bitu odpowiedzialnego za akceptcję
out GICR,ACC ;przerwania INT0 w rejestrze GIMSK
ldi ACC,0x02 ;zbocze narastające na INT0 będzie
out MCUCR,ACC ;generowac przerwanie
ldi ACC,0x00
out DDRC,ACC ;cały port C jako wejściowy
out DDRD,ACC ;cały port D jako wejściowy
out PORTC,ACC ;wszystkie wyjścia portu C w stanie niskim
out PORTD,ACC ;wszystkie wyjścia portu D w stanie niskim
ldi ACC,0xFF
out DDRB,ACC ;cały port B jako wyjściowy
ldi ACC,0x00
out PORTB,ACC ;wszystkie wyjścia portu B w stanie niskim
ldi wskaznik,0x01
ldi r18,0xBC ;wartość porównawcza
ldi r19,0x04
ldi r22,0x01
ldi r23,0x00
ldi r24,0x01
ldi r25,0x00
ldi r26,0x01
ldi r27,0x00
ldi r20,0x00
ldi r30,0x00
sei ;odblokowanie przerwań
rjmp Main
Tak wygląda ustawienie procesora i tu właśnie nie wiem czy wszystko ustawiłem tak jak należy, sygnał wchodzi na nóżkę PD2 czyli INT0, przerwanie ma zostać wygenerowane podczas zbocza narastającego.
A tu jest obsługa tego przerwania:
;--------------------------------Obsługa przerwania------------------------------------------------
;--------------------------------------------------------------------------------------------------
Sygnal:
push ACC
sbrs r17,0
rjmp opadajace
rjmp narastajace
narastajace:
ldi ACC,0x03
out MCUCR,ACC ;zbocze opadające
ldi r17,0x00
ldi ACC,0x00 ;wpisz wartosć początkową licznika
out TCNT0,ACC
ldi ACC,0x03 ;włącz timer0, prescaler 8
out TCCR0,ACC
rjmp koniec
opadajace:
ldi ACC,0x02
out MCUCR,ACC ;zbocze narastające
ldi ACC,0 ;wyłącz timer0
out TCCR0,ACC
in ACC,TCNT0 ;pobierz liczbe z licznika T0
ldi r17,0x01
cp ACC,r18
brlo wylacz
brsh zalacz
zalacz:
cpi r19,0x04
breq zalaczenie
cpi r19,0x02
breq ladowanie
rjmp koniec
wylacz:
cpi r19,0x03
breq nic
cpi r19,0x01
breq wylaczenie
rjmp koniec
wylaczenie:
ldi r19,0x04
ldi r20,0x01
rjmp koniec
zalaczenie:
dec r19
ldi r20,0x02
rjmp koniec
ladowanie:
dec r19
ldi r20,0x03
rjmp koniec
nic:
dec r19
koniec:
pop ACC
reti
W obsłudze przerwania włączam licznik T0 który liczy czas, i zmieniam typ reakcji na sygnał na zbocze opadające, które z kolei wyłącza T0 i z powrotem zmienia reakcje na zbocze narastające. Dokładność tego pomiaru nie jest aż tak znacząca bo muszę rozpoznać tylko czy sygnał jest mniejszy niż 1.5ms czy większy.
Procesor działa na wew. rezonatorze 1MHz, co daje chyba 1us na wykonanie jednego rozkazu, czy się mylę? Tak pokazywał symulator.
Może ktoś wie w czym tkwi problem i pomoże mi go rozwiązać?
Dziękuje i pozdrawiam
Łukasz