www.elektronik.si Seznam forumov www.elektronik.si
Forum o elektrotehniki in računalništvu
 
 PomočPomoč  IščiIšči  Seznam članovSeznam članov  SkupineSkupine  StatisticsStatistika  AlbumAlbum  DatotekeFilemanager DokumentacijaDocDB LinksPovezave   Registriraj seRegistriraj se 
  PravilaPravila  LinksBolha  PriponkePriponke  KoledarKoledar  ZapiskiZapiski Tvoj profilTvoj profil Prijava za pregled zasebnih sporočilPrijava za pregled zasebnih sporočil PrijavaPrijava 

Uporaba Arduino timer-jev
Pojdi na stran 1, 2, 3  Naslednja
 
Objavi novo temo   Odgovori na to temo   Printer-friendly version    www.elektronik.si Seznam forumov -> Arduino sekcija
Poglej prejšnjo temo :: Poglej naslednjo temo  
Avtor Sporočilo
KlemenD
Član
Član



Pridružen-a: Sre 18 Maj 2011 15:08
Prispevkov: 188
Aktiv.: 1.20
Kraj: Maribor

PrispevekObjavljeno: Tor Okt 28, 2014 5:53 am    Naslov sporočila:  Uporaba Arduino timer-jev Odgovori s citatom

Pozdravljeni,

Lotil sem se učenja o AVR timer-jih.
Za začetno razumevanje mi je bila zelo v pomoč ta stran LINK, ki sem jo dobro preučil nato pa na Arduinu poskusil še sam z tole kodo (čisto začetni nivo, najprej bi rad osvojil osnove...):
Koda:

void setup(){
pinMode(8, OUTPUT);

cli();//stop interrupts

  TCCR0A = 0;// set entire TCCR0A register to 0
  TCCR0B = 0;// same for TCCR0B

  TCNT0  = 0;
  TCCR0B |= (1 << CS00);   

sei();//allow interrupts

}

void loop()  {
        if (TCNT0 >= 100){
       digitalWrite(8, digitalRead(8)^1);
       TCNT0 = 0;     
        }
}



No, ko kodo poženem se na pinu 8 res pojavijo neki kvadratki, vendar je njihova frekvenca nesmiselna in se ne ujema s kodo. Kaj bi lahko bilo narobe ?

Dodatna razlaga:
Če je moje razumevanje pravilno, bi pri tej kodi moral biti čas enega tika timer-ja 1/(16x10^6) = 0.0625 uS, kar pomeni, da bo čas 100 tikov 100x0.0625=6.25uS. Vsaj približno toliko bi moral biti tudi Ton in Toff generiranih kvadratkov, pa je daleč od tega (preverjeno z osciloskopom). Če spreminjam vrednost v if izjavi, torej koliko tikov naj šteje se frekvenca generiranih kvadratkov spreminja nesmiselno, ali pa se sploh ne spremeni.

Hvala za pomoč !
Lp,
Klemen
Nazaj na vrh
Skrit Poglej uporabnikov profil Pošlji zasebno sporočilo
rudiP
Član
Član



Pridružen-a: Tor 07 Avg 2007 15:30
Prispevkov: 1234
Aktiv.: 6.09
Kraj: KOPER

PrispevekObjavljeno: Tor Okt 28, 2014 7:35 am    Naslov sporočila:   Odgovori s citatom

Manjka ti ISR rutina. V ISR skoči mikro ko pride do interupta in tu menjaš stanje na izhodnem pinu. Tako kot si napisal se program vrti v neskončni zanki in spreminjanje
stanja pina je odvisno le od hitrosti na kateri dela mikro. Kar imaš sedaj v loopu moraš
dat v ISR in bo prekinitev delala.

http://www.instructables.com/id/Arduino-Timer-Interrupts/

_________________
Lep pozdrav iz Kopra Rudi
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
Peter123
Član
Član



Pridružen-a: Tor 13 Jan 2009 15:34
Prispevkov: 1364
Aktiv.: 7.37
Kraj: Lj.

PrispevekObjavljeno: Tor Okt 28, 2014 8:20 am    Naslov sporočila:   Odgovori s citatom

Načinov uporabe timerjev je več, ampak najbolj pogosta je kot že omenjeno z ISR "stavkom".

In sicer timer vedno šteje ne glede na to kaj počne mcu.
Ko pride timer na 0 ali naredi over flow potem mcu prekine delo in izvede ISR "stavek".
Zelo pomembno: ISR "stavek" mora biti čim krajši!
Ponavadi vsebuje vsaj seštevanje spremenljivke npr.: a++; ali podobno.

