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 

LPC2138 Servo motorček z PWM izhodi

 
Objavi novo temo   Odgovori na to temo   Printer-friendly version    www.elektronik.si Seznam forumov -> ARM arhitektura
Poglej prejšnjo temo :: Poglej naslednjo temo  
Avtor Sporočilo
majstr_
Član
Član



Pridružen-a: Sre 07 Okt 2009 19:02
Prispevkov: 33
Aktiv.: 0.17
Kraj: IDRIJA

PrispevekObjavljeno: Pet Okt 30, 2009 12:12 pm    Naslov sporočila:  LPC2138 Servo motorček z PWM izhodi Odgovori s citatom

Pozdravljeni

Sem dokaj nov na tem forumu zato najprej pozdravljam vse.
V letošnjem šolskem letu smo v drugem letniku na FE v smeri avtomatika pri predmetu mikroračunalniški sistemi sami skupaj zlotali mikrokrmilnik, osnova je lpc2138, spodaj dodam slike.

Ker me je zadeva kr zelo pritegnila in imam kr nekaj izkušenj z programiranjem PLCjev sem se lotil sam doma pisanja programa za ta uC.

Imam ULINK2 JTAG debugger ter uVision3 program.
Težavo pa mi sedaj predstavljajo PWM izhodi z katerimi bi rad krmilil običajen servo motor. Prosil bi če se da dobiti primer kode kako naj bi tole zgledalo, ali pa gradivo kjer bi bilo delo z temi izhodi obrazloženo.

LP



301020091959.jpg
 Opis:
 Velikost datoteke:  143.34 KB
 Pogledana:  21 krat

301020091959.jpg


Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
SimonS
Član
Član



Pridružen-a: Čet 01 Jul 2004 11:18
Prispevkov: 4769
Aktiv.: 20.12
Kraj: Kobarid

PrispevekObjavljeno: Pet Okt 30, 2009 12:48 pm    Naslov sporočila:   Odgovori s citatom

Evo moj primir
Koda:
void PWM_init (void)
{
    PINSEL0 |= 0x000A800A;   /* set GPIOs for all PWMs */
    PINSEL1 |= 0x00000400;

    PWMTCR = 0;      /* Counter Reset */
      
    PWMPR = 0x00;      /* count frequency:Fpclk */
    PWMMCR = 0x03;   /* interrupt on PWMMR0, reset on PWMMR0, reset TC if PWM0 matches */            
    PWMMR0 = DUTY;           
    PWMMR1 = 0;       
    PWMMR2 = 0;       
    PWMMR3 = 0;       
    PWMMR4 = 0;       
    PWMMR5 = 0;       
    PWMMR6 = 0;       
    /* all PWM latch enabled */
    PWMLER = 0x7F;
}
Koda:

void PWM_start( void )
{

//PWMPCR = 0x00007E00;        /* All single edge, all enable */
   PWMPCR = 0x0000005454; //PWM2,PWM4 and PWM6 are generated dual edge mode
PWMTCR = 0x00000009;   /* counter enable, PWM enable */

    return;
}
Koda:
void PWM_stop( void )
{
    PWMPCR = 0;
    PWMTCR = 0x00;      /* Stop all PWMs */
    return;
}
Koda:
void pwm_izv (int pozicija, float jakost)
   {
   int a=0,b=0,c=0;

   a= pozicija;
   b= pozicija+120;
   c= pozicija+240;
   if (b>360) b = b-360;
   if (c>360) c = c-360;

   PWMMR0 = DUTY;                  // duty faktor
    PWMMR1 = jakost*(DUTY_2-(DUTY_2*cosin[a]));              
    PWMMR2 = jakost*(DUTY_2+(DUTY_2*cosin[a]));              
    PWMMR3 = jakost*(DUTY_2-(DUTY_2*cosin[b]));       
    PWMMR4 = jakost*(DUTY_2+(DUTY_2*cosin[b]));
    PWMMR5 = jakost*(DUTY_2-(DUTY_2*cosin[c]));
    PWMMR6 = jakost*(DUTY_2+(DUTY_2*cosin[c]));
    PWMLER = 0x7F;   
 
//    sprintf(izpis,"P:%d %d, %d, %d",pozicija,TA,TB,TX);      // %.2f iz int ali podobno kreira char %f za 6.decimalk
//   LCD_puts(izpis);   
    }

Ta moj primir deluje v dual adge modu, ker sem z njim generiral 3F sinusni signal za motor. Upam, da ti bo kaj prišlo prav. Saj je čisto enostavno

_________________
Lep dan
Simon
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
majstr_
Član
Član



Pridružen-a: Sre 07 Okt 2009 19:02
Prispevkov: 33
Aktiv.: 0.17
Kraj: IDRIJA

PrispevekObjavljeno: Pet Okt 30, 2009 9:04 pm    Naslov sporočila:   Odgovori s citatom

Hmmmm. Najprej bi prosil če mi lahko negdo potrdi moje razmišljanje. Za krmiljenje servo motorja moram generirati signal za premik in sicer 1ms za 0 stopinj ter 2 ms za polni odklon. Ta signal je potrebno pošiljati vsakih 20 do 30 ms kar pomeni približno 50x v sekundi => f=50Hz

Kako bi tole rešil z pwm, pa mi ni jasno.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
PrimozL
Član
Član



Pridružen-a: Tor 21 Mar 2006 10:55
Prispevkov: 404
Aktiv.: 1.72
Kraj: okolica Vipave

