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

Pridružen-a: Tor 03 Mar 2009 15:49 Prispevkov: 52 Aktiv.: 0.26 Kraj: Ribnica
|
Objavljeno: Čet Feb 23, 2012 9:00 am Naslov sporočila: Programski PWM |
|
|
Pozdravljeni!
Imam mikrokrmilnik pic16f877a, ki ima samo en hardwerski PWM na portu c, jaz pa bi potreboval štiri PWM-je. Slišal sem, da se da narediti programski PWM, tako da bi imel lahko na kateremkoli portu PWM, samo ne vem kako narediti.
Hvala za odgovore!
Lp |
|
Nazaj na vrh |
|
 |
MarkoM Član

Pridružen-a: Tor 12 Sep 2006 15:29 Prispevkov: 2825 Aktiv.: 12.36 Kraj: Lovrenc na P.
|
Objavljeno: Čet Feb 23, 2012 9:35 am Naslov sporočila: |
|
|
Narediš ga lahko s timerji in interuppti. Npr. en timer za frekvenco in drugi za širino pulza. Ali pa samo en timer za frekvenco, širino pulza pa v while ali for zanki. In še par kombinacij...
Možnosti je veliko, odvisno koliko procesorskega časa lahko žrtvuješ. |
|
Nazaj na vrh |
|
 |
gkrusi Član



Pridružen-a: Tor 24 Jul 2007 17:22 Prispevkov: 811 Aktiv.: 3.72 Kraj: Ptuj
|
Objavljeno: Čet Feb 23, 2012 9:38 am Naslov sporočila: |
|
|
Uporabi en timer ali zanko v programu. Ob vsaki prekinitvi timerja se naj neka spremenljivka poveča za neko vrednost, potem pa narediš if stavek, če je želena PWM vrednost večja od trenutne vrednosti spremenljivke vklopi izhod, sicer ga izklopi. Poskrbi še, da se vrednost te spremenljivke resetira na 0, vsakič ko preseže najvišjo možno vrednost PWM-a. Nekaj takega prikazuje sledeča koda.
Koda: |
int PWM; // štetje za PWM
int PWM1; // željena vrednsot PWM-a
void RTTC_isr() // se izvede vsakih 400 us
{
int i;
set_timer0(50);
if(99 > PWM) { PWM++; } else { PWM=0; }
if(PWM1 > PWM)
{
output_high(PIN_B0); // vklopi
}
else
{
output_low(PIN_B0); // izklopi
}
} |
_________________ Zakaj bi bilo preprosto, če je lahko zakomplicirano??? |
|
Nazaj na vrh |
|
 |
matteo16 Član

Pridružen-a: Tor 03 Mar 2009 15:49 Prispevkov: 52 Aktiv.: 0.26 Kraj: Ribnica
|
Objavljeno: Čet Feb 23, 2012 10:40 am Naslov sporočila: |
|
|
MarkoM je napisal/a: |
Narediš ga lahko s timerji in interuppti. Npr. en timer za frekvenco in drugi za širino pulza. Ali pa samo en timer za frekvenco, širino pulza pa v while ali for zanki. In še par kombinacij...
Možnosti je veliko, odvisno koliko procesorskega časa lahko žrtvuješ. |
Ali bi se dalo dobiti kakšen primer tega programa s timerji in interrupti? To bi mi prav prišlo, da lahko določam dolžino pulza in pavze, ker bom to rabil za servo motorje.
Naredil bom avtomobil z DTMF upravljanjem. Narejen bo iz dveh pogonskih servo motorjev in enim servo motorjem za zavijanje. Ali je to izvedljivo s pic16f877a, če moram na vsak motor pošiljati drugačen signal? |
|
Nazaj na vrh |
|
 |
matteo16 Član

