ATmega8 timer/interrupt
Moderators: pedja089, stojke369, trax, InTheStillOfTheNight
ATmega8 timer/interrupt
Vozdra raja!
Malo se igram s megom8 pa naletio na problem. Htio bi tako konfigurirat timer da se nakon svakih 100 pulseva takta generira interrupt i odradi rutina (prescaler je 1). Koristim Bascom AVR i u njegovom helpu nisam naso nist pametno. Jel bi netko bio voljan pomoc mi u tom naumu?
Fala vam!
Malo se igram s megom8 pa naletio na problem. Htio bi tako konfigurirat timer da se nakon svakih 100 pulseva takta generira interrupt i odradi rutina (prescaler je 1). Koristim Bascom AVR i u njegovom helpu nisam naso nist pametno. Jel bi netko bio voljan pomoc mi u tom naumu?
Fala vam!
Re: ATmega8 timer/interrupt
Vozdra i tebi!
Da, baš je gadan taj help kad nema ništa pametno, neznam kome se je dalo pisati same gluposti.
Ne preostaje nam ništa drugo nego se jako razljutiti, dapače, totalno poluditi i otvoriti datašit, te pročitati odjeljak o tajmerima.
E, upravo tamo se spominje neki CTC mod. Piše: Clear Timer on Compare match ili u prijevodu: zbriši tajmer ak se nekaj poklopi.
I tako ja odaberem Timer2, pogledam malo bolje i vidim da OCR2 registar definira vrijednost dokle će naš timer brojati. Pa pošto želim da mi registrira svaki 100-ti takt, pišem:
Razljutim se još više pa skužim kako konfigurirati Timer2 u CTC mod sa prescalerom=1:
a i malo dalje piše kako uključiti compare match interrupt:
Srećom po nas, ne moramo ništa od toga napraviti, te tražiti sve te silne registre jer bascom ima za to predviđene gotove naredbe, pa onda program izgleda:
Da, baš je gadan taj help kad nema ništa pametno, neznam kome se je dalo pisati same gluposti.
Ne preostaje nam ništa drugo nego se jako razljutiti, dapače, totalno poluditi i otvoriti datašit, te pročitati odjeljak o tajmerima.
E, upravo tamo se spominje neki CTC mod. Piše: Clear Timer on Compare match ili u prijevodu: zbriši tajmer ak se nekaj poklopi.
I tako ja odaberem Timer2, pogledam malo bolje i vidim da OCR2 registar definira vrijednost dokle će naš timer brojati. Pa pošto želim da mi registrira svaki 100-ti takt, pišem:
Code: Select all
OCR2 = 99
Code: Select all
TCCR2 = &H09
Code: Select all
TIMSK.OCIE2 = 1
Code: Select all
'initilize hardware
Config Timer2 = Timer , Prescale = 1 , Clear Timer = 1
'define interrupts
On Oc2 Timer2_comp_vect
'auto reload
COMPARE2 = 99
'enable interrupts
Enable Oc2
Enable Interrupts
'---Main Program---
Do
'do something fun here
Loop
End
'---The Interrupt Handler for the Timer2 Compare Match Vector---
Timer2_comp_vect:
'do something fun here
Return
Re: ATmega8 timer/interrupt
Hvala Kizo, svaka cast!
Slab sam za asembler pa nisam ni gledo datašit a ne mogu ni rec da nest rasturam AVR arhitekturu jer sam tek krenuo s tim.
E sad, jos par pitanja. Nemam sad programator kod sebe pa sam bio osudjen na simulaciju. Ocekivo sam da ce se interrupt dogadjat svakih 100 us (s obzirom da mega8 radi na 1Mhz) al u simulaciji se interrupt rutina moze pokrenut samo ak se stisne na onaj gumb OC2 medju interruptima al to nije ono što ja zelim. Ak je tako onda onaj Compare2 = 99 nema nikakvog smisla kad kontroler ionak ceka vanjski interrupt. E sad, pitanje je kak je to u"stvarnosti".
E da, jel postoji neki Compare a da je 16-bitni broj. Vidio sam u datašitu da postoji 16-bitni timer/counter al tu je mom krhkom znanju kraj.
Slab sam za asembler pa nisam ni gledo datašit a ne mogu ni rec da nest rasturam AVR arhitekturu jer sam tek krenuo s tim.
E sad, jos par pitanja. Nemam sad programator kod sebe pa sam bio osudjen na simulaciju. Ocekivo sam da ce se interrupt dogadjat svakih 100 us (s obzirom da mega8 radi na 1Mhz) al u simulaciji se interrupt rutina moze pokrenut samo ak se stisne na onaj gumb OC2 medju interruptima al to nije ono što ja zelim. Ak je tako onda onaj Compare2 = 99 nema nikakvog smisla kad kontroler ionak ceka vanjski interrupt. E sad, pitanje je kak je to u"stvarnosti".
E da, jel postoji neki Compare a da je 16-bitni broj. Vidio sam u datašitu da postoji 16-bitni timer/counter al tu je mom krhkom znanju kraj.
Re: ATmega8 timer/interrupt
Uspio sam nest napravit sto je proslo kompajler i u biti radi iako se opet treba dat signal za overflow za timer1. Kizo, aj pliz baci oko pa reci kak ti se cini. Program bi trebao mijenjati stanje na portd.0 svake milisekunde.
Code: Select all
$regfile = "m8def.dat"
$crystal = 1000000
Config Timer1 = Timer , Prescale = 1
Timer1 = 64536
On Timer1 Rutina
Enable Timer1
Enable Interrupts
Do
Loop
Rutina:
Toggle Portd.0
Return
Re: ATmega8 timer/interrupt
Ovo:Slab sam za asembler pa nisam ni gledo datašit...
Code: Select all
TCCR2 = &H09
Asembler bi bio:
Code: Select all
LDI r24, 9
OUT TCCR2, r24
Dobro si očekivao.Ocekivo sam da ce se interrupt dogadjat svakih 100 us (s obzirom da mega8 radi na 1Mhz)
Ni kod mene ne radi u zimulatoru, no u stvarnosi naravno radi. Doduše baš taj primjer nebi dobro radio, jedino zato jer se interapt rutina zove svakih 100 ciklusa, a njeno izvršavanje traje 116 ciklusa.al u simulaciji se interrupt rutina moze pokrenut samo ak se stisne na onaj gumb OC2 medju interruptima al to nije ono što ja zelim. Ak je tako onda onaj Compare2 = 99 nema nikakvog smisla kad kontroler ionak ceka vanjski interrupt. E sad, pitanje je kak je to u"stvarnosti".
Tu priču kako to riješiti ostavimo za drugi put, ukratko, trebalo bi koristiti nosave opciju i ručno PUSHati i POPati GP registre koje se koriste u interapt rutini ili cijelu rutinu napisati u asembleru.
Kako kažeš da tek počinješ, ne trebaš se sa time zamarati, rijetko kada je baš potreban tako uski tajming. Ako ti je presporo, pikneš brži kristal i vozi. Samo treba obratiti pažnju na ovaj slučaj kada duže traje izvršavanje interapt rutine nego njezino zvanje.
Što se tiče zadnjeg programa, on će dati overflow nakon 1ms, ali samo prvi put nakon pokretanja, a onda ćeš imati svakih 65.536ms.
Tu imaš dvije opcije. Možeš u interapt rutini svaki put ponovno upisati vrijednost timera.
No tu na neku preciznost zaboravi.Rutina:
Timer1 = 64536
Toggle Portd.0
Return
Ako hoćeš točnu milisekundu, koja ovisi samo o toleranciji kristala, koristi Timer1 u CTC modu po uzoru na prvi program. Hint: Top = OCR1A
Re: ATmega8 timer/interrupt
Onda bi to trebalo izgledati ovako:
Sad je to 16-bitni timer koji odradjuje toggle svake ms.
Kako si izracunao da izvrsavanje rutine traje 116 cikljusa? U datasheetu sam nasao trajanje asemblerskih naredbi al kak znas za bascom?
Code: Select all
$regfile = "m8def.dat"
$crystal = 1000000
Config Timer1 = Timer , Prescale = 1 , Clear Timer = 1
On Oc1a Rutina
Compare1 = 999
Enable Oc1a
Enable Interrupts
Do
Loop
Rutina:
Toggle Portd.0
Return
Kako si izracunao da izvrsavanje rutine traje 116 cikljusa? U datasheetu sam nasao trajanje asemblerskih naredbi al kak znas za bascom?
Re: ATmega8 timer/interrupt
Fali ti još:
i zaboravio si "a"
U simulaciji uključi "sim timers" i "refresh variables" i to mora raditi.
Cikluse vidiš pri dnu lijevo i onda izvršavaš naredbe korak po korak da vidiš koliko pojedini dio traje.
Code: Select all
$sim
Code: Select all
Config PORTD.0 = Output
Code: Select all
Compare1a = 999
Cikluse vidiš pri dnu lijevo i onda izvršavaš naredbe korak po korak da vidiš koliko pojedini dio traje.
Re: ATmega8 timer/interrupt
E hvala Kizo, car si!