Fórum témák
» Több friss téma |
OK HP41C Köszönöm
Azt hiszem keresek egy 3. kapcsolást, de először a szoftverrel kezdem (h. boldogulok-e vele) és utána alkatrész beszerzés, panel stb. Habár lehet h írok még a cikk szerzőjének is, h. tud -e segíteni. Vagy van valakinek ötlete??
Szia!
Elnézést a késő válaszért, kicsit félre kellett tennem. Kipróbáltam, de sajnos nem oldotta meg a problémát.
MpLab 8.9x -el fordítható verzió.
Írd át a master programot "üresre", töltsd fel azt, és kapcsold be a mastert. A clock vezérlő vonalnak magasban kell maradnia. Jelezd, ha nem marad ott. A leguccsó oszcilloszkóp képed szerint lemegy alacsonyba. Bármi is az oka, meg kell találni.
Segítene egy kapcsrajz is, és hogy milyen fejlesztói környezetben vagy / milyen összetevőkkel. A hozzászólás módosítva: Márc 1, 2017
Maradt benne néhány apró hiba az eltérő alapértelmezett számrendszer miatt.
Egy érdekesség: A letöltött hex állományban egy lényeges eltérés van a fordítotthoz képest:
Az eredeti hex -ben a keresett címen nbem 0x0103 utasításkód van hanem 0x0100. Mindkettő a clrw utasítást hajtja végre. Az adatlap szerint clrw kódja 00 0001 0xxx xxxx.
Sziasztok!
Egy furcsa hibával szembesültem: három szinuszhullámot akarok létrehozni, de egy periódus alatt 4 helyen furcsa tüskék jelentek meg a kimeneten. A programrészlet biztos hogy itt van a hiba: AMP=255; //Amplitude[POT2]; AMP1=AMP*Sine_duty[counterA]; AMP1=AMP1>>6; AMP2=AMP*Sine_duty[counterB]; AMP2=AMP2>>6; AMP3=AMP*Sine_duty[counterC]; AMP3=AMP3>>6; if(counterA<180){ //Pozitív félperiódus a komplementer üzemmód miatt AMP1=1016+AMP1; } else{ AMP1=1016-AMP1; //Negatív félperiódus } if(counterB<180){ //Pozitív félperiódus AMP2=1016+AMP2; } else{ AMP2=1016-AMP2; //Negatív félperiódus } if(counterC<180){ //Pozitív félperiódus AMP3=1016+AMP3; } else{ AMP3=1016-AMP3; //Negatív félperiódus } PDC0L=AMP1; PDC0H=AMP1>>8; PDC1L=AMP2; PDC1H=AMP2>>8; PDC2L=AMP3; PDC2H=AMP3>>8; AMP alapból egy táblázatból olvas ki értékeket 0-255 között, de 253-tól minden normális csak 254 és 255-nél jelentkezik a hiba. Biztos valami túlcsordulás vagy valami, de nem találtam meg. A sine duty szintén 0-255 közötti értékek és két pozitív félhullám értékei vannak letárolva így a negatív félhullámot ki kell kiszámoltatni. A lényeg, hogy veszek egy 0-255 közötti értéket és megszorzom szintén egy 0-255 közötti értékkel az eredményt elshiftelem 6-tal, hogy 0-1016 közötti szám legyen. A PWM modulok komplementer üzemmódban vannak 1016 az 50% kitöltési tényező így ehhez képest +-1016 a szinusz pozitív és negatív félperiódusa. A maximális kitöltési tényező most 2032 (kipróbáltam 2044-el is, de ugyan az a hiba). A végén pedig beírom a regiszterekbe az alsó 8 bitet, majd a felső 3-at (próbáltam fordított sorrendben is, de semmi változás). Nem értem mi a hiba, valakinek van ötlete? A hozzászólás módosítva: Márc 2, 2017
Miért pont 1016=b'1111111000' szerepel 1024=b'10000000000' helyett?
255 * 255 = 65536 65536 >> 6 = 1024 A hozzászólás módosítva: Márc 2, 2017
Ezt elírtam: 256 * 256 = 65536
A hozzászólás módosítva: Márc 2, 2017
A lényegen nem változtat csak azért használok 0-255 közötti számokat, mert így elég 8 bites változókat kezelni szorzásnál a 8*8 bites változók szorzása lényegesen gyorsabb mint a 16*16 biteseké, még a hardveres szorzásnál is lényeges a különbség.
Minden esetre nem találom a hiba okát próbálom számolgatni, de semmi. Annyit javítanék, hogy 2db tűske van egy periódusban és mindkettő visszafelé hat azaz azon a két helyen esik a feszültség. Elég körülményes a hiba megtalálása, mert rendes modulált két fázis közötti szinuszt állítok elő szóval nem a szokványos szinusz függvényt kell használni hanem egy trükkösebbet, de maga a függvény biztos, hogy rendbe van, mert 253 és az alatti amplitúdó értékekkel minden ok.
Nem tudom milyen PIC ez, szinkronizálod-e a PWM váltásokat valami LD vagy UDIS bittel, hogy egyszerre történjen a váltás.
18F4431 nem tudom, hogy van e ilyesmi ezen, de nem feltétlen gondolnám hogy ez az oka. 253-mal szorozva a szinusz értékét a jel normális 254 vagy 255-tel már nem.
A hozzászólás módosítva: Márc 2, 2017
Igen van benne: PWMCON1->UDIS bittel lehet lehet tiltani/engedélyezni a regiszterek frissítését, de igazad van, ennek a hibának máskor is elő kellene jönnie. Debuger módban figyeld a számítások közben, vagy logolj akár csak a memóriába és olvasd ki debuggal.
Most nézem tényleg benne van, de alapból engedélyezett a frissítés.
Egyébként pont kérdezni akartam, hogy is működik ez a debug? Eddig a pickit2-t csak programozásra használtam, de gondolom lehet vele debugolni is, illetve az mplab x ide-ben is van debug de még az se használtam. Lényegében csak a pwm regiszterek vagy az azokhoz használt segédváltozók értékeit kellene kiolvasni attól függően éppen hol jár a szinusz táblázat, csak még nem tudom hogy lehet ez elérni. Ha esetleg megírod vagy valaki más azt megköszönném. Addig is megpróbálok utána nézni, hátha magamtól is rájövök,.
Valami túlcsordulási hiba lesz. Kellene a kód egésze, és áttekinthetőség végett jó lenne unit szintre szervezni a kódot. Egyenlőre legyen csak jó az egyik amp.
Hogy szorzást minek használsz, amikor sima összeadás is elég, azt nem igazán értem. Nincs annak a picnek elég flash memóriája a program mellett még 720 byte-nyi (360 x 16 bites szó) konstans tömböt elrakni?
Miért ne szorozzon az a kontroller, ha ven benne 8 bites szorzó? Már csak az a kérdés, hogy használja-e.
Milyen módban van a Power Controll PWM? Belefér -e a teljes kitöltés módosítása a Continuous Up/Down Count mode with double updates módban az aktív periódusba? Adatlap: Figure 18-12.
Felőlem aztán szorozzon
![]() ![]()
Komplementer üzemmód free running, edge aligned. Nem akarok continuous up/down módot használni.
Lényegében az alap szinuszt letárolom 0-255 között pontosabb 0-255 között a pozitív félperiódust 0-179°-ig de program szempontjából könnyebb volt, hogy 0-359-ig tárolok be 2 pozitív félperiódust 180°-tól pedig fordul a polaritás a félhidaknál. Nem igazán értem, hogy lehetne szorzás nélkül megoldani egy szinusz hullám tetszőleges amplitúdó változtatását. Hacsak nem tetárolom az összes szükséges változatot külön egy táblázatban, de ki a fene csinálna legalább 100 táblázatot. A kód elég hosszú nincs unit szintre hozva és nem biztos hogy más számára átlátható, bár nekem megfelel így is. ![]() Egyelőre próbálom megfejteni a hibát, és azt hogy hogy kéne használni a debugot.
A másik gond az, hogy mint említettem ez nem sima szinusz táblázat. Ha fogok egy sima szinusz táblázatot és abból állítom elő a szinuszokat akkor két fázis között nem szinusz lesz, legalább is jóval kisebb amplitúdójú és csak szakaszos szinusz. Matematikailag ugyan működik, hogy két szinusz összege is szinusz, csak a félhidaknál ez már nem így működik.
Oké, szóval van egy kicsike gabalyodás.
Te első alkalommal fognád a maximális amplitudót, meg a fázis állapotot, és gyártanál belőle egy 64-el leosztott értéket így: Idézet: Aztán pedig vizsgálod a fázis állapotot, mert a tömbben nem volt benne a teljes 360 foknyi cucc:„AMP=255; //Amplitude[POT2]; AMP1=AMP*Sine_duty[counterA]; AMP1=AMP1>>6;” Idézet: A felvetődő kérdés, hogy ha nincs benne a teljes 360 foknyi cucc a táblázatban, előzőleg miért nem veszed azt figyelembe az indexelésnél is?„if(counterA<180){ //Pozitív félperiódus a komplementer üzemmód miatt AMP1=1016+AMP1; } else{ AMP1=1016-AMP1; //Negatív félperiódus }” Ha még több memóriát spórolnál, nem kell még 180 foknyit tárolni sem. Elég csak 0-tól 90 fokig. 90 foktól fölfelé ugyanis tükröződik ugyan úgy, ahogy 180 fölött meg negatív lesz. Idézet: „Lényegében az alap szinuszt letárolom 0-255 között pontosabb 0-255 között a pozitív félperiódust 0-179°-ig de program szempontjából könnyebb volt, hogy 0-359-ig tárolok be 2 pozitív félperiódust 180°-tól pedig fordul a polaritás a félhidaknál.” Pont fentebb írtam, hogy program szempontjából könnyebb volt ha 360 elemet tárolok el és a negatív felet csak "tükrözöm" a félhíddal. Tehát figyelembe veszem és persze ha A / B/ C >=360 akkor nullázás. Most nem térnék ki minden részletre, de csinálok olyat is, hogy 50Hz alatt megy ez az amplitúdó szorozgatás de 50Hz felett már simán a táblázatból olvasom ki az értékeket picit alakítani kell és egyből megy a PDC regiszterekbe. 50Hz-től minden okés nincs torzulás tehát mindenképpen az AMP-os szorozgatás környékén van a hiba. (Tényleg elég sok plusz funkció van beépítve amire most nem térnék ki csak a fent említett programrészletnél van hiba mivel elve úgy kezdődik, hogy ha 50Hz alatti a beállítani kívánt érték akkor belép a korábban írt programrészbe ha nem teljesül a feltétel és 50Hz vagy a feletti a beállított freki megkerülöm az amplitúdóval való szorzás és 64-el való osztást és csak simán shiftelem <<2-vel ami lényegében 4-el való szorzás. Ráadásul a PDC regiszter is úgy lett beállítva, hogy megfeleljen a két számítás közötti különbségnek. Az első esetben ahol a hiba van 255*255/64 = 1016 a második esetben 255*4= 1020. Így a PDC regiszter maximális értéke 2040 és az 1020+- a kapott értékek az adott periódusnak megfelelően. Annyi csalás van benne, hogy 0-1016 között mozog az amplitúdóval kalkulált programrészlet így már 255-ös értékkel is van benne némi amplitúdó csökkenés ami még jól is jön. A hozzászólás módosítva: Márc 3, 2017
if(.........){ //50Hz-nél kisebb?
AMP=255;//Amplitude[POT2]; AMP1=AMP*Sine_duty[counterA]; AMP1=AMP1>>6; AMP2=AMP*Sine_duty[counterB]; AMP2=AMP2>>6; AMP3=AMP*Sine_duty[counterC]; AMP3=AMP3>>6; if(counterA<180){ //Pozitív félperiódus a komplementer üzemmód miatt AMP1=1020+AMP1; } else{ AMP1=1020-AMP1; //Negatív félperiódus } if(counterB<180){ //Pozitív félperiódus AMP2=1020+AMP2; } else{ AMP2=1020-AMP2; //Negatív félperiódus } if(counterC<180){ //Pozitív félperiódus AMP3=1020+AMP3; } else{ AMP3=1020-AMP3; //Negatív félperiódus } //AMP1=2036; PDC0L=AMP1; PDC0H=AMP1>>8; PDC1L=AMP2; PDC1H=AMP2>>8; PDC2L=AMP3; PDC2H=AMP3>>8; } else{ //50Hz vagy annál nagyobb //DUTY CYCLE WRITING AMP1=Sine_duty[counterA]; AMP1=AMP1<<2; AMP2=Sine_duty[counterB]; AMP2=AMP2<<2; AMP3=Sine_duty[counterC]; AMP3=AMP3<<2; if(counterA<180){ //Pozitív félperiódus a komplementer üzemmód miatt AMP1=1020+AMP1; } else{ AMP1=1020-AMP1; //Negatív félperiódus } if(counterB<180){ //Pozitív félperiódus AMP2=1020+AMP2; } else{ AMP2=1020-AMP2; //Negatív félperiódus } if(counterC<180){ //Pozitív félperiódus AMP3=1020+AMP3; } else{ AMP3=1020-AMP3; //Negatív félperiódus } PDC0L=AMP1; PDC0H=AMP1>>8; PDC1L=AMP2; PDC1H=AMP2>>8; PDC2L=AMP3; PDC2H=AMP3>>8; } Nem akarok nagyon ideszemetelni, de a két feltételben elhelyezett programrészlet között alig van különbség az else ág működik az if-esnél AMP=254 vagy 255-nél jön a hiba, alacsonyabbnál minden ok. Gondolom, hogy túlcsordulás, de nem találtam még meg, hogy hol. AMP, AMP1-AMP3 unsigned int, a tömb unsigned char. Az "A" "B" "C" számlálók is unsigned int.
Két sorban végül is működik, de ahogy írtad úgy is. (El is tárolom a memóriámban így fogom most már használni.
![]() Na de még mindig gáz van, ha így írom ok: AMP1=(unsigned int)Sine_duty[counterA]<<8; AMP1=AMP1>>6; ha így akkor megint kezdi a hülyeséget: AMP1=Sine_duty[counterA]; AMP1=AMP1*255; AMP1=AMP1>>6; Ezt már nem értem, ha shiftelem <<8 olyan mintha 256-tal szoroznám, nem lehet túlcsordulás, mert akkor shiftelésnél is jelentkezne. Olyan mintha maga a szorzás néha megtréfálná.
A hozzászólás módosítva: Márc 3, 2017
Még mindig ugyan az a hiba.
Annyit megnéztem szkópon, hogy az alsó kapcsolóelemnél van a gond. Ha 253-mal vagy kisebbel szorzom ok, ha 256-tal szorzom ok. Csak 254 és 255-tel van gond nagyon furcsa. A hozzászólás módosítva: Márc 3, 2017
Annyi biztos, hogy programhiba csináltam pár képet a jelalakokról, és közvetlenül a pic kimenetén is mértem egy r-c szűrővel és a hiba ott is jelen van.
Az alapfüggvénynek úgy kéne kinéznie mint a szinusz.jpg képen szereplőnek. A másik két szkópos kép szerintem egyértelmű, és az is, hogy nem túlcsordulási hibáról van szó. Gondolom a fordító ha létrehozom a változókat szépen lefoglalja a memóriaterületet és véletlenül sincs olyan, hogy egy adott változó memóriahelyére időnként más változók értékei is odakerülnek. Kezdek kifogyni az ötletekből 2 napja keresem az okot de semmi.
Biztos, hogy jó a táblázatod?
A szinkronizált frissítéshez: pont az a probléma, hogy engedélyezve van. Ilyenkor megtörténhet, hogy a dupla bufferelés miatt pont olyankor frissíti a PDC értékét, amikor még nem teljes a új kitöltési érték beírása (főleg ha még az L/H beírása között számolgatsz is). Tehát a helyes megoldás: letiltani a frissítést (ilyenkor a régi értékekkel megy tovább), és ha minden értéket beírtál újra engedélyezni. Így az összes változás a következő ciklusban lép életbe.
A táblázat biztos hogy jó, bizonyos feltételek között elég szép a szinusz szkópon néztem, csak a programhiba néha bekavar.
Ez jön ki ha a 2 fáziskimenet különbségét veszem (lásd. kép), mintha feszültségkülönbséggel számolnék legalább is pont úgy kalkuláltam az értékeket. Egyébként pár külföldi oldalon is ilyen használnak ha modulált 3 fázisú szinuszt kell előállítani egy része onnan származik. Ok, ezt a frissítést megpróbálom lehet ez a gond.
Kipróbáltam erős javulás, de még mindig van 3 kis tűszerű impulzus a csúcsoknál legalább is olyan mintha amikor először eléri a max kitöltési tényezőt valamiért visszaesne, de megnézem még a pic kimenetét is közvetlenül, de nem a maximális kitöltési tényező értékével lesz a probléma, mert egy jó darabig megy maximális értéken is csak előtte ott a "visszaesés" a szinusz csúcsán illetve a szinusz utáni "ugrás" helyén is, de erősen javult a szinusz alakja. Szóval köszi!
![]() Még nézem hátha megtalálom az "új" hibák okát, de ha van ötleted szívesen fogadom. A képért bocs, de a telefon kamerájának exponálása ilyen. A hozzászólás módosítva: Márc 3, 2017
|
Bejelentkezés
Hirdetés |