PrispevekObjavljeno: Pet Okt 30, 2009 11:10 pm    Naslov sporočila:   Odgovori s citatom

majstr_ je napisal/a:
Hmmmm. Najprej bi prosil če mi lahko negdo potrdi moje razmišljanje. Za krmiljenje servo motorja moram generirati signal za premik in sicer 1ms za 0 stopinj ter 2 ms za polni odklon. Ta signal je potrebno pošiljati vsakih 20 do 30 ms kar pomeni približno 50x v sekundi => f=50Hz

Kako bi tole rešil z pwm, pa mi ni jasno.



Nastaviš periodo PWM tako, da bo recimo 22 ms. Potem pa vpisuješ v PWMMRx register (poglej, kateri x je zate pravi) tako vrednost, da bo impulz trajal 1-2 ms. Da boš recimo 1000-2000 us pretvoril v vrednost za ta register, bo potreben kratek račun. To je vse. Prilagam ti svojo kodo za PWM5. PWMMRx lahko nastavljaš povsem asinhrono.

//-----------------------------------------------------------------------------
void init_PWM5 (int PCLK, int freq, int duty) {
PWMTCR = 0; // all stopped
PWMMR0 = PCLK/freq; // set period
PWMMR5 = ((PCLK*duty)/freq)/100; // set duty cycle
PWMPR = 0; // prescaler is set to 1
PWMTCR = 0x0B; // enables, stops and resets the counter
PWMPCR = 0x2000; // enable PWM 5
PWMIR = 0; // no PWM interrupts
IODIR0 |= (IR_pin | TEST_pin); // PWM5 pin basic functionality is output
IOCLR0 = IR_pin | TEST_pin; // and pin is cleared
// PINSEL1 = (PINSEL1 & IR_PINS_MSK) | IR_PINS_VAL; // PWM5 is an alternate output of P0.21
PWMTCR = 0x09; // discards reset, PWM counter is running
}

LP Primož.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
majstr_
Član
Član



Pridružen-a: Sre 07 Okt 2009 19:02
Prispevkov: 33
Aktiv.: 0.17
Kraj: IDRIJA

PrispevekObjavljeno: Sob Okt 31, 2009 12:08 pm    Naslov sporočila:   Odgovori s citatom

U hvala PrimozL zdej pa mislem da bo ratalo.

Me pa še nekaj zanima, kje se da dobiti kakšno literatura al obrazložiter ukazov na splošno za ARMe

LP
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
SimonS
Član
Član



Pridružen-a: Čet 01 Jul 2004 11:18
Prispevkov: 4769
Aktiv.: 20.12
Kraj: Kobarid

PrispevekObjavljeno: Sob Okt 31, 2009 12:31 pm    Naslov sporočila:   Odgovori s citatom

Mogoče se sliši zelo neverjetno, ampak prvi zadetek googla na niz LPC2138 user manual je povsem uporaben. Shhh
_________________
Lep dan
Simon
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
majstr_
Član
Član



Pridružen-a: Sre 07 Okt 2009 19:02
Prispevkov: 33
Aktiv.: 0.17
Kraj: IDRIJA

PrispevekObjavljeno: Čet Nov 12, 2009 8:38 pm    Naslov sporočila:   Odgovori s citatom

Prosil bi če mi kdo lahko pove kje bi bila napaka v tej kodi.
preračunav sem periodo za 20ms=>50Hz > 15MHz/50Hz = 300000 (493E0)
ter duty cycle 1ms => 1KHz > 15MHz/1KHz =15000 (3A98)
Na izhodu P0.8 pa se ne zgodi nič.




Koda:
               
#include <LPC213x.H>                    /* LPC213x definitions                */
#include <stdio.h>
#include <io.h>




int main (void)
{
    while (1) {
 
   PINSEL0 |= 0x00020000; // GPIO P0.8 = PWM4
   VPBDIV = 0x00000000;  // set up pheripheral clock for 15Mhz
   PWMPR = 0x00000000; //Set prescale to 0
   
   IODIR0 |= 0x00000100; //Direction to be output
   PWMPCR = 0x00001000;  //Single edge
   PWMMR0 = 0x000493E0; // SET PERIOD
   PWMMR4 = 0x00003A98; // SET DUTY CYCLE
   PWMTCR =0x0000002;       //RESET COUNTER
   PWMLER = 0x7F;
   PWMTCR =0x02;
   PWMTCR =0x09;       //ENABLE COUNTER


   }
}


LP
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
majstr_
Član
Član



Pridružen-a: Sre 07 Okt 2009 19:02
Prispevkov: 33
Aktiv.: 0.17
Kraj: IDRIJA

PrispevekObjavljeno: Pon Feb 22, 2010 3:43 pm    Naslov sporočila:   Odgovori s citatom

Pozdravljeni

Že nekaj časa mi servo motorčki delujejo lepo, težava je bla drugje, ne pa v kodi.
Imel bi pa še eno uprašanje, saj imam malo probleme z natančnostjo.
Na lpcju imam 12Mhz kristal
Prosil bi če mi lahko poveste ali je moj način računanja periode pravilen.

Recimo za 20ms periodo:

Iz 12Mhz zračunamo čas ene periode ter nato zaračunamo koliko period potrebuje za čas 20ms. Je to pravilno?
Nato to število vpišemo v register PWMMR0

je to pravililen način??
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 -> ARM arhitektura Časovni pas GMT + 2 uri, srednjeevropski - poletni čas
Stran 1 od 1

 
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: 498 dni


Powered by phpBB © 2001, 2005 phpBB Group