V glavni zanki pa imaš če je a enak temo potem izvedeš...
Seveda je lahko zelo mikavno podaljšati ISR za še nekaj ukazov vendar se lahko pojavijo napake v komunikaciji (uart ali kaki drugi), saj ko mcu izvaja ISR vse ostalo stoji. So tudi drugi problemi, ki lahko nastopijo z uporabo predolge isr zanke.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
dejko1
Član
Član



Pridružen-a: Ned 16 Mar 2008 0:21
Prispevkov: 265
Aktiv.: 1.36
Kraj: Ljubljana

PrispevekObjavljeno: Tor Okt 28, 2014 10:30 am    Naslov sporočila:   Odgovori s citatom

Predlagam da najprej poskusiš zadevo izvesti malo počasneje Wink

Če so mikrosekunde nekaj kar res rabiš v programu ki bi ga rad naredil boš pa kmalu ugotovil da so funkcije digitalWrite in digitalRead precej počasne...
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Obišči avtorjevo spletno stran
KlemenD
Član
Član



Pridružen-a: Sre 18 Maj 2011 15:08
Prispevkov: 188
Aktiv.: 1.20
Kraj: Maribor

PrispevekObjavljeno: Tor Okt 28, 2014 3:27 pm    Naslov sporočila:   Odgovori s citatom

Pozdravljeni,

kako bi pa z ISR stavki naredil tole:

-timer mora pri frekvenci 16MHz štet 400 tikov (uporabil bi timer 1).
-ko prešteje 400 tikov (399 če štejem 0) se resetira na nič.
-ob poljubnem številu tikov (npr. 50, 150, 300, 350) bi rad prožil različne ISR stavke.

