 |
www.elektronik.si Forum o elektrotehniki in računalništvu
|
Poglej prejšnjo temo :: Poglej naslednjo temo |
Avtor |
Sporočilo |
program_er Član


Pridružen-a: Sob 08 Mar 2008 13:47 Prispevkov: 2173 Aktiv.: 10.30 Kraj: Maribor (Pohorje)
|
Objavljeno: Sre Jul 09, 2008 11:11 pm Naslov sporočila: Timer, Counter, Interrupts |
|
|
Pozdravljeni!
Že dolgo se hočem naučit uporabo timerjev v Bascom-AVR, pa mi ne grejo in ne grejo v glavo. Nekaj časa nazaj ste mi predlagali gradivo z Bascom seminarja. Prebral sem ga, vendar se nisem naučil bistva. Prebral sem tudi Bascom-AVR Help, vse kjer piše kaj o timerjih. To moje neznanje pa mi je dok***lo v tej temi kjer bi to rabil!
Zato mi prosim lahko kdo na kratko razloži bistvo in kakšen primer kode bi bil dobrodošel.
Predvsem pa mi ne gre v glavo to: Kakšna je za vraga razlika med:
Timer0, Counter0, Int0
Config Timer0 = Counter
Config Timer0 = Timer
Kaj je Prescale? Jaz sem ga vedno dal na 1 .
Kdaj se izvede prekinitev in katera prekinitev se izvede? Kako Pauziram Timer? Sem poiskušal napisati program, pa sem tako zabredel med še sam nevem kaj! Lahko kdo napiše kak izsek kode, ki se navezuje na program LED kot senzor. Lahko to temo uporabite kot primer.
Preveč vprašanj? Upam da se bo na vsaj kakšno našel odgovor... Ta tema bi lahko bila v pomoč tudi drugim, ki jih mučijo iste težae!
Že vnaprej najlepša vam hvala za odgovore!!!
_________________ Upanje ni del naše projektne strategije.
Member of Trisat - 1. Slovenian satellite running new fault tolerant aerospace processor.
|
|
Nazaj na vrh |
|
 |
dkone Član