Pridružen-a: Tor 03 Mar 2009 15:49 Prispevkov: 52 Aktiv.: 0.26 Kraj: Ribnica
|
Objavljeno: Čet Feb 23, 2012 10:46 am Naslov sporočila: |
|
|
gkrusi je napisal/a: |
Uporabi en timer ali zanko v programu. Ob vsaki prekinitvi timerja se naj neka spremenljivka poveča za neko vrednost, potem pa narediš if stavek, če je želena PWM vrednost večja od trenutne vrednosti spremenljivke vklopi izhod, sicer ga izklopi. Poskrbi še, da se vrednost te spremenljivke resetira na 0, vsakič ko preseže najvišjo možno vrednost PWM-a. Nekaj takega prikazuje sledeča koda.
Koda: |
int PWM; // štetje za PWM
int PWM1; // željena vrednsot PWM-a
void RTTC_isr() // se izvede vsakih 400 us
{
int i;
set_timer0(50);
if(99 > PWM) { PWM++; } else { PWM=0; }
if(PWM1 > PWM)
{
output_high(PIN_B0); // vklopi
}
else
{
output_low(PIN_B0); // izklopi
}
} |
|
Tega nisem čisto razumel, kako bi to naredil. |
|
Nazaj na vrh |
|
 |
Tomazp Član


Pridružen-a: Sob 02 Feb 2008 13:24 Prispevkov: 559 Aktiv.: 2.64 Kraj: Ljubljana
|
|
Nazaj na vrh |
|
 |
matteo16 Član

Pridružen-a: Tor 03 Mar 2009 15:49 Prispevkov: 52 Aktiv.: 0.26 Kraj: Ribnica
|
Objavljeno: Čet Feb 23, 2012 9:20 pm Naslov sporočila: |
|
|
gkrusi je napisal/a: |
Uporabi en timer ali zanko v programu. Ob vsaki prekinitvi timerja se naj neka spremenljivka poveča za neko vrednost, potem pa narediš if stavek, če je želena PWM vrednost večja od trenutne vrednosti spremenljivke vklopi izhod, sicer ga izklopi. Poskrbi še, da se vrednost te spremenljivke resetira na 0, vsakič ko preseže najvišjo možno vrednost PWM-a. Nekaj takega prikazuje sledeča koda.
Koda: |
int PWM; // štetje za PWM
int PWM1; // željena vrednsot PWM-a
void RTTC_isr() // se izvede vsakih 400 us
{
int i;
set_timer0(50);
if(99 > PWM) { PWM++; } else { PWM=0; }
if(PWM1 > PWM)
{
output_high(PIN_B0); // vklopi
}
else
{
output_low(PIN_B0); // izklopi
}
} |
|
Meni ta koda ne deluje. Namesto output_high(PIN_B0); sem dal PORTB=0b00000010; in namesto output... sem dal PORTB=0x00; pa set_timer0(50); sem moral odstraniti, ker mi je javljalo napako. |
|
Nazaj na vrh |
|
 |
matjazkariz Član


Pridružen-a: Sre 03 Nov 2004 18:09 Prispevkov: 1026 Aktiv.: 4.33
|
Objavljeno: Čet Feb 23, 2012 9:47 pm Naslov sporočila: |
|
|
Seveda ne dela.
Kakšen kompiler uporabljaš?
Ali si nastavil PORTB,1 kot izhod?
Funkcija set_timer0(50); nečemu služi, se ti ne zdi?
Si iz main loopa sploh klical funkcijo RTTC_isr()?
Kaj ko bi pripel kaj si sam sčaral v celoti? _________________ LP, Matjaž |
|
Nazaj na vrh |
|
 |
matteo16 Član

Pridružen-a: Tor 03 Mar 2009 15:49 Prispevkov: 52 Aktiv.: 0.26 Kraj: Ribnica
|
Objavljeno: Čet Feb 23, 2012 9:55 pm Naslov sporočila: |
|
|
Za enkrat še poizkušam in nimam nobenega celotnega programa
Sedaj sem napisal ta program, ampak ne vem kako bi to naredil da nebi zakasnil celotnega programa.
void main()
{
unsigned long int i;
i=0;
TRISC=0x00;
while(1)
{
if(i<2000)
{
i++;
if(i%20==0)
{
PORTC=0xFF;
}
else
PORTC=0x00;
}
else
{
i=0;
}
Delay_us(1);
}
} |
|
Nazaj na vrh |
|
 |