Ali je kakšna hitrejša koda, ki naredi isto kot: (digitalWrite(x, digitaRead(x)^1) torej da vsakič, ko progrem stopi v ISR rutino samo pogleda stanje pina in ga spremeni na nasprotno od tega.

Opis delovanja, ki ga z to kodo želim doseči:
Želim, da mi Arduino generira dva 40 kHz signala, kjer bi lahko drugi signal relativno na prvega pomikal poljubno iz faze. 400 tikov bi potem predstavljalo celotno periodo mojega 40 kHz signala. 1/(40*10^3) = 25 uS; 400 tikov pa je 400 * 0.0625uS = 25uS. Torej en pin bi šel on ob 0 oz. ob overfolow-u potem pa off ob 199 tikov. Drugi pa bi šel on (nekje med 0-199 tiki) off pa po 200 tikih za tem ko bi šel on. Takole bi lahko poljubno nastavljal fazo signala dva relativno na signal ena... Ne znam pa tega zapisat v kodi Sad

Lep pozdrav,
Klemen
Nazaj na vrh
Skrit Poglej uporabnikov profil Pošlji zasebno sporočilo
gumby
Član
Član



Pridružen-a: Sob 28 Apr 2007 12:32
Prispevkov: 4066
Aktiv.: 19.74

PrispevekObjavljeno: Tor Okt 28, 2014 3:37 pm    Naslov sporočila:   Odgovori s citatom

50 impulzov pri 16MHz pomeni prekinitev na vsake 3,13 mikrosekunde. Pri 20MHz clocku to pomeni 62 strojnih ukazov procesorja.
Samo za občutek, v kaj se podajaš Smile

_________________
Tule nisem več aktiven.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
tilz0R
Član
Član



Pridružen-a: Čet 31 Maj 2012 15:39
Prispevkov: 898
Aktiv.: 6.24
Kraj: Črnomelj

PrispevekObjavljeno: Tor Okt 28, 2014 3:42 pm    Naslov sporočila:   Odgovori s citatom

KlemenD, piši "AVR" style v register PIN.

Poglej na katerem portu je tvoj pin in naredi nekako tako:

Koda:

//Toggle bit
PINx = 1 << bit_tvojega_pina;


PS: Predpostavljam da uporabljaš Arduino z AVR-jem.

_________________
Knowledge sharing is caring.
majerle.eu | stm32f4-discovery.net


Nazadnje urejal/a tilz0R Tor Okt 28, 2014 3:48 pm; skupaj popravljeno 1 krat
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Obišči avtorjevo spletno stran
KlemenD
Član
Član



Pridružen-a: Sre 18 Maj 2011 15:08
Prispevkov: 188
Aktiv.: 1.20
Kraj: Maribor

PrispevekObjavljeno: Tor Okt 28, 2014 3:46 pm    Naslov sporočila:   Odgovori s citatom

Pozdravljen,

da, res je vse skupaj malo na tesno... No, ampak poskusim lahko Smile bom že potem videl, če bodo kvadratki dovolj stabilni za mojo aplikacijo... če ne iščem drugo rešitev. Tako ali tako je 40kHz v elektronskem svetu zelo malo, pa ne bi smelo bit problema...upam Smile
Nazaj na vrh
Skrit Poglej uporabnikov profil Pošlji zasebno sporočilo
KlemenD
Član
Član



Pridružen-a: Sre 18 Maj 2011 15:08
Prispevkov: 188
Aktiv.: 1.20
Kraj: Maribor

PrispevekObjavljeno: Tor Okt 28, 2014 3:52 pm    Naslov sporočila:   Odgovori s citatom

tilz0R pardon sploh nisem napisal. Da, sklepaš pravilno uporabljam arduino uno (ATmega328). Hvala za nasvet !
Nazaj na vrh
Skrit Poglej uporabnikov profil Pošlji zasebno sporočilo
igo
Član
Član



Pridružen-a: Sre 11 Okt 2006 19:11
Prispevkov: 3638
Aktiv.: 17.11

PrispevekObjavljeno: Tor Okt 28, 2014 4:05 pm    Naslov sporočila:   Odgovori s citatom

Arduino je super za počasne stvari. Ko gre zares in ti nič ne deluje, se zakoplješ v knjižnice ter ugotoviš, da je potrebnih 12 ciklov za navadno spremembo stanja pina.

V glavnem začni preučevati AVR Zbirnik.

Tam v parih ukazih napolniš timer in primerjalne registre, vmes preveriš vhode in spremeniš izhode, na koncu pa še v goto zanki v miru počakaš na naslednjo prekinitev. Mimogrede ob prekinitvi na LCD pošlješ en E=1, naslednjič E=0, do naslednjega E=1 pa pripraviš nov nibble.

_________________
Teoretično je praksa posledica teorije, praktično je pa ravno obratno. (igo 2001)
LP, Igor
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
dejko1
Član
Član



Pridružen-a: Ned 16 Mar 2008 0:21
Prispevkov: 265
Aktiv.: 1.36
Kraj: Ljubljana

PrispevekObjavljeno: Tor Okt 28, 2014 4:29 pm    Naslov sporočila:   Odgovori s citatom

Timer0 in timer2 omogočata na obeh PWM izhodih možnost toggle on match, mogoče bi to delovalo...

Če uporabiš timer v PWM generation načinu potem timer sam od sebe (brez intervencije procesorja) generira signal, ti pa iz programa samo vnašaš vrednosti.

Edit: Vsi timerji znajo toggle on match ne samo timer0 in timer2.


Nazadnje urejal/a dejko1 Tor Okt 28, 2014 6:57 pm; skupaj popravljeno 1 krat
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Obišči avtorjevo spletno stran
KlemenD
Član
Član



Pridružen-a: Sre 18 Maj 2011 15:08
Prispevkov: 188
Aktiv.: 1.20
Kraj: Maribor

PrispevekObjavljeno: Tor Okt 28, 2014 5:04 pm    Naslov sporočila:   Odgovori s citatom

dejko1 priznam, da se mi trenutno ne sanja, kako bi s tem dosegel dve enaki frekvenci z poljubno razliko v fazi.

Sedaj najprej nekoga prosim, da mi napiše, kako uporabljam ISR stavke.
Naprimer pustim timer1 (16-bit), da šteje vseh svojih 65536 tikov, nato pa se resetira. Jaz pa želim sprožit naprimer 4 različne ISR funkcije (kadar bo timer naštel 4000 tikov, 10000 tikov, 30000 tikov in 50000 tikov) . Iz literature, ki sem jo tem izbrskal na spletu se žal ne znajdem Brick wall
Nazaj na vrh
Skrit Poglej uporabnikov profil Pošlji zasebno sporočilo
tilz0R
Član
Član



Pridružen-a: Čet 31 Maj 2012 15:39
Prispevkov: 898
Aktiv.: 6.24
Kraj: Črnomelj

PrispevekObjavljeno: Tor Okt 28, 2014 5:09 pm    Naslov sporočila:   Odgovori s citatom

Klemen, naredi interrupte, da bo vsakih 10000 ciklov interrupt.

Ustvari statično spremenljivko znotraj ISR funkcije in preverjaj njeno stanje.

Koda:

ISR() {
 static uint8_t i = 0;
 if (i == 0) {
  //interrupt prvič
  //delaj svoje
  i = 1;
 } else if (i == 1) {
  //interrupt drugič
  //delaj svoje
  i = 2;
 } else if (i == 2) {
  //interrupt drugič
  //delaj svoje
  i = 3;
 } else if (i == 3) {
  //interrupt drugič
  //delaj svoje
  i = 0;
 }
}

_________________
Knowledge sharing is caring.
majerle.eu | stm32f4-discovery.net
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Obišči avtorjevo spletno stran
igo
Član
Član



Pridružen-a: Sre 11 Okt 2006 19:11
Prispevkov: 3638
Aktiv.: 17.11

PrispevekObjavljeno: Tor Okt 28, 2014 5:53 pm    Naslov sporočila:   Odgovori s citatom

V sinhronizacijski prekinitvi (Timer1, nosilni signal) samo pobrišeš prekinitvene zastavice, negiraš stanje izhoda in primerjalnemu registru prišteješ vrednost spremenljivke PolPerioda. Prenos zanemariš. Takoj za tem letiš ven in prebereš vhoda Frek_gor in Frek_dol. Po potrebi povečaš ali zmanjšaš debounce števec in preveriš, če se mora PolPerioda spremeniti. Potem se posvetiš zaporedju bytov (ukazi in podatki), ki ga moraš poslati na LCD. Vmes te lahko zmoti prekinitev drugega Timerja2 (sledilni signal - tukaj moraš poskrbeti za Sklad), a se orientiraj samo po Timerju1.
Glej, da boš ob maksimalni frekvenci v eni polperiodi opravil več kot pol potrebnih nalog in nato počakaj, da se sinhronizacijska prekinitev zgodi, ko ne bo nič pomembnega v delovnih registrih. S tem prihraniš čas rogoviljenja s Skladom, ki bi ti načenjal živce, ko bi bila signala zelo malo (par taktov) zamaknjena. Nato dokončaš naloge in počakaš na novo sinhronizacijsko prekinitev.

Ne boj se Zbirnika. Za vse našteto rabiš ene 20 različnih ukazov (in "malo" brskanja po AVR datasheetu).

Jaz sploh ne bi uporabil dveh prekinitev, ampak samo eno - za sledilni signal. Tista za nosilni signal bi pa poskrbela samo negiranje enega bita in s tem za izstop iz čakalne goto zanke.
Cakaj1
Je nek bit 1?
Ne, goto Cakaj1
uredi polovico stvari (vmes se zgodi sledilna prekinitev)
Cakaj2
Je nek bit 0?
Ne, goto Cakaj2
uredi drugo polovico stvari
goto Cakaj1

Seveda se še nisem poglobil v datasheet niti pol stavka dlje od tega, kar sem doslej potreboval. Zato je rešitev od @dejko1 še najelegantnejša.

_________________
Teoretično je praksa posledica teorije, praktično je pa ravno obratno. (igo 2001)
LP, Igor
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
gregoral
Član
Član



Pridružen-a: Pet 24 Nov 2006 9:42
Prispevkov: 688
Aktiv.: 3.26
Kraj: Ljubljana

PrispevekObjavljeno: Tor Okt 28, 2014 6:07 pm    Naslov sporočila:   Odgovori s citatom

1) za večje hitrosti/frekvence signala ki ga želiš generirati MORAŠ uporabiti timer tako, da sam spreminja stanje izhoda!
Primer take nastavitve: vsakih 10 us zamenjaj stanje izhoda.
Po korakih to izgleda takole:
- s kakšno frekvenco teče procesor?
- primerno nastavi prescaler oz. druge parametre timerja
- sproži timer
- od tu dalje timer sam spreminja stanje izhoda in v kodi ne pipaš
- koda v glavnem programu lahko nato ob nekem dogodku (recimo pritisk tipke) izklopi timer

