Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
PIC16F1827 HPWM Push-pull
#41
(11-29-2015, 12:12 AM)Želja Wrote: Kada se obraćaš direktno pinu koristi LOW ili HIGH taj pin,
A kada se obraćaš odredjenom bitu u okviru neke promenljive koristi 0 ili 1 za stanje tog bita.

I koristi SYMBOL da "krstiš taj pin"
recimo:

Symbol Relej = PORTD.4

posle kažeš samo :

Low Relej ili High Relej




(11-29-2015, 12:12 AM)Milan94 Wrote: Posto sam port B postavio u digitalnom modu zato sam pisao nule i jedinice za njihova stanja.

Hajde ponovo pročitaj šta si napisao .... 102

Pročitaj lepu temu na :

http://www.elitesecurity.org/t453500-TUT...c-Pro-PICF

Kupi knjigu - nije skupa :
http://milan.milanovic.org/skola/knjiga02.htm

Hoću da pomognem, ali da bih mogao MORAŠ naučiti nešto iz literature koje ima još osim gore nevedene !


Pozz
Reply
#42
Knjigu imam a ako se postavi neki pin ili ceo port u digotalnom modu onda se njihovo stanje odredjuje sa o (Low) ili 1 (High) tako bi bar trebalo ali moze i samo Low i High.

Zaboravih da napomenem da programe testiram na Razvojnom sistemu koji je napravio Radanocevic Sinisa evo u ovoj temi mozete videti o kom hardveru je rec.
Reply
#43
(11-29-2015, 12:28 AM)Milan94 Wrote: Knjigu imam a ako se postavi neki pin ili ceo port u digotalnom modu onda se njihovo stanje odredjuje sa o (Low) ili 1 (High) tako bi bar trebalo ali moze i samo Low i High.

Da Milane,

ako su u dig.modu onda ne može drugačije nego 0 ili 1.
Ja sam ti pokušao skrenuti pažnju kako da koristiš benefite PBP kroz obraćaanje oslovljenim pinovima sa High ili Low
a ti si odgovoriuo tako da ispadne da si MORAO koristiti 0 ili 1 zato što su u dig.modu.

Kakva je svrha upotrebe PBP-a ili bilo kog drugog kompajlera ako nećeš koristiti njegove sintakse. ?

Pozz
Reply
#44
Kompajler bi trebao da bude dovoljno pametan da uradi casting variable u compile-time iz bilo kog dostupnog formata.
Ako se trazi digitalno stanje, ukucali 1 ili 0x01 ili 0xFF ili "miki" ili true ili … to sve mora da pretvori/evaluira u logicku informaciju "tacno" …
Nisam nikad radio sa tim PBP inace bih vam rado pomogao … Ja uglavnom koristim C/C++, konkretno za Microchip MPLAB X, besplatan software.
Reply
#45
PicBasic nije previše moćan kompajler.

Ja ga koristim 10 - 12 godina i imam dosta uredjenih stvari u njemu, tako da mi se sada ne menja.
Da sam zano ono što sada znam o njemu, sigurno bih ga zaobišao kada sam počinjao - ali sad mi se ne da.

Može dosta toga da se uradi u njemu, ali traži poznavanje svojih slabosti.
Ono što je kod drugih normalno, to ovde nekad mora biti izričito ispoštovano po njegovim pravilima.
Ima tu bubica i problema, jedan je sigurno i ON INTERRUPT koji je dosta ograničen.

Pogledajte po stranim forumima o tome, svi koriste ASM interapt za bilo šta ozbiljnije u PBP.

Zato i pokušavam da objasnim ono što znam,
i prenesem neke cake koje su meni odnosile po par dana češanja po glavi ..

Mogu pomoći i hoću , ali da ne ispadne ono :
Baba šumom a Dida drumom ...

Veliki pozdrav svim kolegama !
Reply
#46
Ranije dok sam koristio PBP interapte sam radio sa ovim include files
pogledati i primere na ovom linku radi razumevanja kako se koriste

http://www.dt-ints.com/DT_INTS-14/intro.html

primer

http://www.dt-ints.com/DT_INTS-14/blinky.html

pogledati i ostale primere
Reply
#47
Skinuo sam include file ali de to treba da raspakuje da bih kompajler mogao to da pronadje prilikom prevodjenja.
Reply
#48
Raspakuj i kopiraj u tvoj pbp kompajler u include
Reply
#49
Posto sam savladao tehniku generisanja PWM 50Hz uz pomoc interrupta sada planiram da iskoristim hardverske PWM module koje poseduje ovaj MCU 2 standardna CCP modula i dva Enhanced CCP (ECCP).
Enhanced PWM, Full - Bridge 
Enhanced PWM, Half - Bridge