matjazkariz Član


Pridružen-a: Sre 03 Nov 2004 18:09 Prispevkov: 1026 Aktiv.: 4.33
|
Objavljeno: Čet Feb 23, 2012 10:21 pm Naslov sporočila: |
|
|
Če nočeš zakasniti celotnega programa, potem funkcije v smislu Delay_us() odpadejo.
Poglej si poglavje interruptov in timerjev v datasheetu tvojega mikrokontrolerja.
Tomazp je sicer pripel zelo dobro referenco, ampak žal se nanaša na Atmele. Lahko pa preportaš tiste aplikacije. Poskusi poiskati podobne primere pisane za PIC na netu. _________________ LP, Matjaž |
|
Nazaj na vrh |
|
 |
matteo16 Član

Pridružen-a: Tor 03 Mar 2009 15:49 Prispevkov: 52 Aktiv.: 0.26 Kraj: Ribnica
|
Objavljeno: Pon Apr 16, 2012 9:00 pm Naslov sporočila: |
|
|
Imam še eno vprašanje glede mikroc-ja.
Zanima me zakaj se ne da nastaviti pwm-ja na 50Hz na pic-u 16F877A?
Mislim, da je najnižja frekvenca, ki sem jo nastavil 245Hz ne, da bi mi izpisalo napako. Če dam nižjo mi izpiše napako in programa ne prevede.
PWM_Init(245);
Lp |
|
Nazaj na vrh |
|
 |
matteo16 Član

Pridružen-a: Tor 03 Mar 2009 15:49 Prispevkov: 52 Aktiv.: 0.26 Kraj: Ribnica
|
Objavljeno: Pon Apr 16, 2012 9:03 pm Naslov sporočila: |
|
|
To potrebujem za krmiljenje servo motorja. Sedaj imam na 500Hz in dela, ampak ne tako kot bi moralo (ko bi moral motor stati malo vibrira). Prebral sem, da je treba imeti frekvenco 50Hz. |
|
Nazaj na vrh |
|
 |
Alex17 Član


Pridružen-a: Ned 28 Feb 2010 21:46 Prispevkov: 476 Aktiv.: 2.55 Kraj: Ljutomer
|
Objavljeno: Pon Apr 16, 2012 9:22 pm Naslov sporočila: |
|
|
Če mirkokrmilnik deluje z neko frekvenco, lahko z 8-bitnimi registri (kakršni so v uporabi za PWM) dosežeš le zakasnitve do neke dolžine. Višja je frekvenca mikrokrmilnika, višja je minimalna frekvenca PWMa. Prevajalnik ugotovi, da ne bo šlo in ti javi napako.
Uporabi počasnejši kristal oz. nastavi prescaler. |
|
Nazaj na vrh |
|
 |
matteo16 Član

Pridružen-a: Tor 03 Mar 2009 15:49 Prispevkov: 52 Aktiv.: 0.26 Kraj: Ribnica
|
Objavljeno: Pon Apr 16, 2012 9:51 pm Naslov sporočila: |
|
|
Hvala za odgovor.
Kako pa se nastavi prescaler?
Če sem prav razumel, če nastavim prescaler, potem ne rabim menjati kristala.
lp |
|
Nazaj na vrh |
|
 |
Alex17 Član


Pridružen-a: Ned 28 Feb 2010 21:46 Prispevkov: 476 Aktiv.: 2.55 Kraj: Ljutomer
|
Objavljeno: Pon Apr 16, 2012 9:54 pm Naslov sporočila: |
|
|
Pardon, sem pisal na splošno. Ta PIC, ki ga uporabljaš, nima možnlosti deljenja vhodne frekvence, niti nima notranjega oscilatorja.
Tako ti ostane edino menjati kristali ali menajti PIC. |
|
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: 497 dni
Powered by phpBB © 2001, 2005 phpBB Group
|