2) pri nižjih hitostih se lahko igraš s tem da timer kliče tvojo kodo.
V tem primeru izbereš najmanjši mnogokratnik časov ob katerih bi rad nekaj naredil.
Recimo interval je 1 sekunda in ob 100, 300 in 650 ms bi rad nekaj izvedel:
Timer nastavi na 100 ms in v ISR povečuj spremenljivko (recimo ticks).
V glavnem programu potem preverjaš stanje ticks in če je vrednost 100 izvedeš kodo, če je vrednost 300 izvedeš drugo kodo, ...
Tak način ne bo zelo natančen, saj lahko preteče nekaj časa preden boš v glavnem programu preveril stanje ticks.
Če imaš v glavnem programu dolge sekvence potem tak način ni najbolj primeren.

3) če bi rad generiral dva signala s kotnim zamikom:
- ena možnost ( ni optimalna ) uporaba dveh timerjev, ki jih primerno nastaviš.
- druga možnost je da znotraj timer isr malo računaš

Žal z arduinom nisem naredil še ničesar, zato so napotki bolj splošni.
Upam da ti napisano kaj pomaga.


lp, Gregor
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
Pokaži sporočila:   
Objavi novo temo   Odgovori na to temo   Printer-friendly version    www.elektronik.si Seznam forumov -> Arduino sekcija Časovni pas GMT + 2 uri, srednjeevropski - poletni čas
Pojdi na stran 1, 2, 3  Naslednja
Stran 1 od 3

 
Pojdi na:  
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: 47 dni


Powered by phpBB © 2001, 2005 phpBB Group