Obsluga przerwan timera (AVR asm)

Jesli jesteś początkującym elektronikiem, to tu z pewnością znajdziesz pomoc. Miejsce dobre do dyskusji nad podstawami elektroniki w zakresie teorii i praktyki.
Awatar użytkownika
Amugilap
Użytkownik
Posty: 480
Rejestracja: 19 cze 2011, 9:28
Lokalizacja: UK

Obsluga przerwan timera (AVR asm)

Post autor: Amugilap » 02 cze 2012, 12:33

Hej!
Probuje napisac program ktory by wykorzytywal sprzetowy timer i o ile w debugerze wsytko dzial zgodnie z zalozeniami to po wgraniu do proca cisza tzn wygaszone diody a powinny byc zapalone, tzn bardzo szybko sie zmieniac. Spojrzy na to ktos swiezym okiem bo pomysly mi sie chyba skonczyly:

Kod: Zaznacz cały

.include "m8515def.inc"
.def acc = r16
.def tik = r25
.macro pushf
push acc
in acc,sreg
push acc
.endm

.macro popf
pop acc
out sreg,acc
pop acc
.endm

.dseg
licznik: .byte 1

;tablica wektorow przerwan
.cseg
	.org	0				;
	rjmp	ResetProcessor			;
;-----------------------------------------------------------------------------
	.org	INT0addr			;External Interrupt0 Vector Address
	reti					;
;-----------------------------------------------------------------------------
	.org	INT1addr			;External Interrupt1 Vector Address
	reti					;
;-----------------------------------------------------------------------------
	.org	ICP1addr			;Input Capture1 Interrupt Vector Address
	reti					;
;-----------------------------------------------------------------------------
	.org	OC1Aaddr			;Output Compare1A Interrupt Vector Address
	reti					;
;-----------------------------------------------------------------------------
	.org	OC1Baddr			;Output Compare1B Interrupt Vector Address
	reti					;
;-----------------------------------------------------------------------------
	.org	OVF1addr			;Overflow1 Interrupt Vector Address
	reti					;
;-----------------------------------------------------------------------------
	.org	OVF0addr			;Overflow0 Interrupt Vector Address
	rjmp	TC0OvfInterrupt			;
;-----------------------------------------------------------------------------
	.org	SPIaddr				;SPI Interrupt Vector Address
	reti					;
;-----------------------------------------------------------------------------
	.org	URXCaddr			;USART Receive Complete Int. Vector Address
	reti					;
;-----------------------------------------------------------------------------
	.org	UDREaddr			;USART Data Register Empty Int. Vector Address
	reti					;
;-----------------------------------------------------------------------------
	.org	UTXCaddr			;USART Transmit Complete Int. Vector Address
	reti					;
;-----------------------------------------------------------------------------
	.org	ACIaddr				;Analog Comparator Interrupt Vector Address
	reti					;
;-----------------------------------------------------------------------------
	.org	INT2addr			;External Interrupt2 Vector Address
	reti					;
;-----------------------------------------------------------------------------
	.org	OC0addr				;Output Compare0 Interrupt Vector Address
	reti					;
;-----------------------------------------------------------------------------
	.org	ERDYaddr			;EEPROM Interrupt Vector Address
	reti					;
;-----------------------------------------------------------------------------
	.org	SPMRaddr				;SPM complete Interrupt Vector Address;	
	reti					;
;-----------------------------------------------------------
resetprocessor:

ldi acc,high(ramend)
out sph,acc
ldi acc,low(ramend)
out spl,acc

ldi acc,0b00000101
out tccr0,acc
ldi acc,0b00000010
out timsk,acc
ldi acc,0b11111111
out ddrd,acc
out portd,acc


;-------glowna petla------------
;-------------------------------
main:
ldi r31,0
sts licznik,r31
ldi tik,0
start:
out portd,r30
bset 7
cpi tik,1
breq zmien
rjmp start