Pridružen-a: Sre 07 Mar 2007 18:53 Prispevkov: 2116 Aktiv.: 9.48 Kraj: Krško
|
Objavljeno: Sre Jul 09, 2008 11:21 pm Naslov sporočila: |
|
|
Tudi meni ne grejo najbolje v glavo. Zato sem preko ZS,prosil g.Vilkota,da mi razloži delovanje,ter primere kode za uporabo timerjev,mislim da je odlično razloženo,zato bom kar kopiral(upam,da ne bo g.Vilko hud )
Citiram: |
Seveda upravljam to z timerjem. Timer programiram tako, da mi v enakomernih znani intervali generira prekinitve. V prekinitveni rutini po potrebi dodam števce, ki se prebrnejo na sekundo, in postavijo zastavico-flag-bit sekunda.
V glavnem programu sprašujem ali je ta flag postavljen, in potem po potrebi štejem naprej recimo do minute. Seveda moram ta flag resetirati, da ne bi ko pridem v tej isti sekundi spet naokrog, to naredil večkrat.
Rele ima svoj števec. Če ta števec ni nič, bo rele pritegnjen. To krmilim v glavnem programu in glavni program tudi vsako minut zmanjša vrednost tega števca proti nič.
potem seveda glavni program tudi odtipava tipko in na pritisk tipke reagira kot zahtevano.
Pri AVR-ih je preprost krmiliti timer. Enostavno uporabim program, ki ti ga prilagam, in ki vanj daš zahtevane parametre, frekvenco, s katero delaš, interval, ki ga želiš, kateri timer hočeš upravljati in program ti odgovori, ali je to mogoče, in če je mogoče ti tudi generira kodo, ki jo potem z kopiraj in prilepi (copy and paste) preneseš v tvoj bascom.
Prilagam ti datoteko avrtimer.pdf, ki je pravzaprav avrtimer.exe, a ker exe datotek ne morem pripeti, sem jo preimenoval v avrtimer.pdf. Ti so seveda spet preimenjuj v avrtimer.exe in poženi. Mislim, da ne boš imel težav.
Če časovni intervali ne bodo v redu, je lahko problem v tem, da procesor ne niha na frekvenci, ki so jo podal v crystal ukazu in v timeravr program. Mene je na začetku zelo nagajalo, ker je avr kar naprej nihal na svoji frekvenci in se za priklopljeni kristal ni menil.
|
Citiram: |
Če prav razumem, tvoj procesor dela z internim oscilatorjem na 8MHz. če to drži, potem dobimo od programa, ki generira kodo sledeče za čas eno sekundo dve možnosti, ali prescale 256 ali 64. Takrat dobimo točno eno sekundo, če izberemo 1024 dobimo približno eno sekundo in sicer 999,936 msec.
Izberem prescale 256:
Koda: |
const Timer1Reload = 15625
config timer1=timer,prescale = 256
load timer1 , Timer1Reload
on ovf1 Timer1_isr
enable timer1
start timer1
enable interrupts
'Add your code here
Timer1_ISR:
load timer1, Timer1Reload
'Add your ISR code here
return
'Timer value explination
' The timer is a 16Bit timer, it overflows when the timer reaches 65536
' The AVR is running at 4000000Hz, the prescaler is 256
' Each tick is 0,064 ms - (1 / CPUSpeed in KHz ) * Prescaler
' The timer needs 15625 ticks to reach the required time ( 15625 * 0,064 = 1000ms)
' The start value for the timer must be set to 49911 so that it will overflow at 65536 after 15625 ticks
' NOTE: The load command does the inversion for you (256-value or 65536-value)
|
Timer prekinitveni podprogram dodelamo toliko, da nam postavit zastavico sekundabit: (tega moraš definirati že prej z dim
Koda: |
Timer1_ISR:
load timer1, Timer1Reload
'Add your ISR code here
set sekundabit
return
|
Sedaj lahko v glavnem programu ob vsaki postavitvi tega bita reagiramo tako, da vidimo da se nekaj dogaja v sekundnem ritmu. če imaš ledico, prižgi in ugasni ledioc, če imaš rele, naj ta škloca v sekundnem ritmu.
Koda: |
const Timer1Reload = 15625
config timer1=timer,prescale = 256
load timer1 , Timer1Reload
on ovf1 Timer1_isr
enable timer1
start timer1
enable interrupts
'Add your code here
dim sekundabit as bit
do
if sekundabit = 1 then
sekundabit = 0
if ledica = 1 then
ledica = 0
else
ledica = 1
endif
endif
loop
|
|
_________________ Denis |
|
Nazaj na vrh |
|
 |
dkone Član

Pridružen-a: Sre 07 Mar 2007 18:53 Prispevkov: 2116 Aktiv.: 9.48 Kraj: Krško
|
Objavljeno: Sre Jul 09, 2008 11:24 pm Naslov sporočila: |
|
|
Nadeljevanje:
Citiram: |
Glavni program stalno teče, tudi takrat, ko nisi na prehodu sekunde. Zato je potrebno takrat, ko se zazna trenutek, ko se ena sekunda konča in začne druga narediti preklop led diode.
Prvi if
Koda:
if sekundabit = 1
zazna konec ene sekunde in začetek druge. ker se po nekaj mikrosekundah
program v zanki vrne le sem, mora takrat biti ta bit n 0, sicer bi se
vse kar je v tem if-endif odstavku odvijalo morda 100.000 krat v tej, in vsaki prihodnji sekundi, torej stalno. To nočemo, zato takoj naredimo
Poleg tega moramo narediti delo, ki naj bi ga naredili vsako sekundo enkrat, se pravi preklop ledice. če je ledica vklopljena, ozklopiti, če je izklopljena pa vklopiti zato drugi if
Koda: |
if Ledica = 1 Then
Ledica = 0
Else
Ledica = 1
End If konec drugega if odstavka
|
Koda: |
endif konec prvega if odstavka
|
Prekinitvena rutina se bo izvajal po preteku čas, ki smo ga s parametri določili, to naj bi bila ena sekunda, torej enkrat na sekundo. Postavi zastavico sekundabit in s tem je svoje opravila, ostalo mora narediti glavni program, vključno z resetiranjem te zastavice.
|
Citiram: |
Definiramo števec minut, kolikor časa bodi rele ali ledica prižgana.
Dogovoriva se, da bo rele ali ledica prižgana vedno, kadar ta števec ne bo na nič.
Naprej definicija:
Koda:
Dim minute as byte
Potem nekje na koncu programa, v glavni zanki, ki se stalno odvija, torei izven vseh if endif odstavkov krmilimo rele na osnovi vsebine tega šrevca:
Koda: |
if minute <> 0 then
reset ledica 'prižgemo ledico
else
set ledica 'ugasnemo ledico
endif
|
Potem je potrebno vsako minuto odšteti števec minute za 1, vendar naša prekinitev šteje samo sekunde, torej potrebujemo še en števec sekund, in ko le ta doseže 60, vemo da je pretekla minuta. To naredimo v if-endif odstavku ki je pogojen z bitom sekundabit, da zagotovimo, da se dogaja samo enkrat v sekundi.
If.endif odstavek, ki resetira sekundabit moramo raziširiti tako:
Koda: |
if sekundabit = 1 then
reset sekundabit
incr sekunde
if sekunde > 60 then
sekunde = sekunde - 60
if minute <> 0 then
decr minute
endif
endif
endif
|
Sedaj moramo samo še testirati pritisk na tipko in ob pritisku postaviti števec minute na določeno vrednost, oziroma, če je rele pritegnjee, torej minute niso 0, tedaj želim ugasniti rele/ledico, tedaj pač postavimo minute na 0
Koda:
debounce tipka, 0, tipkapodprogram, sub
Nekje izven zanke glavnega programa pa napišemo podprogram, ki se izvaja vsakokrat, ko pritisnemo na tipko:
Koda: |
tipkapodprogram:
' tipka je bila pritisnjena
if minute = 0 then
'če je bil rele/ledica ugasnjema teaj
minute = 15 ' postavimo minute na določeno vrednost
else
' v obratnem slučaju izklopimo z
minute = 0
endif
return 'povratek v glavni program
|
|
_________________ Denis |
|
Nazaj na vrh |
|
 |
dkone Član

Pridružen-a: Sre 07 Mar 2007 18:53 Prispevkov: 2116 Aktiv.: 9.48 Kraj: Krško
|
Objavljeno: Sre Jul 09, 2008 11:27 pm Naslov sporočila: |
|
|
Upam,da sem nekako pomagal. Sam jih še vedno nisem osvojil,trenutno nimam časa,jih bom pa v prihodnosti.
_________________ Denis |
|
Nazaj na vrh |
|
 |
program_er Član


Pridružen-a: Sob 08 Mar 2008 13:47 Prispevkov: 2173 Aktiv.: 10.30 Kraj: Maribor (Pohorje)
|
Objavljeno: Sre Jul 09, 2008 11:30 pm Naslov sporočila: |
|
|
HVALA!
In tukaj je še najnovejša verzija AVR Timer Calculator:
Opis: |
|
 Download |
Ime datoteke: |
AVR Timer Calculator.zip |
Velikost datoteke: |
431.92 KB |
Downloadano: |
41 krat |
_________________ Upanje ni del naše projektne strategije.
Member of Trisat - 1. Slovenian satellite running new fault tolerant aerospace processor.
|
|
Nazaj na vrh |
|
 |
program_er Član


Pridružen-a: Sob 08 Mar 2008 13:47 Prispevkov: 2173 Aktiv.: 10.30 Kraj: Maribor (Pohorje)
|
Objavljeno: Sre Jul 09, 2008 11:37 pm Naslov sporočila: |
|
|
Ja malo bolj razumem. Samo to je že generiranje sekund in minut.
Jaz pa sem imel v mislih čisto enostavno definiranje Timerja0 in kar štetje taktov oscilatorja. Upam da se bo g. Vilko še sam kaj javil in malo razložil.
Kolikor vem lahko Timer prekinjamo ai z Overflovom ali z zunanjo prekinitvijo na Int0 ali pa Int1. Tudi to mi ne gre v glavo...
_________________ Upanje ni del naše projektne strategije.
Member of Trisat - 1. Slovenian satellite running new fault tolerant aerospace processor.
|
|
Nazaj na vrh |
|
 |
program_er Član


Pridružen-a: Sob 08 Mar 2008 13:47 Prispevkov: 2173 Aktiv.: 10.30 Kraj: Maribor (Pohorje)
|
Objavljeno: Sre Jul 09, 2008 11:52 pm Naslov sporočila: |
|
|
Naprimer iziv bi bil, da bi skupaj naredili delujočo kodo LED kot senzor.bas za ATmegoXX in se ob tem tudi kaj naučili.
_________________ Upanje ni del naše projektne strategije.
Member of Trisat - 1. Slovenian satellite running new fault tolerant aerospace processor.
|
|
Nazaj na vrh |
|
 |
dragoon Član


Pridružen-a: Čet 03 Maj 2007 21:51 Prispevkov: 452 Aktiv.: 2.04 Kraj: Trojane
|
Objavljeno: Čet Jul 10, 2008 10:53 am Naslov sporočila: |
|
|
Timerji imajo dva načina delovanja: counter in timer. razlika med timerji je še v obmoičju štetja - 16 bitov ali 8 bitov.
counter mode: timerju se poveča vrednost pri vsakem impulzu na pripadajočem pinu (capture timer). uporabno za štetje impulzov. s prescale nastavimo delilnik timerja, če je 256 potem se za vsakih 256 impulzov na capture pinu vrednost timerja poveča za 1.
timer mode: tukaj pa timer šteje delovni takt procesorja, capture pin ni v uporabi. delilnik spet deli frekvenco. če imamo delilnik na 2, frekvenco procesorja 8mhz, potem se timerju povečuje vrednost z 4mhz.
prekinitve: timer lahko generira prekinitev ko doseže vrh (0xff pri 8b, 0xffff pri 16b), ko je njegova vrednost enaka vrednosti v ocr registru,.... ko generira prekinitev se lahko resetira ( začne šteti od 0), lahko se mu začne zmanjševati vrednost proti 0, lahko pa normalno šteje naprej... glej datasheet za različne načine delovanja (pwm, frek generator,...)
katera funkcija se ti bo izvedla ob prekinitvi enostavno določiš na začetku pri nastavljanju timerja.
timer s prekinitvami prekinja glavni program, in ne obratno. ko se prekinitvena rutina izvede do konca se nadaljuje glavni program od tam kjer je bil prekinjen.
vrednost timerja lahko kadarkoli prebereš, pač bereš vrednost registra.
int0, int1,int2 nimajo veze s timerji. to so prekinitve, ki jih prožiš z spremembo stanja na pripadajočih pinih.
beri datasheet.
_________________ LP, Mitja |
|
Nazaj na vrh |
|
 |
program_er Član


Pridružen-a: Sob 08 Mar 2008 13:47 Prispevkov: 2173 Aktiv.: 10.30 Kraj: Maribor (Pohorje)
|
Objavljeno: Čet Jul 10, 2008 12:14 pm Naslov sporočila: |
|
|
Sem že prebiral datasheet.
dragoon je napisal/a: |
...na začetku pri nastavljanju timerja. |
Lahko kdo napiše primer enostavne nastavitve, da bi Timer deloval kot timer, ko bi bil overflow bi se izvedla prekinitev TPrekinitev.
_________________ Upanje ni del naše projektne strategije.
Member of Trisat - 1. Slovenian satellite running new fault tolerant aerospace processor.
|
|
Nazaj na vrh |
|
 |
dragoon Član


Pridružen-a: Čet 03 Maj 2007 21:51 Prispevkov: 452 Aktiv.: 2.04 Kraj: Trojane
|
Objavljeno: Čet Jul 10, 2008 1:07 pm Naslov sporočila: |
|
|
Koda: |
'The following code shows how to use the TIMER0 in interrupt mode
'The code is block remarked with '( en ')
'(
'Configute the timer to use the clock divided by 1024
Config Timer0 = Timer , Prescale = 1024
'Define the ISR handler
On Ovf0 Tim0_isr
'you may also use TIMER0 for OVF0, it is the same
Enable Timer0 ' enable the timer interrupt
Enable Interrupts 'allow interrupts to occur
Do
'your program goes here
Loop
'the following code is executed when the timer rolls over
Tim0_isr:
Print "*";
Return
') |
kopirano direktno iz help. izvede se Tim0_isr, lahko bi dal namesto tega tudi tprekinitev: On Ovf0 Tprekinitev ali On TIMER0 Tprekinitev . Po mojem izračunu dobiš pri 1mhz taktu 4 zvezdice na sekundo. namesto print * bi dal lahko naprimer not PORTRB.0 in ledko na portb.0.
ti napipšem še v Cju?
_________________ LP, Mitja |
|
Nazaj na vrh |
|
 |
vilko Član



Pridružen-a: Pet 13 Feb 2004 10:26 Prispevkov: 3365 Aktiv.: 14.17 Kraj: Dragomer
|
Objavljeno: Čet Jul 10, 2008 3:57 pm Naslov sporočila: Hm |
|
|
program_er je napisal/a: |
Ja malo bolj razumem. Samo to je že generiranje sekund in minut.
Jaz pa sem imel v mislih čisto enostavno definiranje Timerja0 in kar štetje taktov oscilatorja. Upam da se bo g. Vilko še sam kaj javil in malo razložil.
Kolikor vem lahko Timer prekinjamo ai z Overflovom ali z zunanjo prekinitvijo na Int0 ali pa Int1. Tudi to mi ne gre v glavo... |
hja, v enem taktu oscilatorja, ki poganja mikroprocesor, se ne da kaj veliko narediti, niti prikazati rezultat štetja. če pa si mislil štetje inpulzov nekega drugega - zunanjega oscilatorja izven mikroprocesorja, potem je to nekaj drugega.
Potem nekako potrebuješ dva timerja, recimo timer0 in timer1. en timer (=timer) ti bo zagotovil točen čas ene sekunde, na začetku sekunde boš dal start ukaz za drugi timer, na koncu sekunde stop ukaz za ta drugi timer, (conuter) ki je predviden ko števec, bo ta čas štel inpulze merjenega oscilatorja in na koncu sekunde lahko ta števec imaš v neki spremenljivki in ga prikažeš.
Tisto z overflowom naj te ne bega. Tisto je razlaga, kako interno dela timer. Šteje pač nekaj v nekem registru, in ko gre števec preko ničle (kot pri avtomobilu preko 1000000km) gre spet na 0 a takrat generira prekinitev, ki pa je lahko ignorirana (disable) ali dopuščena (enable) a v drugem slučaju moraš imeti za ta namen predvideno programsko kodo, ki bo pač nekaj, kar hočeš naredila.
Pri prvem timerju (=timer) se prekinitev uporabi za merjenje časa, v sekunde in naprej, pri drugem pa, se prekinitev uporabi, če je spoh potrebno, za zaznavo, da je število v števcu napačno, in je prekoračena kapaciteta števca ( analogija, avto ima preko 1000000 km a števec kaže 10000km )
_________________ Nihče ni za vojno in vsi so za mir,
vsi so za bratstvo, nihče za prepir.
Od same ljubezni vsak čas na granatah
bo vtisnjeno geslo: "Darilo za brata"
Janez Menart |
|
Nazaj na vrh |
|
 |
program_er Član


Pridružen-a: Sob 08 Mar 2008 13:47 Prispevkov: 2173 Aktiv.: 10.30 Kraj: Maribor (Pohorje)
|
Objavljeno: Ned Jul 13, 2008 10:37 pm Naslov sporočila: |
|
|
Pa ne gre mi no! Sicer sem nekaj probaval v Bascom-AVR pa mi je zaštekalo oziroma spoh ne vem, če se začel prav. Tukaj je moja koda:
Koda: |
' Bojan Potočnik
'*******************************************************************************
' LED DIODA KOT TOUCH SENZOR
'*******************************************************************************
$regfile = "m8def.dat"
$crystal = 1000000
'-------------------------------------------------------------------------------
Config Portb.0 = Output
Config Portb.1 = Output
'-------------------------------------------------------------------------------
Katoda Alias Portb.1
Anoda Alias Portb.0
'-------------------------------------------------------------------------------
Const Timer0reload = 131
Config Timer0 = Timer , Prescale = 8
Load Timer0 , Timer0reload
On Timer0 Prekinitev
'-------------------------------------------------------------------------------
Enable Timer0
Enable Interrupts
'===============================================================================
Do
Portb = 0
Katoda = 0
Anoda = 1
Waitms 5
Katoda = 1
Anoda = 0
Config Portb.0 = Input
'Tu mi zašteka! Kako naj timerju povem, da naj
'neha štet, ko je Anoda na 0. In ko bi nehal štet,
'naj pogleda svojo vrednost in če je manj kot
'50 naj gre v Prekinitev, če pa je več kot 50
'pa naj se program tukaj nadaljuje, oziroma
'gre od začetka.
Loop
Prekinitev:
Load Timer0 , Timer0reload
Config Portb.0 = Output
Config Portb.1 = Output
Katoda = 0
Anoda = 1
Waitms 500
Anoda = 0
Waitms 500
Return
End
|
Tam ko sem napisal da mi zašteka, tam res ne vem, kako naprej. Kaj mi lahko popravite kodo, da bo delovala, ko bi morala (več v tej temi)?
_________________ Upanje ni del naše projektne strategije.
Member of Trisat - 1. Slovenian satellite running new fault tolerant aerospace processor.
|
|
Nazaj na vrh |
|
 |
vilko Član



Pridružen-a: Pet 13 Feb 2004 10:26 Prispevkov: 3365 Aktiv.: 14.17 Kraj: Dragomer
|
Objavljeno: Pon Jul 14, 2008 8:59 am Naslov sporočila: Samo na brzino |
|
|
Samo na brzino. Nisem preštudiral tvoj program. A kar vidim na prvi pogled:
Ukaz wait in waitms imata kot parameter en bajt in je navišja vrednost, ki jo lakho zahtevaš od njega 255
Ko bom imel čas, bom pogledal malo več.
_________________ Nihče ni za vojno in vsi so za mir,
vsi so za bratstvo, nihče za prepir.
Od same ljubezni vsak čas na granatah
bo vtisnjeno geslo: "Darilo za brata"
Janez Menart |
|
Nazaj na vrh |
|
 |
vilko Član



Pridružen-a: Pet 13 Feb 2004 10:26 Prispevkov: 3365 Aktiv.: 14.17 Kraj: Dragomer
|
Objavljeno: Pon Jul 14, 2008 9:02 am Naslov sporočila: Pa še to |
|
|
Pa še to na brzino:
program_er je napisal/a: |
Kako naj timerju povem, da naj
'neha štet, |
Stop Timer je ukaz
_________________ Nihče ni za vojno in vsi so za mir,
vsi so za bratstvo, nihče za prepir.
Od same ljubezni vsak čas na granatah
bo vtisnjeno geslo: "Darilo za brata"
Janez Menart |
|
Nazaj na vrh |
|
 |
program_er Član


Pridružen-a: Sob 08 Mar 2008 13:47 Prispevkov: 2173 Aktiv.: 10.30 Kraj: Maribor (Pohorje)
|
Objavljeno: Pon Jul 14, 2008 9:26 am Naslov sporočila: Re: Samo na brzino |
|
|
vilko je napisal/a: |
Ukaz wait in waitms imata kot parameter en bajt in je navišja vrednost, ki jo lakho zahtevaš od njega 255 |
To vem. Toda Bascom ima v sebi že generiran taki programček, ki zazna take napake in jih pri prevajanju razbije na pravilne. Meni vedno pravilno deluje. Tudi Waitms 963 in Waitms 1005 mi lepo delujeta (praqvilen čas). Probaj!
_________________ Upanje ni del naše projektne strategije.
Member of Trisat - 1. Slovenian satellite running new fault tolerant aerospace processor.
|
|
Nazaj na vrh |
|
 |
|
|
Ne, ne moreš dodajati novih tem v tem forumu Ne, ne moreš odgovarjati na teme v tem forumu Ne, ne moreš urejati svojih prispevkov v tem forumu Ne, ne moreš brisati svojih prispevkov v tem forumu Ne ne moreš glasovati v anketi v tem forumu Ne, ne moreš pripeti datotek v tem forumu Ne, ne moreš povleči datotek v tem forumu
|
Uptime: 8 dni
Powered by phpBB © 2001, 2005 phpBB Group
|