Sa standardnim CCP pwm koji generise signal na jednom pinu znam kako da menjam u petlji Duty (iscitavam vrednost iz sine tabele) i time dobijem jednu poluperiodu ali meni treba signal na jos jednom punu za generisanje druge poluperiode.

Uradio sam transformator u Push-pull (2x12v) znaci meni bi odgovarala varijanta Enhanced PWM, Half - Bridge ali mi nije jasno kako tu da menjam Duty jer trebam prvo na jednom pinu da izgenerisem celu poluperiodu dok na drugom pinu netreba da imam signal i obrnuto.
Kada postavim neku vrednos Duty
u Half - Bridge modu dobicu tu vrednost na oba pina. Da li mora bas da se koristi Full - Bridge mod u kom bi kada izgenerisem jednu poluperiodu Sinus (izcitam celu tabelu) tada u CCPxCON podesim reverse mod i opet ispocetka krene iscitavanje tabele.
Reply
#50
Pogledaj steering mod kod tvog kontrolera. Možeš da generišeš PWM na jednom pinu koji vozi recimo gornji mosfet dok ti je drugi PWM pin konfigurisan kao gpio i on vozi donji mosfet. Za drugu poluperiodu im samo obrneš uloge. Na taj način ovim kontrolerom možeš da generišeš max. dva sinusna signala sa dva half-bridge. Biće u fazi ili pomereni za 180 stepeni.
Reply
#51
Hvala puno nisam ni obratio paznju cemu sluzi Steering mod pa ovo je super kada se dodje do zadnje vrednosti u sinus tabeli samo zamenim stanja BIT 0, Bit 1 u PSTRxCON regustru  i krenem ponovo ispocetka tabelu.
Reply
#52
Baš tako. Baci pogled na PIC16F1783 da vidiš šta taj malac ima.
Reply
#53
Pic16f1783 imam na legeru nekoliko komada kupljenih zbog 12bit/AD znam da imaju 16bit rezoluciju PWM ali mi je malo komplikovano podesavanje registra veznih za PWM i zato sam ga u ovom trenutku zobisao i resio da urdim sa mojim omiljenim PIC16f1827 Big Grin .

Imam jos jedno pitanje glavna noseca frekvencija je 20Khz (50us) pwm-u je dodeljen tajmer2 u tabeli imam 40 vrednosti za generisanje sinusa e sada drugim tajmerom (timer 0) pravim prekide na 250us i u interapt rutini dodeljujem vrednost duty iz tabele da li to moze ovako da radi sobzirom da nije sinhronizovan tajmer0 i tajmer2 ili bi trebalo da bude sinhronizovano kada noseci PWM uradi 5 inpulsa tada se dodeli nova vrednost duty za narednih 5 inpulsa.
Reply
#54
Imaš onaj tool od microchip-a zove se PSMC Designer. Probaj sa njim.
Reply
#55
(04-27-2017, 07:32 PM)gorankg Wrote: Imaš onaj tool od microchip-a zove se PSMC Designer. Probaj sa njim.

Kada savladam ovo generisanje sinusa mozda i resim da probam kako radi na pic16f1783 ili pic18fx431.

Da li nam veca rezolucija daje mogucnos finije podesavanje duty .
Reply
#56
(04-27-2017, 07:49 PM)Milan94 Wrote: [quote pid='71693' dateline='1493317967']

Da li nam veca rezolucija daje mogucnos finije podesavanje duty .

[/quote]

Da.
Reply
#57
Milan94,

Evo ti nešto korisno...

http://www.daycounter.com/Calculators/Si...ator.phtml

P.S.

Naravno, to nije jedino na raspolaganju:

http://www.daycounter.com/Calculators/
Reply
#58
Kalkulator za vrednost sinusoide koristim sa ove stranice Smart Sine  .

Interesuje me da li se ovo ovako radi sa dva tajmera ili treba da uvecavam duty preko tamera koji je dodeljen pwm-u kojim cu uvecavati neku promenljivu do 250us i tada da unesem novu vrednost u duty.


Quote:Glavna noseca frekvencija je 20Khz (50us) pwm-u je dodeljen tajmer2 u tabeli imam 40 vrednosti za generisanje sinusa e sada drugim tajmerom (timer 0) pravim prekide na 250us i u interapt rutini dodeljujem vrednost duty iz tabele da li to moze ovako da radi sobzirom da nije sinhronizovan tajmer0 i tajmer2 ili bi trebalo da bude sinhronizovano kada noseci PWM uradi 5 inpulsa tada se dodeli nova vrednost duty za narednih 5 inpulsa.
Reply
#59
Nisam dovoljno ispratio temu, zbog nedostatka vremena, Milane.

