ATmega8 timer/interrupt

Rasprava o AVR mikrokontrolerima, AVR projekti i drugo vezano za AVR...

Moderators: pedja089, stojke369, trax, InTheStillOfTheNight

Post Reply
User avatar
shiki
Posts: 15
Joined: 24-03-2011, 19:33
Location: Hrvatska

ATmega8 timer/interrupt

Post by shiki »

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? :D
Fala vam! :wink:
User avatar
Kizo
Pravo uznapredovao :)
Pravo uznapredovao :)
Posts: 387
Joined: 01-11-2009, 22:40
Location: Hrvatska

Re: ATmega8 timer/interrupt

Post by Kizo »

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:

Code: Select all

OCR2 = 99
Razljutim se još više pa skužim kako konfigurirati Timer2 u CTC mod sa prescalerom=1:

Code: Select all

TCCR2 = &H09
a i malo dalje piše kako uključiti compare match interrupt:

Code: Select all

TIMSK.OCIE2 = 1
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:

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
User avatar
shiki
Posts: 15
Joined: 24-03-2011, 19:33
Location: Hrvatska

Re: ATmega8 timer/interrupt

Post by shiki »

Hvala Kizo, svaka cast! :wink:

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. :D
User avatar
shiki
Posts: 15
Joined: 24-03-2011, 19:33
Location: Hrvatska

Re: ATmega8 timer/interrupt

Post by shiki »

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
User avatar
Kizo
Pravo uznapredovao :)
Pravo uznapredovao :)
Posts: 387
Joined: 01-11-2009, 22:40
Location: Hrvatska

Re: ATmega8 timer/interrupt

Post by Kizo »

Slab sam za asembler pa nisam ni gledo datašit...
Ovo:

Code: Select all

TCCR2 = &H09
nije asembler.
Asembler bi bio:

Code: Select all

LDI r24, 9
OUT TCCR2, r24
To ti je čisto postavljanje registara, koje možeš koristiti u bascomu, a možeš koristiti i već gotove Config… naredbe koje će te registre postaviti umjesto tebe. Te gotove naredbe su u jednu ruku dobre jer početnicima omogućava da odmah krenu sa programiranjem, a da nisu ni otvorili datasheet, niti znaju kako uopće dotični mikrokontroler radi. No to ti je dvosjekli mač, jer te to uči gotovanskom načinu programiranja, a prije ili kasnije ćeš naletiti na nešto što nije u Bascomu implementirano, nego se mora pješice.
Ocekivo sam da ce se interrupt dogadjat svakih 100 us (s obzirom da mega8 radi na 1Mhz)
Dobro si očekivao. :wink:
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".
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. :D
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. :D 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.
Rutina:
Timer1 = 64536
Toggle Portd.0
Return
No tu na neku preciznost zaboravi.

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
User avatar
shiki
Posts: 15
Joined: 24-03-2011, 19:33
Location: Hrvatska

Re: ATmega8 timer/interrupt

Post by shiki »

Onda bi to trebalo izgledati ovako:

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
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?
User avatar
Kizo
Pravo uznapredovao :)
Pravo uznapredovao :)
Posts: 387
Joined: 01-11-2009, 22:40
Location: Hrvatska

Re: ATmega8 timer/interrupt

Post by Kizo »

Fali ti još:

Code: Select all

$sim

Code: Select all

Config PORTD.0 = Output
i zaboravio si "a"

Code: Select all

Compare1a = 999
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.
User avatar
shiki
Posts: 15
Joined: 24-03-2011, 19:33
Location: Hrvatska

Re: ATmega8 timer/interrupt

Post by shiki »

E hvala Kizo, car si! :wink:
Post Reply