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

Pridružen-a: Sre 07 Okt 2009 19:02 Prispevkov: 33 Aktiv.: 0.17 Kraj: IDRIJA
|
Objavljeno: Pet Okt 30, 2009 12:12 pm Naslov sporočila: LPC2138 Servo motorček z PWM izhodi |
|
|
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
Opis: |
|
Velikost datoteke: |
143.34 KB |
Pogledana: |
21 krat |

|
|
|
Nazaj na vrh |
|
 |
SimonS Član



Pridružen-a: Čet 01 Jul 2004 11:18 Prispevkov: 4769 Aktiv.: 20.12 Kraj: Kobarid
|
Objavljeno: Pet Okt 30, 2009 12:48 pm Naslov sporočila: |
|
|
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 |
|
 |
majstr_ Član

Pridružen-a: Sre 07 Okt 2009 19:02 Prispevkov: 33 Aktiv.: 0.17 Kraj: IDRIJA
|
Objavljeno: Pet Okt 30, 2009 9:04 pm Naslov sporočila: |
|
|
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 |
|
 |
PrimozL Član


Pridružen-a: Tor 21 Mar 2006 10:55 Prispevkov: 404 Aktiv.: 1.72 Kraj: okolica Vipave
|
Objavljeno: Pet Okt 30, 2009 11:10 pm Naslov sporočila: |
|
|
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 |
|
 |
majstr_ Član

Pridružen-a: Sre 07 Okt 2009 19:02 Prispevkov: 33 Aktiv.: 0.17 Kraj: IDRIJA
|
Objavljeno: Sob Okt 31, 2009 12:08 pm Naslov sporočila: |
|
|
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 |
|
 |
SimonS Član



Pridružen-a: Čet 01 Jul 2004 11:18 Prispevkov: 4769 Aktiv.: 20.12 Kraj: Kobarid
|
Objavljeno: Sob Okt 31, 2009 12:31 pm Naslov sporočila: |
|
|
Mogoče se sliši zelo neverjetno, ampak prvi zadetek googla na niz LPC2138 user manual je povsem uporaben.
_________________ Lep dan
Simon |
|
Nazaj na vrh |
|
 |
majstr_ Član

Pridružen-a: Sre 07 Okt 2009 19:02 Prispevkov: 33 Aktiv.: 0.17 Kraj: IDRIJA
|
Objavljeno: Čet Nov 12, 2009 8:38 pm Naslov sporočila: |
|
|
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 |
|
 |
majstr_ Član

Pridružen-a: Sre 07 Okt 2009 19:02 Prispevkov: 33 Aktiv.: 0.17 Kraj: IDRIJA
|
Objavljeno: Pon Feb 22, 2010 3:43 pm Naslov sporočila: |
|
|
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 |
|
 |
|
|
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
|