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


Pridružen-a: Pet 02 Nov 2012 15:08 Prispevkov: 231 Aktiv.: 1.50 Kraj: Zgornji Brnik
|
Objavljeno: Sob Nov 03, 2012 12:10 am Naslov sporočila: |
|
|
Uporabljam metodo s prekinitvama dveh timerjev, pa me zanima, a obstaja še kakšna, ker bi kak timer porabil raje drugje.
_________________ Pa sam programirat sem hotu! |
|
Nazaj na vrh |
|
 |
aly Član



Pridružen-a: Tor 28 Sep 2004 14:51 Prispevkov: 9407 Aktiv.: 39.71 Kraj: Kranj - struževo
|
Objavljeno: Sob Nov 03, 2012 11:45 am Naslov sporočila: |
|
|
En timer je zadosti za generiranje desetih ali še več PWM signalov.
Prekinitve se morajo izvajati na najvišjo željeno resolucijo.
Če želiš resolucijo npr 64 korakov, potem 20 ms (periodo) razdeliš na 64 korakov. En korak je tako dolg 312,5 µs.
Seveda mora biti mikrokontroler dovolj zmogljiv in hiter, da v tem času obdela vse pwm izhode in naredi še kaj drugega poleg tega.
_________________ I'm going to stand outside, so if anyone asks, I'm outstanding  |
|
Nazaj na vrh |
|
 |
igo Član

Pridružen-a: Sre 11 Okt 2006 19:11 Prispevkov: 3641 Aktiv.: 16.01
|
Objavljeno: Sob Nov 03, 2012 12:47 pm Naslov sporočila: |
|
|
Vsak servo impulz ima dolžino 1 do 2ms. Torej vklopiš prvi izhod za 1ms, vklopiš drugi izhod, v naslednjih 1024us pa je možno z 8-bitno resolucijo izklopiti prvi izhod. Nato počakaš do preteka 1024us, vklopiš tretji izhod in začneš čakati do izklopa drugega izhoda.
V 20ms ciklu lahko s čistimi decfsz pavzami 8-bitno poganjaš 18 ali 19 servo motorčkov, na koncu in v prvi ms novega cikla pa postoriš še kakšno malenkost.
Enostavno ne dobijo vsi servoti hkrati začetka impulza (to bi se poznalo tudi kot motnja na napajanju), ampak gre vse lepo po vrsti.
Za tiste 4 servote se PIC-u sploh ne pozna, da kaj počne. Timer lahko uporabiš kar za zbujanje iz sleep vsakih 20ms. To pa že veš, da lahko za sproti spreminjaš bite razpoložljivih registrov (preddelilnika, INTCON, ...), da notranji časi tečejo skladno s potrebami.
Sploh tisti, ki za debounce tipk uporabljate nekaj ms zakasnitve z zankami, imate še ogromno rezerve za optimizacijo kode.
_________________ Teoretično je praksa posledica teorije, praktično je pa ravno obratno. (igo 2001)
LP, Igor |
|
Nazaj na vrh |
|
 |
galjotj Član


Pridružen-a: Pet 02 Nov 2012 15:08 Prispevkov: 231 Aktiv.: 1.50 Kraj: Zgornji Brnik
|
Objavljeno: Sob Nov 03, 2012 3:09 pm Naslov sporočila: |
|
|
A obstaja kakšen nazoren C primer ?
Delam z 18f2550 v C18 in bi rad poleg mnogih drugih I/O operacij, izračunavanj.. krmilil še 8-9servo-tov, kar sedaj počnem z dvema timer-jema ter prekinitvenimi rutinami.
HVALA IN LP
_________________ Pa sam programirat sem hotu! |
|
Nazaj na vrh |
|
 |
xsyt Član


Pridružen-a: Sre 28 Maj 2008 22:19 Prispevkov: 1346 Aktiv.: 6.48 Kraj: Slov.Bistrica
|
|
Nazaj na vrh |
|
 |
galjotj Član


Pridružen-a: Pet 02 Nov 2012 15:08 Prispevkov: 231 Aktiv.: 1.50 Kraj: Zgornji Brnik
|
Objavljeno: Sob Nov 03, 2012 3:58 pm Naslov sporočila: |
|
|
Zelo zanimiv in nazoren prikaz, res pa da iz "drugega tabora" (Atmel).
Bom probal to implementirati na PIC-u in če kaj dobrega rata, to tudi objavim.
HVALA IN LP
_________________ Pa sam programirat sem hotu! |
|
Nazaj na vrh |
|
 |
aly Član



Pridružen-a: Tor 28 Sep 2004 14:51 Prispevkov: 9407 Aktiv.: 39.71 Kraj: Kranj - struževo
|
Objavljeno: Sob Nov 03, 2012 6:26 pm Naslov sporočila: |
|
|
Tale koda, predstavljena v videu, je precej slaba.
Se lepo vidi na koncu, ko motorčki "žmrkajo", namesto, da bi bili pri miru: klik.
_________________ I'm going to stand outside, so if anyone asks, I'm outstanding  |
|
Nazaj na vrh |
|
 |
