Fórum témák
» Több friss téma |
Fórum » PIC - Miértek, hogyanok haladóknak
Megint egy táblával kínlódom. Miért nem oda ugrik ahová szeretném?
És hova ugrik helyette? A PCL értéke nem már a következő utasításra mutat, amikor az összeadást végrehajtja, és így W=0 kezdőértéknél kerülne az "ADDWF PCL,F" utáni sorba?
Arra már rájöttem hogy valószínűleg az a baj, hogy a PC felső részét is be kellene állítani. Egyenlőre nem jöttem rá hogy hogyan...
Szia!
Az sem ártana, ha vizsgálná, hogy a táblázat elfér-e egy 256 byte-os lapon... Az első ugrásra a 0 sorszámmal kell hivatkozni, mivel az add utasítás a megnövelt pc -hez adja hozzá a w regiszter értékét.
Szia
Valamit sikerült elérni... "movf PCL, W" utasítással kiolvasódik a PCH tartalma is a PCLATH-ba és ott is marad! Ha utána írom át a PCL-t, akkor már nagyjából jó helyre ugrik!
Noigen, a felső címrészt be kell állítani a PCLATH-ba. Ezügyben az adatlap szépen leírja, hogy hogy működik a PC feltöltése. A táblázattal valóban vigyázni kell, hogy ne csorduljon át ilyen laphatáron, vagy pedig igazi, kétbyteos összeadással kell kiszámolni a címet PCLATH-ba és PCL-be.
Igen, pont most akartam írni hogy csak a tábla első felében működik jó, a második felében túlcsordul a PCL és rossz helyre ugrik.
Idézet: Feltaláltad a GOTO SOMEWHERE utasítást? „Ha utána írom át a PCL-t, akkor már nagyjából jó helyre ugrik!”
Megpróbáltam összeadni két bájton, de valami nem jó. Mit rontottam el?
Nem tudom mit akarsz elérni ilyen módon, de bevallom soha az életben nem használtam ilyen szekvenciát, pedig egy pár programot megírtam már!
Mond el mit szeretnél, hátha van arra normálisabb mód is! Ez egyébként nem táblázat, hanem egy változótól függő feltételes elágazás.
Van egy regiszterem aminek a meglétét most a hiba kiderítéséig a "movlw d'8'" sorral helyettesítem (hogy könnyen át tudjam írni). Ez a regiszter azt tartalmazza, hogy a menürendszerben épp hol vagyunk. Ez az ugrótábla arra kell, hogy az adott menüpontba belépéskor a PIC a menüponthoz tartozó rutinhoz ugorjon.
Érdemes lenne laphatárra rakni az ugrótábla elejét, PCLATH legyen high(ugrótábla) PCL az meg ugye a sorszám ahova ugrani szeretnél az ugrótáblán. Ez a megoldás 256 elágazásig megfelel. Én az ilyen táblákat az utolsó lapokra szoktam rakni, mert így elkerülhető a fragmentáció.
Ehhez mit szólsz?
Végül is jó, de talán így ugrótáblaként lett volna a legelegánsabb.
Egyrészt a btfss-bra párost meg lehetne egyszerűbben oldani, ugyanis csak az "incf PCLATH,f"-et kellene átugrani, ha nincs carry (btfsc). Másrészt az "incf PCLATH"-nál nincs megadva, hogy az eredmény hova kerüljön, nem tudom, ilyenkor mi az alapértelmezett. Harmadrészt - és ez a legfontosabb - a W-hez nem PCL-t kellene hozzáadni a carry vizsgálata előtt, hanem a low(ugrótábla1) értéket!
Ez a fajta ugrótábla a 16F-ek "csökevénye".
Én valahogy így csinálnám (bár ezt fejből írtam, lehet, hogy valami nem pontosan így jó):
A legelegánsabb, ha kiszámítja a címet az ember és beírja a flash-be menet közben a goto utasítás operandusába Ehhez olyan PIC kell, ami tudja írni a saját flash-ét futás közben.
Idézet: „Mit rontottam el?” Az aktuális PCL helyett a táblázat első utasításának címe kellene, hogy legyen a kiindulási érték, ehhez kellene hozzáadni W négyszeresét (amit a két balra léptetéssel csinálsz meg).
Kérdés, meddig bírná a flash!? De jó ötlet!
Akkor már inkább a return stack tetejére kellene beírni, s egy return utasítással ráugratni.
Ha van elég RAM a gépben (legalább másfél giga), akkor érdemes a virtuális memóriát (lapozófájlt) letiltani, sokkal jobb lesz a gép válaszideje ablakváltásoknál. A böngésző kivételével a többi program nem egy processzorzabáló, csak a windows elcseszett lapozófájlkezelése miatt lassú az ablakváltás.
Ha indításonként először olvassuk és megnézzük, hogy jó-e a cím, és csak akkor változtatunk, ha nem jó, akkor szerintem elég sokáig
Az újabb PIC-ek csak 1000x írhatók!
Amit írsz azt feltételezi, hogy van néhány menüpont, ami többször ismétlődik. Ez elég valószínűtlen, de végül is néhány %-ban növelné az élettartamot. Az lenne még a megoldás, hogy számolni a regiszter ciklusát, és megfelelő számosság esetén áttenni a goto-t is másik címre, helyére pedig az új címmel egy BRA-t!
Az a baj ezzel még, hogy egy goto két programrekeszt foglal, tehát nem elég, hogy olvashatatlan lesz a kód, fixálni kell egy területen a táblát, ami esetleg még gondot okozhat, ha fogyóban a memória, de még nagyobb területet is foglal, mint az általam felvetett megoldás. Hogy elegáns-e? Szerintem inkább erőltetett.
Ha jól emlékszem, 18F-eken van DCFSNZ utasítás, ezzel lehet "szép" szekvenciát csinálni menüpont-elágazásokhoz: DCFSNZ-GOTO-DCFSNZ-GOTO-... De több menüpontnál meggondolandó szerintem az Attila86 által írt módszer is, főleg, ha rendes, hosszú goto-k vannak, amivel a programmemória bármely pontjára lehet ugrani.
Ha módosítások után is forrásból fordítja és nem a hex-be akar beletúrni, akkor édesmindegy, hogy hol kezdődik az ugrótábla, mivel a leírt módszer carryvel együtt számolja az elem címét. Az elején a négyszeres szorzás miatti egyedüli megkötés, hogy W-ben 64-nél kisebb értéket kapjon (talán 64 menüpont elég). Bonyolultabb menürendszereknél pedig már nem is biztos, hogy ilyennel csinálnám, hanem inkább egy állapotgéppel és az ahhoz tartozó, paraméterekkel feltöltött tömbbel.
Igen így is jó lenne, valóban:
Az állapotgépet nem pontosan értem, de jól hangzik!
Az állapotgépnél arra gondolok, hogy mondjuk papíron felrajzolod az egész menürendszert egy gráfba, a gráf csúcsai a menüpontok, a menüpontok közötti irányított élekre ráírod, hogy milyen esemény hatására kell az adott élen egyik pontból a másikba lépni. Ezután a menüpontokat meg kell sorszámozni, majd felvenni egy táblázatot, aminek minden eleme pl. a következőket tartalmazza:
- a menüpont megjelítendő szövege - a menüpontról az 1. számú esemény hatására melyik menüpontra kell lépni - a menüpontról a 2. számú esemény hatására melyik menüpontra kell lépni ... - a menüpontról az x. számú esemény hatására melyik menüpontra kell lépni - egyéb információk, ezek már alkalmazás-specifikusak lehetnek, ilyen pl. a menüpont aktiválásakor meghívandó szubrutin címe Ha ez megvan, akkor egyetlen programmaggal az egész, akármilyen bonyolult menüfán végig lehet sétálgatni (sokkal egyszerűbb a valóságban, mint így leírva). Nem kell bonyolult "eseményekre" sem gondolni: pl. van két-három nyomógomb, ezeknek a megnyomása az "esemény", illetve pl. meg lehet különböztetni hosszú és rövid megnyomást. Ilyen jellegű megoldás működik a 16F946-os órámban, aminek 3 nyomógombja van, de hosszú megnyomást is megkülönböztetek, valamint nyomva tartás esetén az "ismételt megnyomások"-at is. Ezenkívül ott bevezettem még egy olyan eseményt, ami az utolsó gombnyomás után pár másodperccel következik be - ezt alaphelyzetbe visszaállásra használom bizonyos módokból. Ha belegondolsz, egy egyszerű kétgombos kvarcóra is elég bonyolult menürendszerrel dolgozik, attól függően, hogy épp hol vagy, mindegyik gombnak más a jelentése. "Hagyományos" módszerekkel már az elején olyan átláthatatlan lett a kód, hogy kénytelen voltam erre az állapotgépes menünjárkálásra átírni, de nem bántam meg. Amikor rákerült az órára a DS1821, akkor annak a menürendszerbe illesztése csak a táblázat néhány új elemmel történő kiegészítésébe tellett, meg persze a meghívandó (primitív) rutinok megírásába. A gomb- és menükezeléshez semmit nem nyúltam. |
Bejelentkezés
Hirdetés |