zmien:
lds r30,licznik
com r30
ldi tik,0
rjmp start
;-------koniec glownej petli----

;------------obsluga przerwania--------
TC0OvfInterrupt:
pushf
ldi tik,1
inc r31
sts licznik,r31
popf
reti

Awatar użytkownika
dondu
Użytkownik
Posty: 211
Rejestracja: 24 maja 2005, 9:47
Lokalizacja: Śląskie
Kontakt:

Post autor: dondu » 03 cze 2012, 9:44

Dla własnego dobra oraz by ułatwić chętnym sprawdzanie Twojego programu powinieneś bogato komentować kod.

Jony130
Moderator
Posty: 3170
Rejestracja: 11 sie 2005, 16:33
Lokalizacja: wrocław

Post autor: Jony130 » 03 cze 2012, 11:37

Program wygląda na poprawny. A o jakiej częstotliwości kwarcu używasz?

Awatar użytkownika
Amugilap
Użytkownik
Posty: 480
Rejestracja: 19 cze 2011, 9:28
Lokalizacja: UK

Post autor: Amugilap » 03 cze 2012, 13:30

Procesor chodzil na wewnetrzym oscylatorze 1 Mhz, ale praktycznie nie zaleznie od czestotliwosci wszsytkie diody powinny sie palic jednoczesnie (potem mialem dodac pentle spowalniajaca zeby uklad zwiekszal licznik co sekunde). Niestety procesor mi padl sam z siebie (nie zmienialem fusebitw i mial moze ze 100 cykli prgramowania wiec nie wiem dlaczego. ). Skladam wiec teraz fuse doctora i sprobuje go ozywic a w miedzyczasie czekam na dostawe procesorkow i jak tylko bede mial na czym to wroce do tego programu.

Awatar użytkownika
mr_x
Użytkownik
Posty: 385
Rejestracja: 12 gru 2010, 19:05
Lokalizacja: /bin/bash
Kontakt:

Post autor: mr_x » 03 cze 2012, 17:56

Skąd wiesz, że miał jeszcze 100 cykli? Poza tym producent podaje minimalną gwarantowaną liczbę zapisów pamięci programu.

Awatar użytkownika
Amugilap
Użytkownik
Posty: 480
Rejestracja: 19 cze 2011, 9:28
Lokalizacja: UK

Post autor: Amugilap » 03 cze 2012, 18:50

Tzn 100 cykli mial dopiero za soba, kupilem nowy a 8515 ma cos okolo 1000 co najmniej

Jony130
Moderator
Posty: 3170
Rejestracja: 11 sie 2005, 16:33
Lokalizacja: wrocław

Post autor: Jony130 » 03 cze 2012, 18:53

A tym programem to jaki efekt chwiałeś uzyskać ?

Awatar użytkownika
Amugilap
Użytkownik
Posty: 480
Rejestracja: 19 cze 2011, 9:28
Lokalizacja: UK

Post autor: Amugilap » 03 cze 2012, 19:02

Co pewien zadany czas zwiekszac licznik i wyswietlac jego zawartosc binarnie na 8 diodach podlaczonych do portu D. Podany kod nie ma jeszcze petli opozniajacej wiec licznik natychmiast sie przepelnia, wiec diody powinny sie sie palic praktycznie non stop. Prescaler licznika ustawilem na podzial przez 1024 wiec dla zegara 1MHz stan licznika zmienia sie co okolo 1ms. A u mnie diody wogole sie nie zapalaly, Wgralem inny program na proca ktory dziala poprawnie ale procek juz nie daje sie zaprogramowac...

Jony130
Moderator
Posty: 3170
Rejestracja: 11 sie 2005, 16:33
Lokalizacja: wrocław

Post autor: Jony130 » 03 cze 2012, 19:32

