Fórum témák

» Több friss téma
Fórum » PIC programozása C nyelven, C-Compiler
Lapozás: OK   122 / 153
(#) Bakman válasza c27 hozzászólására (») Márc 2, 2016 /
 
Feltételes elágazás megy? Ha kisebb, mint 10 (y<10), akkor egy számjegyű. Ha nagyobb, mint 9 de kisebb, mint 100 (y>9 and y<100), akkor kétjegyű, ha nagyobb, mint 99 (y>99), háromjegyű. Azt már te találd ki, hogy C-ben ezt hogyan kell megadni.
A hozzászólás módosítva: Márc 2, 2016
(#) c27 válasza Bakman hozzászólására (») Márc 2, 2016 /
 
Oké, én valami bonyolultabbra gondoltam, de kár volt. Kösz.
A hozzászólás módosítva: Márc 2, 2016
(#) c27 hozzászólása Márc 9, 2016 /
 
Sziasztok!

Megint megakadtam. Egyszerűen nem értem ezt a power pwm modult. Átnéztem az adatlapot 10x mindent úgy csináltam, de nem akar működni a countinous up-down count mode.

A free run mode még megy is, de ha átírom a prescale-t 64-ről 16-ra akkor időnként megakad egy rövid időre a pwm kimenet, legalább is a pwm0 és pwm1 kimenet. Még mindig nem tudom élesben kipróbálni, de eddig még normálisan működött a szimuláció.
PTCON0-val lehet állítani a prescalet és a freerun vagy count up-down módot is. Adatlap 178 oldaltól kezdődik ez a pwm-es leírás, de én már nem tudok mit mondani erre. Az adatlapi leírás elég gyatra amúgy, nagyon sok részletről nem írnak semmit, de legalább működne normálisan.

#include "config.h"

void main(void) {

LATB = 0x00; //PORTB OUTPUT CLEARED
TRISB = 0X00; //RB0-RB7 OUTPUT


PTCON0=0b00001100; //Countinous up-down count mode (no interrupt): 0b00001110;
PTCON1=0x00;
PWMCON1=0X00;
//OVDCOND=0b00000110;
//OVDCONS=0x00;
PTMRL=0;
PTMRH=0;
PTPERL=0xFF;
PTPERH=0x0F;
PDC0L=0xFF;
PDC0H=0x0F;
PDC1L=0x00;
PDC1H=0x20;
PTCON1bits.PTEN=1;
PWMCON0=0b00110000;
while(1);
}

Mi a jó eget csináljak vele?
(#) Hp41C válasza c27 hozzászólására (») Márc 9, 2016 /
 
Az első, amit tehetsz, hogy megírod melyik típusról van szó.
(#) c27 válasza Hp41C hozzászólására (») Márc 9, 2016 /
 
18F4431.
Egyébként próbáltam azt is hogy a pten az utolsó parancsa while előtt, mert elvileg azzal kéne indulnia a pwm-nek, de ha nem indítom el a pwm timerjét akkor is a pwm 1 és 3 állandóan megy bár ez lehetne akár a komplementer üzemmód hatása is.
A másik érdekes dolog, hogy ha átteszem folytonos fel-le számlálós üzemmódba és a PTDIR bit értékét kirakom pl a c port egyik kimenetére akkor az mindig 0 még akkor is ha beállítom kezdőértéknek 1-re. Legalább is ebben a folytonos fel-le számlálós üzemmódban, free runba be tudom állítani 1-re, de ott meg nincs értelme, mert nem fog menni a pwm, ha fentről számol lefelé a timer.
A hozzászólás módosítva: Márc 9, 2016
(#) ktamas66 válasza c27 hozzászólására (») Márc 9, 2016 /
 
A kitöltéshez tartozó idő (PDCxx) nem lehet nagyobb mit a periódusidő (PTPERx), de ha egyenlő, szerintem akkor sem történik semmi (100%-os kitöltés).
(#) c27 válasza ktamas66 hozzászólására (») Márc 9, 2016 /
 
Tudom, de teljesen mindegy milyen értéket írok be a PTPER értéke vagy az alatti PDCxx értéknél a páratlan számú pwm kimenetek mennek és amikor nagyobb a PDC értéke mint a PTPER csak akkor lesznek a páros számú pwm kimenetek "magasak". De ez csak a count. up-down count módnál.
A fenti programrészlet free runba van ha kb felét írom be (0x0200) a PDC-be akkor felváltva villog normálisan. De már az is érdekes, ha free runba gyorsítok rajta (növelem a frekvenciát azaz csökkentem a prescalet) kb. 3-4 mp-ként megakad egy pillanatra. Nem tudom hogy most a szimuláció vacakol vagy a beállítás rossz.
(#) c27 válasza c27 hozzászólására (») Márc 9, 2016 /
 
Csak a teszt kedvéért próbáltam kiszűrni mi lehet a hiba.
A timer enable aktív tehát a timernek elvileg mennie kéne.
A PTIF jelez állandóan, viszont mivel indulásnál egyből a a PTPER értékéről indul így jelezni is fog, de olyan mintha nem indulna el a lefelé számlálás. Ezt eléggé igazolja a PTDIR bit állandó "alacsony" értéke.
PWM0 és PWM2 megy állandóan, pedig a pwm0 modul értéke 0 a pwm1 modul értéke pontosan PTPER. Ekkor a PWM0 'magas' PWM1 'alacsony' PWM2 'alacsony' PWM4 'magas' szinten kéne lenniük.

#include "config.h"

void main(void) {

LATB = 0x00; //PORTB OUTPUT DELETED
TRISB = 0X00; //RB0-RB7 OUTPUT

LATC = 0x00; //PORTB OUTPUT DELETED
TRISC = 0X01; //RB0-RB7 OUTPUT


PTCON0=0b00001110; //Countinous up-down count mode (no interrupt)
PTCON1bits.PTDIR=1; //ha PTDIR=0 semmi sem változik de akár ki is lehetne törölni ezt a sort
PWMCON1=0X00;
//OVDCOND=0b00000110;
//OVDCONS=0x00;
PTMRL=0;
PTMRH=0;
PTPERL=0xFF;
PTPERH=0x0F;
PDC0L=0x00;
PDC0H=0x00;
PDC1L=0xFF;
PDC1H=0x0F;
PWMCON0=0b00110000;
PTCON1bits.PTEN=1;
while(1){
LATCbits.LATC1=PTCON1bits.PTEN;
LATCbits.LATC2=PIR3bits.PTIF;
LATCbits.LATC3=PTCON1bits.PTDIR;
if(PORTCbits.RC0==0){
PIR3bits.PTIF=0;
}
}
}

Ha az RC0 nullán lévő nyomógombot megnyomom a flag bit törlődik, de amint felengedem azonnal ismét magas szinten lesz. A configot is mellékeltem, már nem tudom mi lehet a hiba.
A szimulátor proteus 7.
A hozzászólás módosítva: Márc 9, 2016

config.txt
    
(#) ktamas66 válasza c27 hozzászólására (») Márc 9, 2016 /
 
A PTDIR bit csak olvasható, úgyhogy tényleg törölheted a sort. A többi szerintem működhetne, ha nem a szélső értékekkel tesztelnéd (0 és 100% kitöltés). A félút a PDCx=0x08FF. Az előosztó állításához lehet érdemes megállítani a PWM-et, majd újraindítani. A PTPER regiszterek írhatók (ugyebár az is állítja a frekvenciát).
A szimulátorról nem tudok semmit mondani.
(#) c27 válasza ktamas66 hozzászólására (») Márc 9, 2016 /
 
Ha 0x08FF-et írok bele akkor is ugyan így áll a kimenet. De a szélső értékeknél sem működik megfelelően, mintha beállt volna a pic, de a nyomógomba reagál, szóval passz. Holnap megpróbálom összedobnia hardvert hátha csak a szimulátor nem birkózik meg a power pwm-el.
Egyébként milyen más módon lehet még szimulálni a programot? ASM-be széten végig lehet követni a programot, de a C18-al nem tudom milyen lehetőségek vannak.
A hozzászólás módosítva: Márc 9, 2016
(#) c27 hozzászólása Márc 9, 2016 /
 
Ezzel a PWM-el utoljára offolom már szét a fórumot.

Valahogy sikerült elindítani, ha a PTPER 0x0FFF nem indul el a pwm beragad. Elvileg lehetne FFF értéke mert 12 bites a regiszter.
A másik, hogy ezen a csodaszép szimulátoron van szkóp is, így ahogy elindult a pic meg tudtam mérni végre a pwm kimenetét. (A void main-t és a headert szándékosan nem másoltam már ide.)

LATC=0x00;
TRISC=0x00;
LATB = 0x00; //PORTB OUTPUT DELETED
TRISB = 0X00; //RB0-RB7 OUTPUT

PTCON0=0b00000110; //Countinous up-down count mode (no interrupt)
PWMCON1=0X00;

PTPERL=0xFF;
PTPERH=0x04;
PDC0L=0xFE;
PDC0H=0x09;
PDC1L=0x7F;
PDC1H=0x02;
PWMCON0=0b00110000;
PTCON1bits.PTEN=1;
while(1){
LATCbits.LATC3=PTCON1bits.PTDIR;
}

Ebből a lényeg, hogy a PWM0 modulhoz tartozó PDC értéke 2x-ese a PTPER-nek és a PWM1 modulhoz tartozó PDC értéke fel a PTPER-nek.
A lényeg, hogy meglepő módon a PWM0 szolgáltat 50%-os kitöltési tényező, míg a PWM1 csak jóval kisebbet.
Az adatlapi értelmezéseim szerint pont fordítva kéne lennie a PTPER-től számol le a pwm timere és amikor eléri a PDC értékét akkor kapcsol be a kimenet, azután számol lefelé 0-ig majd ismét felfele amikor a timer értéke nagyobb mint a PDC értéke ismét kikapcsol a kimenet.
Én így értelmeztem az adatlapot. Hozzáteszem most komplementer üzemmód van beállítva, de ennek nem szabadna befolyásolni a működést.
Ötletek javaslatok? Valamit elnéztem?
(#) c27 válasza c27 hozzászólására (») Márc 10, 2016 /
 
A mai nap tanulsága:
PDCH: PDCL ≤ (4 * (PTPERH: PTPERL)).

Persze az adatlapban egy szó sincs erről csak az Errata-ban van eldugva, még jó hogy megtaláltam.
Aki ezt az adatlapot csinálta nem normális.
A hozzászólás módosítva: Márc 10, 2016
(#) ktamas66 válasza c27 hozzászólására (») Márc 10, 2016 /
 
Benne van ez az adatlapban, de én is elsiklottam felette. A 18.6 fejezetben, a 18-11. ábra mutatja, hogy a TMR számlálóhoz hozzáveszi a Q fázisokat. Mondjuk gyanús lehetett volna nekem is, hogy amíg a periódus regiszter 12 bites, a DC 14 bites.
(#) c27 válasza ktamas66 hozzászólására (») Márc 10, 2016 /
 
Azért ha ez a képlet benne lett volna sokkal többet segített volna, plusz sokkal feltűnőbb.
A hozzászólás módosítva: Márc 10, 2016
(#) c27 válasza ktamas66 hozzászólására (») Márc 10, 2016 /
 
Ismét van egy kérdésem.
Össze kéne szorozni egy 16 bites változót egy 8 bites változóval majd 2-vel szorozni és elosztani 255-tel.
Lényegében van egy változó ami 250-1270 között lehet össze kéne szorozni egy 0-255 között változó számmal majd 2-vel szorozni és osztani 255-tel.
Hogy lehet ezt megtenni a leggyorsabb módon? Mire a 255-tel osztani kéne addigra 24 bites lesz így nem tudom hogy lehetne normálisan megcsinálni C18-ban. Hamarabb meg nem érdemes osztani, mert nagyon sok hiba lesz a tizedesjegyek nélkül.
Esetleg érdemes betenni asm részt és oda egy gyorsan futó programot? Illetve C18-ban hogy lehet egyáltalán a hardveres szorzást kihasználni, mert erre utalást nem találtam vagy szintén asm részt kell betenni?
(#) Hp41C válasza c27 hozzászólására (») Márc 10, 2016 /
 
  1. short long  var24bits; // 24 bites egész változó...
(#) foxi63 válasza c27 hozzászólására (») Márc 10, 2016 /
 
Szia!
Nagy pontatlanságot okozna a 256-tal való osztás?
Egyébként gyors a HW szorzó, a paramétereket pedig át lehet adni.Ha assembly betéttel oldod meg a műveletet, akkor sem probléma a 24 bit.
Milyen PIC -ed van?
(#) c27 válasza foxi63 hozzászólására (») Márc 10, 2016 /
 
18F4431
A 256-tal való osztás kicsit problémásabb lenne. A hardveres szorzást nem tudom hogy lehet elérni ebben a C18-as fordítóban, de max akkor asm rész is lesz.

Egyébként korábban így próbáltam de nem lett jó:
unsigned short long PDC=0;
PDC=PTPER*2*255/255; Így elcsúszik a pwm ha kiveszem belőle a *255/255-öt akkor jó.
A hozzászólás módosítva: Márc 10, 2016
(#) foxi63 válasza c27 hozzászólására (») Márc 10, 2016 /
 
Azért nem problémásabb, mert egyszerűen a 24 bitből elhagyod az utolsó 8-at és ez a 256-tal való osztás...
(#) c27 válasza foxi63 hozzászólására (») Márc 10, 2016 /
 
Értem, csak némiképpen módosítja a végeredmény ezért problémásabb, de még kicsit utánaszámolok mennyire veszélyes.
Ettől függetlenül, csak nem működik az unsigned short long-gal.
PDC=PTPER*2*255/255; ennem nem ugyan az az eredménye mint PDC=PTPER*2; ennek.
Elég érthetetlen, jócskán kevesebb az eredmény, csak ezt a C18-at még annyira sem ismerem, mint az asm-est, meg azt legalább nyomon tudom követni bitenként.
Hát 0,4% a hiba a maximális értéknél akár még jó is lehet az utolsó 8 bit elhagyása, de azért érdekes, hogy nem tudok egy 24 bites számot osztani.
A hardveres szorzásról semmit sem nyilatkozik a C18 manual, szóval nem tudom C-ben hogy lehet ezt elérni, pedig jóval gyorsabb mint a szoftveres.
A hozzászólás módosítva: Márc 10, 2016
(#) c27 válasza c27 hozzászólására (») Márc 10, 2016 /
 
És próbaképpen így sem jó:
PDC1=(PTPER*2*255)>>8;
PDC0L=PDC1&0xFF;
PDC0H=PDC1>>8;
(#) ktamas66 válasza c27 hozzászólására (») Márc 11, 2016 /
 
Nem értem pontosan mit szeretnél, hol van itt a változó.
Ha a 8 bites számmal szeretnéd állítani a kitöltést, én az választanám, hogy a PTPER értékét eltolnám 4-szer jobbra (osztás 16-tal), így egy 8 bites számot kapok. Ezt szoroznám a 8 bites változóval, majd osztanám 4-gyel ( 2-szer jobbra), így egy 14 bites számot kapnék, ami mehet a kitöltésbe. Ez sem teljesem pontos számítás, de talán belefér a hiba.
A PWM felbontása annál jobb, minél magasabbra tudod választani a PTPER értékét, az órajel osztás helyes megválasztásával.
(#) foxi63 válasza c27 hozzászólására (») Márc 11, 2016 /
 
Valószínűleg a megírt függvények nem támogatják a HW -es szorzót, de megírtam neked.
Asm betéttel. Leteszteltem működik, de még átnézem és holnap este felteszem.A függvény elvégzi a 16 bit x 8 bit szorzást, a 2x-es szorzást és az eredményt 16 biten visszaadja.
(#) foxi63 válasza c27 hozzászólására (») Márc 11, 2016 /
 
A 24 bites változóhoz csatoljad a GenericTypedefs.h headert.
A függvény itt van:
  1. #include "p18f2320.h"
  2. #include "Generictypedefs.h"
  3. unsigned int arg1,result;
  4. unsigned char arg2;
  5. void szoroz(unsigned int*,unsigned char*,unsigned int*);
  6. void main ()
  7. {
  8.         while(1)
  9.         {
  10.                 arg1=32156;arg2=127;result=0;
  11.                 szoroz(&arg1,&arg2,&result);
  12.                 Nop();
  13.         }
  14. }
  15.  
  16. void szoroz(unsigned int* _arg1,unsigned char* _arg2,unsigned int*_res)
  17. {
  18. UINT24 sv;
  19.  
  20.  
  21.  
  22. sv = 0;
  23. FSR0 = (unsigned int)_arg2;
  24. _asm
  25. MOVFF   INDF0,EEDATA
  26. _endasm
  27. FSR0 = (unsigned int)_arg1;
  28. FSR1 = (unsigned int) &sv;
  29. _asm
  30. MOVF    POSTINC0,0,ACCESS
  31. MULWF   EEDATA,ACCESS
  32. MOVFF   PRODL,POSTINC1
  33. MOVFF   PRODH,INDF1
  34. MOVF    INDF0,0,ACCESS
  35. MULWF   EEDATA,ACCESS
  36. MOVF    PRODL,0,ACCESS
  37. ADDWF   POSTINC1,1,ACCESS
  38. CLRF    WREG,ACCESS
  39. ADDWFC  PRODH,0,ACCESS
  40. MOVWF   POSTDEC1,ACCESS
  41. MOVF    POSTDEC1,0,ACCESS
  42. BCF             STATUS,0,ACCESS
  43. RLCF    POSTINC1,1,ACCESS
  44. RLCF    POSTINC1,1,ACCESS
  45. RLCF    POSTDEC1,1,ACCESS
  46. _endasm
  47. FSR0 = (unsigned int)_res;
  48. _asm
  49. MOVFF   POSTINC1,POSTINC0
  50. MOVFF   INDF1,INDF0
  51. _endasm
  52.        
  53. }

arg1 16 bites arg2 8 bites result= eredmény
természetesen az alsó 8 bitel már nem foglalkozok. (/256)
A hozzászólás módosítva: Márc 11, 2016
(#) foxi63 válasza c27 hozzászólására (») Márc 11, 2016 /
 
Szia!
Idézet:

ha kiveszem belőle a *255/255-öt akkor jó.

Azért nem világos, hogy miért is kell megszorozni, és elosztani valamit ugyanazzal a számmal.
Még lebegőpontos számítással is van hiba, azonban a PWM 14 bites intervallumában is elenyésző változás az utolsó 2 bit. 10bites PWM nél csak a felső 8 bitet szoktam piszkálgatni.
üdv. Foxi
(#) Wezuv válasza c27 hozzászólására (») Márc 11, 2016 /
 
PTPER*2*255/255 = PTPER*2
(#) potyo válasza c27 hozzászólására (») Márc 11, 2016 /
 
A C18 minden további nélkül használja a hardveres szorzót. Nézz bele a disassembly listába. Igaz, hogy nem mindig optimálisan használja, de sokkal jobb, mintha szoftveresen csinálná.
(#) c27 válasza ktamas66 hozzászólására (») Márc 11, 2016 /
 
Na jó leírom akkor.
Két db olyan négyszögjelet szeretnék előállítani, aminek a frekvenciája 1-5khz között van és a két négyszögjel mindig szimmetrikusan változik. A frekvenciát lehet állítani az adc-n keresztül és a kitöltési tényezőt is.
A lényeg, hogy a két négyszögjellel egy H hidat akarok hajtani, ezért nem lehet a két négyszögjelben "fedés" (dead time szoftveresen majd be lesz állítva, de a meghajtó ic-nél is lehet állítani egyelőre ez most nem számít). Mivel azt szeretném, hogy a 2 félhíd szimmetrikusan dolgozzon ezért nem lehet a két négyszögjel egymás komplementere. Az adc-k 8 bitesek, így elég a 8 bites felbontás a pwm-nél. De mellékelek 2 képet azon látszik mit akarok.
Lényegében az egyik poti értékéből meghatározok a PTPER-t a másik potival pedig a kitöltési tényezőt akarom változtatni, de a kitöltési tényező függ a PTPER-től.
Lényegében a PTPER értékét kell megszorozni 2-vel ekkor lesz 50%-os a kitöltési tényező ennél nagyobb nem lehet, mert különben jön az egymásra kapcsolás. A 8 bites adc pedig 0-255 között változik ezzel szorzom meg a PTPER*2-t és osztom 255-tel. Innen jött a PTPER*2*255/255 ki akartam próbálni, hogy maximumnál tényleg 50% e a kitöltési tényező, de nem annyi lett, míg PTPER*2-nél az volt. A frekvenciák már a kellő értékek között mozognak, a kitöltési tényezőt is kipróbáltam 50% és 25%-nál csak ez a szorzás hiányzik még.
Még annyi kiegészítést a PTPER értéke most 250-1270 között változik a PDC-t pedig úgy kell kiszámolni, hogy PDC=PTPER*2*ADC értéke /255 így a PDC értéke nem 8 bites, midig függ a PTPER-től.
A hozzászólás módosítva: Márc 11, 2016
(#) c27 válasza Wezuv hozzászólására (») Márc 11, 2016 /
 
Kis pontatlansággal egyenlőnek kéne lennie, de a teszt során nagyságrendi eltérés van.

Kösz, Foxi63 mindjárt kipróbálom a programod.
(#) Wezuv válasza c27 hozzászólására (») Márc 11, 2016 /
 
Így már értelmet nyer, hogy tudjuk, az egyik 255, nem mindig 255, azaz egy változó.
Ha egy sorban leírt művelet eredménye nem megfelelő, próbáld felbontani a képletet részleteire, több lépésben elvégezve azt. Sokszor túlcsordulások keletkezhetnek, illetve szerintem a fordító sem mindig érti mit akarunk, vagy mi nem ismerjük eléggé őt.
A hozzászólás módosítva: Márc 11, 2016
Következő: »»   122 / 153
Bejelentkezés

Belépés

Hirdetés
XDT.hu
Az oldalon sütiket használunk a helyes működéshez. Bővebb információt az adatvédelmi szabályzatban olvashatsz. Megértettem