Odavno nisam pisao u Pic Basic i odavno sam ga napustio zbog dosta njegovih mana, kako Želja reče upravo zbog mana sa ISR.

Ne znam koji Pic trenutno upotrebljavaš, ali svi koji imaju hardverski PWM modul (CCP) se koriste tako što se konfiguriše taj modul kao PWM, potom se samo u jednoj ili najviše nekoliko instrukcija (zavisno da li radiš pwm sa 8 ili više bita) upisuje vrednost u registre pwm modula.

Upisivanje je na nivou asm, bez obzira u kom jeziku pišeš. Na primer, ako je osmobitna vrednost nekog pwm za modul CCPR1, onda upisuješ u njegov donji bajt tu vrednost.

Ovako to izgleda u Pic Basic, ako se dobro sećam sintakse (nisam ga koristio bar 12 godina):
Code:
CCPR1L = neka_vrednost

U C to izgleda skoro isto:
Code:
CCPR1L = neka_vrednost;
Ukoliko je to više od 8 bita, obično postoji registar u kome u neke bitove upisuješ ono što je preko 8 bita, na primer ovako kod 18F serije i u C jeziku (; je terminacija jedne linije a // je komentar u jednoj liniji u C):
Code:
// pwm1_val je 16bit varijabla
// prvo se smeštaju viši bitovi na potrebne lokacije, obično su to bitovi u registru CCPxCON

DC1B0=(bit)pwm1_val;
DC1B1=(bit)(pwm1_val>>1);
CCPR1L=(pwm1_val>>2);  // potom se niži bajt vrednosti smesti u niži bajt CCP modula.
(U Pic Basic je to isto osim što se ne koristi ; za terminaciju linije, koliko se sećam...)

Konfiguracija PWM modula je takođe istovetna u oba jezika (pošto je asm) i najpametnije je da je direktno uradiš a ne preko nekih biblioteka koje su ti "nevidljive".

Na primer, za 18F seriju na 40MHz (i većinu 16F) i na primer CCP1 modul, konfiguracija kao PWM za na primer od 0-100% i na primer frekvenciju 6,25KHz (/* je takođe komentar u C, samo važi od /* do */ bez obzira na broj linija):

Code:
// pwm 1 i/ili 2 , za 8bita(0-100%) 6.25KHz

  PR2 =     99;                
  T2CON =   0x07;
  CCP1CON = 0b00001100;
   // CCP2CON = 0b00001100;  
/* iskomentarisan kod kao alternativna upotreba drugog PWM sa istim performansama. dovoljno je odkomentarisati // CCP2CON i odmah može da radi i drugi pwm */
Kada je pwm osmobitni, kao na primer ovaj poslednji konfig od 0-100%, upisivanje traje jednu instrukciju koja je na primer kod PIC16F1783 na 32MHz kloka 125nS svega.
To vrlo beznačajno opterećuje interrupt pa naravno možeš vršiti modifikaciju pwm u okviru interrupta.
PWM će kod Pic MCU prihvatiti novu vrednost trenutno po isteku prethodnog pwm perioda (u ovom slučaju 1/6.25KHz).

Ukoliko taktuješ te događaje na primer nekim tajmerom, poput TMR0, i ako želiš rezoluciju sinusa od na primer 100 vrednosti, onda konfigurišeš TMR0 da ti izaziva prekid na 100uS i brojiš svaki put do 100, tako da ti se sve vrti na 10mS tačno, da bi imao jedan polutalas događaja.
Mora se iskontrolisati i izvor takta za TMR0 kao interni i preskaler da bi dobio željeno vreme.
Code:
RCON  =  neka vrednost;                  /*    Compatibility mode. Priority. interapti */
T0CON =  neka vrednost;           /*  prescaler, clk source... */
INTCON = neka vrednost;                  /* GIE,TMR0IE... */
Naravno napraviš i lookup tabelu sa 100 vrednosti za sinus (jedan polutalas).

Ovako bi na primer to osvežavanje pwm izgledalo u C (a ti prevedi u Basic jer je veoma slično, da se sad ne bavim time):

Code:
void interrupt int_hand (void) //funkcija koja se bavi interruptom, kod Basic je to labela koja se malo drugacije zove
                                          // posto si je vec koristio ne bih se bavio prekopavanjem oko imena
{  //pocetak funkcije    
    
   if ( TMR0IF && TMR0IE ){  //uslov, ako je flag od TMR0 i (and) je odobren isr TMR0 onda..
     TMR0H=TimerH;      //upisi vrednost viseg bajta u TMR0, za njegovu sledecu iteraciju
     TMR0L=TimerL;       //upisi vrednost nizeg bajta u TMR0, za njegovu sledecu iteraciju     
                                   //vrednosti natrimovati na tacno 100uS, preskalerom i vrednostima oba TMR0 registra
                
      test_pin ^=1;          // toglovati neki spoljni pin da bi skopom mogao da meris vreme
                                    // to je kod tebe naredba toggle, koliko se secam    
                                    // jedno stanje traje koliko i isr, H=100uS i L=100uS, odnosno isr je 100uS
                                    // ujedno stanje ovog pina (ili npr nekog flag) koristiš za promenu polariteta izlaza
                                    //na primer, ako je test_pin H onda je pozitivan polutalas, ako je L onda negativan  

      if(test_pin) h_bridge=positive; // prebacivanje polariteta H mosta, na osnovu stanja koje se togluje u isr
      else h_bridge=negative;


      int_timer++;            // u svakom prolazu uvecaj ovu varijablu za 1, trebaće ti za neke tajmere u main
      int_temp++;            // u svakom prolazu uvecaj ovu varijablu za 1, ona pravi period od 10mS
              
      if(int_temp >=100) int_temp=0; //resetuj je svaki put kad dostigne 100, tj. na svakih 10mS
          
      CCPR1L=lockup_table[int_temp]; //upisi u pwm vrednost iz tabele, indeksiranu sa int_temp
                                                      //vrednost se osvežava na svakih 100uS
    
    }  // isto što je kod tebe endif

    
    TMR0IF = 0;  // ocisti TMR0 flag da bi omogucio novi interrupt

} // kraj interrupt funkcije ili kod tebe labele


Ti sa 100uS u jednoj iteraciji tajmera TMR0, imaš na raspolaganju prostora za SKORO 800 instrukcija u okviru samog događaja, sa na primer PIC16F1783 na 32MHz !

Nije isr toliko tesan koliko se misli, ako u njemu ništa drugo ne obavljaš. Resurse mu troše komunikacije na primer, poput RS232, I2C, SPI i slično, i naravno blokiraju ga loše napisane delay funkcije, koje ako su loše napisane okupiraju potpuno MCU za vreme svog trajanja.
Za to je na primer pametnije koristiti jednu varijablu koja se stalno uvećava u isr (nazvao sam je int_timer u prethodnom kodu) i neko merenje vremena bi izgledalo ovako:

Code:
neka petlja u main programu

  if (neki_dogadjaj) int_timer=0; //resetuj varijablu, kao start tvog timera
  if (int_timer>= neko_vreme) uradi_nesto; //kada istekne neko_vreme x 100uS,uradi nesto sto treba

  // radi nesto sto vec radis u petlji glavnog programa, potpuno neopterecen merenjem nekih vremena
  
kraj main petlje

Ovo je način merenja vremena koji ne opterećuje glavni program, a isr ti radi pa radi ono što mora...
Ako ti treba vise tajmera paralelno onda napraviš više varijabli koje se inkrementuju u isr.
Svega desetak instrukcija će ti oduzeti na primer "motanje" long (32 bit varijable) u isr, što ti može obezbediti timer od koju stotinu uS pa do oko skoro 120 časova, i da ti ne pravi frku u glavnom programu....
Na primer word varijabla (16bit) ti oduzima samo dve instrukcije u isr a omogućava merenje od 100uS do 65535 x 100uS, tj. do 6.5 sekundi...

Možeš na primer resetovati int_timer na svakih 10000 i u tom trenutku uvećati neku treću varijablu kao referencu za 1 sekundu, i tako dalje i tako dalje...

Nadam se da sam pomogao...
Reply
#60
(04-28-2017, 09:43 AM)Milan94 Wrote: Interesuje me da li se ovo ovako radi sa dva tajmera ili treba da uvecavam duty preko tamera koji je dodeljen pwm-u kojim cu uvecavati neku promenljivu do 250us i tada da unesem novu vrednost u duty.

Glavna noseca frekvencija je 20Khz (50us) pwm-u je dodeljen tajmer2 u tabeli imam 40 vrednosti za generisanje sinusa e sada drugim tajmerom (timer 0) pravim prekide na 250us i u interapt rutini dodeljujem vrednost duty iz tabele da li to moze ovako da radi sobzirom da nije sinhronizovan tajmer0 i tajmer2 ili bi trebalo da bude sinhronizovano kada noseci PWM uradi 5 inpulsa tada se dodeli nova vrednost duty za narednih 5 inpulsa.

Taj PIC nema prekide višeg i nižeg prioriteta tako da u slučaju da ih imaš više, može da se dogodi da ti tajmeri budu više ili manje nesinhronizovani. Ne znam koliko ovo može da utiče na krajnji  rezultat (možda više softver naraste pa imaš više prekida).
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)