Prescaler 8 bitowego licznika masz ustawiony na 1024.
Czyli przerwanie od przepełniania będziesz miał co 2^8 * 1024 = 256*1024 = 262144 cykli zegara. Dla 1MHz jeden cykl trwa 1µs co daje przerwanie co 0.26s.
Ostatnio zmieniony 03 cze 2012, 20:40 przez Jony130, łącznie zmieniany 1 raz.

Awatar użytkownika
Amugilap
Użytkownik
Posty: 480
Rejestracja: 19 cze 2011, 9:28
Lokalizacja: UK

Post autor: Amugilap » 03 cze 2012, 20:35

Dzięki za poprawke, dokladnie tak :)

Awatar użytkownika
kayron
Użytkownik
Posty: 2088
Rejestracja: 21 wrz 2008, 12:53
Lokalizacja: Poland
Kontakt:

Post autor: kayron » 03 cze 2012, 20:38

A nie przypadkiem 262,144ms ? 1ms to chyba 1000us ?

Jony130
Moderator
Posty: 3170
Rejestracja: 11 sie 2005, 16:33
Lokalizacja: wrocław

Post autor: Jony130 » 03 cze 2012, 20:39

kayron pisze:A nie przypadkiem 262,144ms ? 1ms to chyba 1000us ?
Tak miało być 0.26s bez mili.

Jony130
Moderator
Posty: 3170
Rejestracja: 11 sie 2005, 16:33
Lokalizacja: wrocław

Post autor: Jony130 » 03 cze 2012, 20:53

A tak w ogóle to jaką funkcje miały pełnić te dwa makra, odkładania i ściągania ze stosu?

Kod: Zaznacz cały

.macro pushf
push acc
in acc,sreg
push acc
.endm

.macro popf
pop acc
out sreg,acc
pop acc
.endm 
Bo ja nie widzę żeby miały jakiś wpływ na program.

Awatar użytkownika
Amugilap
Użytkownik
Posty: 480
Rejestracja: 19 cze 2011, 9:28
Lokalizacja: UK

Post autor: Amugilap » 03 cze 2012, 21:40

W tym przypadku faktycznie obsluga przerwania niewiele robi i niewiele sie dzieje po powrocie z przerwania, ale kultywuje taki nawyk zeby przed wywolaniem przerwania czy funkcji zrzucac rejestr statusow na stos, wiele to nie kosztuje a czesto oszcczedza wielu problemow przy bardziej zlozonych programach

Jony130
Moderator
Posty: 3170
Rejestracja: 11 sie 2005, 16:33
Lokalizacja: wrocław

Post autor: Jony130 » 04 cze 2012, 16:43

No rzeczywiście musiałeś maić jakąś awarie uC. Bo dzisiaj wgrałem ten twój program na atmega8.

Kod: Zaznacz cały

.include "m8def.inc"
.def acc = r16
.def tik = r25
.dseg
licznik: .byte 1
.cseg
.org 0 
;tablica wektorow przerwan

rjmp ResetProcessor		; skok do początku programu
reti
reti
reti
reti
reti
reti	
reti
reti
rjmp TIM0_OVF ; przerwanie timera
reti
reti
reti
reti
reti
reti
reti
reti
reti
;-----------------------------------------------------------
resetprocessor:

ldi acc,high(ramend)
out sph,acc
ldi acc,low(ramend)
out spl,acc

ldi acc,0b00000101
out tccr0,acc
ldi acc,0b00000001
out timsk,acc
ldi acc,0b11111111
out ddrd,acc
out portd,acc


;-------glowna petla------------
;-------------------------------
main:
ldi r31,0
sts licznik,r31
ldi tik,0
start:
out portd,r30
bset 7
cpi tik,1
breq zmien
rjmp start

zmien:
lds r30,licznik
com r30
ldi tik,0
rjmp start
;-------koniec glownej petli----

;------------obsluga przerwania--------
TIM0_OVF:

ldi tik,1
inc r31
sts licznik,r31
reti 
I diody ładnie "mrugają" binarnie

ODPOWIEDZ