Fórum témák
» Több friss téma |
Fórum » PIC - Miértek, hogyanok haladóknak
Nem ez az ido fix. Tehat 9600 -l nem mukodokepes. A jelnek meghatarozott allapotai lennenek uart on keresztul erzekelve. Akkor vagy marad mas megoldas az uarton kivul vagy 19200bps.
Sziasztok!
Van egy problémám. Egy P szabályozóról van szó. dsPic-et programozok C-ben, C30 compilerrel. Két integer adatot kivonva egymásból lehet pozitív és negatív szám is, így az eredményt signed int-ben tárolom. Viszont úgy tűnik, hogy nem úgy működik, ahogy kéne neki. Ha mondjuk X=1, Y=2, Z=5, Kp=1. eredmeny=X-Y; output=Z-eredmeny*Kp, az nem 4 lesz. Próbáltam úgy is, hogy if-fel vizsgáltam, h negatív-e, de úgy se jött össze. Hogy kell megmondani a fordítónak, hogy a negatív számot negatívnak kezelje?
Rég volt matekórám, de szerintem: 5-(1-2)*1 = 5-(-1)*1 = 5-(-1) = 5+1 = 6
Bizony-bizony! Ebbe belekeveredtem
Szóval erre gondoltam, ezt a kifejezést programoztam le: output=Z+eredmeny*Kp. De nem működik.
Meg kell nézni a C fordító assembly kimenetét, és végigszámolni, hogy ki mit csinált rosszul.
Szerintem valamit nem jól értelmezel, mert ennek simán működnie kell. Szimulátorban milyen eredményeket ír ki a változó név mellé a watch ablakban az érték oszlopban, ha negatív számot töltesz bele?
Minden változód int is vagy van köztük unsigned int?
Ha unsigned int is van, akkor castolni kell hiába az output sima int. Így kell, hogy: output = (int)Z+eredmeny*Kp Az a lényeg, hogy magát a műveletet nem kell zárójelbe tenni, mert akkor elvégzi a zárójelben lévő műveletet és utána castol, aminek nem lenne semmi értelme.
Csak signed int van.
Próbáltam először így: error=SP-PV; PDC1=PWM_kozep+Kp*error; //ahol PWM_kozep és Kp konstans. nem lett jó. Aztán így is próbáltam: error=SP-PV; if (error<0) { error=PV-SP; PDC1=PWM_kozep-Kp*error; } if (error>=0) { PDC1=PWM_kozep+Kp*error; } Így sem lett jó, mert bármelyik if teljesült hozzáadta a PWM_kozep-hez a második kifejezest. Figyeltem a watch-ban, és a kettes kompl. negatív látszott.
Azt ki tudod valahogy deríteni, hogy az error jól számolódik-e ki? Pl. Gondolom ha a visszacsatolt jel kisebb mint egy referencia, akkor lesz error negatív, vagy fordítva. Tehát olyat ki tudsz próbálni, hogy pl.:
Ha ez nem működik, akkor próbáld ki, hogy az if elé direktben beírod, hogy error = 100, és nézd meg világít-e a LED, ezután nézd meg error= -100 esetén mi lesz. Amit írtál az if-es példádban biztosan nem jó, ugyanis, gondolj bele ha SP=2 PV=5. Ekkor error = -3. Belép az első if-be. error újra kiszámolódik, most 3 lesz. Az első if-nek vége, majd mivel már error>0 (ugyanis 3) belép a második if be is. Ha azt írnád, hogy esle if (error>=0) akkor jó lenne.
Úgy látom, h ha manuálisan beírom, hogy -100, akkor valóban annyi az értéke. Ha viszont számolnia kell (SP-PV), akkor más számok jönnek ki - mintha nem 2-es komplemes lenne.
És most SP és PV értéke honnan jön? Olyat is ki próbálhatsz, hogy direktbe beírod, hogy pl SP=30, PV=70 és nézed mi történik, hogy tényleg a kivonás rossz-e.
Ott érdemes lenne cast-olni, hátha megoldja: error = (int) SP - PV.
SP egy int változó, programban adok neki értéket, ami aztán nem változik (egyenlőre).
PV-t A/D olvassa ki, szintén int-nek van definiálva. De most végigpróbálgatva kiderült, hogy jól működik, ott rontottam el, hogy túl nagy értéktartományt engedtem meg. Akkor most másik kérdés. Azt hogy oldjam meg, hogy az error-t megszorzom Kp-vel, amit eddig int-nek definiáltam. De tört számmal kell szoroznom, mondjuk 0.1-gyel. De a végeredmény int-ben kell. És köszönöm az eddigi segítségeket!
Szorozni 0,1-gyel olyan, mint osztani 10-zel.
Ez övön aluli volt. Egyrészt az osztás 18 ciklus, másrészt 0.11-gyel szorozni, az nem lesz egyszerűbb osztással sem. Tehát inkább az a kérdés, hogy ott cast-olni kell?
Nem egészem értelek. De ha az baj, hogy túl sok a 18 utasítás, akkor biztosítalak, hogy ha double-ként kiszámolod, hogy x * 0,1 és vissza konvertálod int-re, akkor az 180 utasításból sem lesz meg.
Egyébként úgy kell, hogy y = (int) ((double) x * 0.1).
Double helyett lehet float is.
Végül is szerintem úgy a legegyszerűbb és leggyorsabb, hogy ha a Kp = 0.234, akkor eredmeny = (error * 234) / 1000. Értelemszerűen ha tudod, hogy Kp pl 2 tizedes jeggyel van értelmezve, akkor 100-zal kell osztani.
Aha, ez tök jó ötlet, erre nem gondoltam. Bár most ahogy tesztelgettem, úgy tűnik, hogy a sima törttel szorzás is működni fog. Csak lassan haladok, mert lusta vagyok a kódot könnyen szimulálhatóvá átírni, így mindig módosít-letölt-futtat-debugol kombóval nyomom.
Idézet: „lusta vagyok a kódot könnyen szimulálhatóvá átírni” Csak egyszer kellene... Egy szimbólumtól függő feltételes fordítással pillanatok alatt át lehet térni a szimulálható és a futtatható verzió között. Egy kódrészlet is szimulálható (fűleg, ha csak számítgatás). A rutin elejére kell állítani a PC -t, aztán mehet a szimuláció akár lépésenként. Sokkal eredményesebb a szimuláció. Vannak korlátozott számú újraprogramozási lehetőséggel bíró típusok. A hozzászólás módosítva: Szept 30, 2013
És hogy tudom a PC-t oda állítani? Nem zavar be az, h pl az egyik értéket AD-ból nyeri, illetve, h vannak interruptok?
Összetett a kérdésed:
- Számolgatás helyességének ellenőrzésére nem szükséges, hogy az értékek a forrásukból érkezzenek, elég a teszt értékeket beírni pl. a Watch ablakon, - Ha kellenek a valóság közeli (mondjuk A/D) értékek, stimulus beállításával fájból olvashatók, - Megszakítás szimulálható. Ahogy írtam, egy feltételes fordítással átalakítható a kód, hogy a nem szimulálható ((M)SSI) perifériák kezetését kihagyja. Hogyan juttatható el a program a tesztelni kívánt részhez: - Töréspont az inicializálás végére (lesznek megszakítások), - A PC átállítása a kívánt részlet elé (Set PC), - Teszt adatok feltöltése a Wath ablakkal, - További töréspontok beállírása a vizsgálni kívánt rész összes kijáratához (csak, ha annyira összetett, hogy lépésenként túl hosszú lenne) és a kritikus múvelet utánra. - Továbbindítás és/vagy lépésenkénti műveletvégrehajtás.
Hú, köszönöm, ezek nagyon hasznos infok!
Idézet: - például ezt sem tudtam, mindig csak nézegettem. „teszt értékeket beírni pl. a Watch” Meg ez a Set PC-s dolog is nagyon tuti. Ezeket ki is próbáltam már, és gyorsabb is így az egész folyamat. Köszi a segítséget!
Sziasztok!
Van egy ilyen típusú flash memóriám. Arra lennék kíváncsi, hogy ennek a tartalma kiolvasható-e PICKIT2 segítségével? (Ha nem akkor milyen más módszerek jöhetnek szóba?)
Nem.
Építeni kell hozzá valami olvasót (esetleg lehet próbálkozni a netről rendelni). Mivel SMD, ezért vagy veszel aranyáron hozzá foglalatot, vagy kénytelen leszel ráforrasztani valami panelra.
A foglalat nem gond, csinálok hozzá forrasztható kivezetéses NYÁK-ot. A lényeg az lenne hogy van 2 egyforma memória chipem és a beltartalmát szeretném átmásolni az egyikből a másikba. (Az a valós probléma hogy van egy tabletem amiben ez a chip van. Elállítottam benne egy fájlt és azóta nem tölt be. recovery menüt nem lehet behozni, így nem tudom frissíteni se az androidot. Bármilyen megoldást elfogadok)
A belsejéről rakjál fel fotókat. 99%, hogy kiforrasztás nélkül is hozzá lehet nyúlni. Vagy rávehető, hogy bootoljon máshonnan, vagy JTAG-en keresztül átírható. De ez innentől már inkább nem PIC témába való, szóval keress valami jobb témát neki.
|
Bejelentkezés
Hirdetés |