galjotj Član


Pridružen-a: Pet 02 Nov 2012 15:08 Prispevkov: 231 Aktiv.: 1.50 Kraj: Zgornji Brnik
|
Objavljeno: Sob Nov 03, 2012 8:21 pm Naslov sporočila: |
|
|
Moram malce bolj preučiti posnetek, čeprav o Atmelih nevem kaj dosti. Ker uporablja prekinitev, je kar čudno, da motorčki takole trzajo.
Pri uporabi dveh timerjev so servoti pri miru, a se zaplete, če hkrati uporabljaš prekinitve za kaj drugega, vendar trzajo veliko manj.
Tale PWM s enim timerjem pa verjetno pomeni, da se uporablja CPP modul - po pregledu nekaterih primerov sklepam ?
LP
_________________ Pa sam programirat sem hotu! |
|
Nazaj na vrh |
|
 |
tezo Član

Pridružen-a: Sob 19 Sep 2009 10:44 Prispevkov: 40 Aktiv.: 0.21 Kraj: Zgornji brnik
|
Objavljeno: Sob Nov 03, 2012 9:48 pm Naslov sporočila: |
|
|
Še ena možnost: Rabiš en timer in 2ms porabljenga časa vsakih 20ms.
Prvo pulze razporediš po času, od najkrajšega, do najdaljšega. Ko timer vsakih 20ms sproži interupt, v njem postavimo vse izhode na "1", nato čakamo dokler ne poteče čas najkrajšega pulza in ga potem postavimo na "0". Nato izračunamo koliko časa moramo še počakati do drugega najkrajšega pulza, počakamo in potem ta izhod postavimo na "0". in tako dalje...
Tako bi lahko dosegel veliko natančnost in število izhodov, in to samo z uporabo 8bitnega timerja. Tega še nisem preizkusil v praksi, ampak bom to kmalu rabil v enem projektu. Trenutno imam problem z BRANJEM pwm signala iz sprejemnika. Če ima kdo kakšen predlog kako to narediti (na ZS ali tukaj, da nebomo smetili teme)...
Lep Pozdrav!
|
|
Nazaj na vrh |
|
 |
MvE Član


Pridružen-a: Ned 04 Jan 2009 12:24 Prispevkov: 146 Aktiv.: 0.73 Kraj: MB
|
Objavljeno: Tor Nov 06, 2012 2:15 am Naslov sporočila: |
|
|
Takšen čisto amaterski program napisan iz glave (bi se ga dalo sigurno optimirati) in približek tega kar sem nekoč delal. Verjetno vsebuje napake ampak se vidi princip:
Koda: |
//Globalne spremenljivke
int servo_A=0, servo_B=0, korak=0;
//Prekinitev timerja
void timer_interrupt(void){
korak++;
//Zanka, ki skrbi da pulz na RB1 in RB2 traja med 1 in 2ms in ju postavi na "0"
if(korak <= 32){
if(korak >= servo_A) izklopi RB1;
if(korak >= servo_B) izklopi RB2;
}
//Ko število korakov preseže 20ms postavi RB1 in RB2 nazaj na "1"
if(korak >= 312){
vklop RB1;
vklop RB2;
korak = 0;
}
}
void main(void){
inicializiraj izhode;
nastavi timer in prekinitve;
//Nastavi začetni položaj servomotorja
servo_a = 16;
servo_b = 31;
while(1){
//Postavi na drug položaj
servo_A++;
servo_B--;
//Če preseže dovoljeno vrednost postavi na začetni položaj/vrednost
if(servo_A > 31) servo_A = 16;
if(servo_B < 16) servo_B = 31;
delay; //Upočasni premikanje servomotorja
}
}
|
Napisano za primer da imamo 16MHz kristal in 8 bitni timer s preddelilnikom 256. Minimalna vrednost za spremenljivko servo_x je 16 (1,024ms) in maksimalna 31 (1,984ms). Se pravi, da ima servomotor 16 položajev oziroma deluje z resolucijo je 64us ali drugače povedano prekinitev se sproži vsakih 64us.
Imam napisan tudi program za branje dolžine pulza iz RC sprejemnika ampak je za PIC, tega še imam nekje shranjenega če ga kdo potrebuje, drugače je opisan v Tips ‘n Tricks - stran 3-4, TIP#3.
|
|
Nazaj na vrh |
|
 |
galjotj Član


Pridružen-a: Pet 02 Nov 2012 15:08 Prispevkov: 231 Aktiv.: 1.50 Kraj: Zgornji Brnik
|
|
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: 492 dni
Powered by phpBB © 2001, 2005 phpBB Group
|