Fórum témák
» Több friss téma |
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
Oké, én valami bonyolultabbra gondoltam, de kár volt.
![]() A hozzászólás módosítva: Márc 2, 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?
Az első, amit tehetsz, hogy megírod melyik típusról van szó.
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
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).
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.
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
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.
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
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?
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
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.
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
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?
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?
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
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...
É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
És próbaképpen így sem jó:
PDC1=(PTPER*2*255)>>8; PDC0L=PDC1&0xFF; PDC0H=PDC1>>8;
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.
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.
A 24 bites változóhoz csatoljad a GenericTypedefs.h headert.
A függvény itt van:
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
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
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á.
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
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.
Í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
|
Bejelentkezés
Hirdetés |