Fórum témák
» Több friss téma |
Idézet: „Vegyünk 30 dkg valamit, reszeljünk hozzá 10 dkg amolyat, majd keverjük össze 2dl emilyennel, végül süssük meg tetszőleges hőfokon ameddig kedvünk tartja. Pfuj, ezt a kutya sem eszi meg, mit rontottam el?” Tudja a fene. Mi ez valami titkos CIA project? Valami támpont csak kellene. A bemenő jellel biztosan nincs gond? Hogyan veszed a jelet? (SPI, IIC, ADC...) Milyen programozó? Milyen assembler?
Már meg oldódott, köszönöm.
![]() A hozzászólás módosítva: Ápr 28, 2017
Köszönöm! Ez az oldal nagyon hasznos számomra!
Sziasztok, szeretnék kérdezni egy pár dolgot ami nem tiszta nekem.
Mostanában kezdtem assemblyben programozni, nagyon tetszik, élvezhetőbb rajta a fejlesztés mint C-ben (a logika felépítése nehezebb, viszont a modulok beállítása átláthatóbb) A kérdésem a következő lenne, adott a következő kód (PIC12f629):
Így helyesen elhelyezem a GP regiszterek elejétől a változóimat ? Illetve ez így egyáltalán változóként működik? Így elvileg 3 regisztert foglalok , viszont MpLab alatt többnek jelzi, ez miért lehet ? Köszönöm ! ![]()
Elsőre el kell döntened, hogy abszolut vagy relokálható kódot szeretnél írni.
Abszolut kódban a cblock ... endc direktívákkal lehet helyet foglalni a változóknak, relokálhatóban az idata szekciókban a dw és az udata, szekciókban a res direktívákkal. Ld. MpAsm leírása. A második kérdésre a válasz a kép utolsó sorában: Egy kis adat- és programterület a nyomkövetés céljára le van foglalva. A nyomkövetéshez un. header -re lenne szükség...
Direkt az abszolút miatt kérdeztem, még 64x8 rekeszt nyomon tudok követni és magam optimalizálni (meg tanuláshoz jobb ha látom hogy mi hol van), viszont egy 18f szériában már nem gondolnám hogy ez menne. Így most majd a cblock ... endc -t fogom használni.
Ha nem debugolom akkor csak annyi helyet foglal amennyit én lefoglalok saját magamnak ? Idézet: „Direkt az abszolút miatt kérdeztem, még 64x8 rekeszt nyomon tudok követni és magam optimalizálni (meg tanuláshoz jobb ha látom hogy mi hol van), viszont egy 18f szériában már nem gondolnám hogy ez menne.” Ebben az esetben csak 64 rekeszt kell észben tartani, de nem ördöngösség a 18F -ek abszolút módban való kezelése. Úgyis lesz egy-két tömb, buffer, stb. Valahogy el kell magyarázni a keretrendszernek, hogy nem szeretnéd nyomon követni.
Mostmár átraktam CBLOCK-osra. Még egy utolsó kérdésem lenne, és utána visszamerülök a tanulásba.
Az alábbi kód mennyire helyénvaló ? Mennyire sikerült szépen/nem szépen megoldanom, mit lehetne egyszerűsíteni, mit kellett volna másképp csinálni? Azért kérdezem, mert assemblyt a tömör kód miatt kezdtem el tanulni és itt is próbáltam a legtömörebben megírni. GP5-4-2 között valósít meg egy futófényt. Az időalapot a TMR0 modul adja, csak "felbővítettem" 16 bitesre. Itt egy IF ELSE szerkezetet szerettem volna megvalósítani ezzel. UI: A W_SAVE és STATUS_SAVE jelenleg direkt nincs használva, pusztán azért mert nincs most rájuk szükség.
A hozzászólás módosítva: Jún 5, 2017
Észrevételek:
Idézet: „MAIN_PROG CODE” Ez a relokálható kódhoz tarozik. Abszolút kódban nem kell külön a kódot bevezetni. Egy adott címen való kezdéshez az org direktívát lehet használni:
Idézet: „ISR_RUTIN BCF INTCON, T0IF ;TMR0 INTFLAG CLEAR INCF TMR0_SZAMLALO ;TMR0 16 BITRE BŐVÍTÉSE” Majdnem minden művelet elvégzése módosítja a STATUS regiszter tartalmát. A megszakítási rutinnak minden (nem szándékosan) módosított regiszter értékét mentenie kell a belépéskor és a kilépés előtt vissza kell állítania:
Köszönöm az észrevételeket, javítottam a kódot eszerint! A regisztereket egyenlőre azért nem mentettem ki, mert mindent a megszakításban oldottam meg a "fő" programhurok csak ébrentartja a chippet, de beiktatom a mentést.
UI: Az nem baj hogy goto-zok az elégazásoknál, meg lehetne oldani azt szebben is ? Köszönöm mégegyszer! A hozzászólás módosítva: Jún 5, 2017
Assembly -ben csak goto ill. call utasítással lehet a végrehajtást vezérelni (ill. a PCL írásával).
Akkor maradok ennél, csak más nyelveknél ugye nem szeretik mert spagetti kódot okoz.
Egy legutolsó kérdés; 12f629-nél a programmemória 001h és 002h helyén mi található ?
Én a számlálókat ha lehet visszafelé számolósra csinálom, mert a nullát könnyebb vizsgálni (decfsz).
Az ilyen sorszámozott állapotoknál C-ben is inkább switch case jellegű megoldást használnak. Valahogy így:
Így hogy fix helyre rögzítem a kódot ez is járható és elegánsabb
![]() Idézet: „12f629-nél a programmemória 001h és 002h helyén mi található ?” Semmi, az is használható csak csínján kell bánni vele, mert összeakad a megszakítással ami ugye a 004h címen kezdődik. Bár elméletileg a fordító hibát ad rá ha ilyen előfordulna. Bár nálam az szokott inkább előfordulni, hogy ORG utasítással beteszek egy kódrészletet a memória közepére és ha valamit még faragok a kód elején akkor az előtte való rész már túllóg azon a címen ahova az előzőt raktam, így azt át kell tenni máshová. Egyébként az Mplabban, ha lefordítod a programod a view menüben vagy egy Program memory, ha erre rányomsz akkor megnézheted, hogy melyik utasítás pontosan hol helyezkedik a memóriában. És ez az assembly másik nagy előnye, hogy ott is assembly kódokat mutat, így pontosan érted az egészet. A hozzászólás módosítva: Jún 5, 2017
Igen, csak az zavart meg hogy 001h és 002h-ra RETLW 0x0-t csinál magától a többi üres helyet pedig ADDLW 0xFF-el tölti ki. Ha így ahogy végigondolom akkor arra a 2 helyre 1 bármit és 1 goto-t kell írnom különben jön az összeakadás.
Érdekes ez az assembly világ, nekem nagyon tetszik ![]() Idézet: „Ha így ahogy végigondolom akkor arra a 2 helyre 1 bármit és 1 goto-t kell írnom különben jön az összeakadás.” Nem egészen. Ha nem használsz megszakítást a programban, akkor a program első sora ez legyen: org 0x0000 Utána írhatsz folyamatosan. Ha akarsz megszakítást használni, csináld ezt:
Így ugyan elvesztesz 2-3 byte programmemóriát, de biztos, hogy nem lesz ütközésed. A hozzászólás módosítva: Jún 6, 2017
De ha jól értelmezem és teljesen ki szeretném használni, akkor írhatom ezt is (nop helyén értelmes utasítás):
Ez így is működne ?
Én azért a megszakítás címét minden esetben átugranám, tehát a 0x00 (reset) címről egy GOTO-val megyek minden esetben a megszakítás(ok) utáni címre.
Nem feltétlen szeretném felhasználni a 001 002 területet, csak elméletben kérdezem
![]()
Vannak a 12F629 -nél nagyobb programmemóriával rendelkező típusok is 4, 8 ill. 16kszóval. A goto ill call utasírások kódolása csak 11 bites címet enged meg, a legfelső biteket a midrange kontroller a PCLATH regiszterből veszi. Ha a inicializáló rutin magasabb címekre kerül, a PCLATH értékét az ugró utasítás előtt be kell állítani. Ezen utasítások számára tartják fenn a 1..3 címeket.
Régebben voltak nem törölhető memóriával rendelkező típusok is pl. 16C622. Ezen kontrollereknél nagyon jól jött az a bizonyos 3 utasítás. Miután egy rekesz tartalma felülprogramozható 0x0000 (nop) -pal, igy néhány lehetőség még maradt a program módosítására. Az első verzió a 0 címen elhelyezett utasítással ugrott a programra. A második a 0. címre egy nop -ot tett, a 1. cimre helyezte az ugrást. A harmadik a 1. címre is noip -ot tett és a 2. címet használta az ugrásra. A negyedik a 2. címre is nop -ot tett és a 3. címről ugrott. Ezek után ki lehetett dobni a kontrollert.... Persze egy rövid más célra szolgáló rutin is elhelyezhető itt. Ha a nyomkövetést is szeretnéd használni, a legelső utasításnak nop utasításnak kell lennie. Ugyanis a belső töréspont regiszter alapesetben 0 értékre áll be, a reset hatására a 0. címen levő utasítás végrehajtódik mielőtt a vezérlés a debugger executive -re adódik. Miért nem szerepel sehol sem a leírásokban, mire szolgál a userid és a konfigurációs regiszterek közötti tartomány? Ha nyomkövetést végzel midrange kontrollerrel, a 0x2004 címre egy ugrás kerül, ami a debugger executive egyik belépési pontjára adja a vezérlést. Amennyiben a program azon a címen hajt végre utasítást, ami a töréspont regiszter tartalmaz vagy lépésenként hajtja végre a programot, egy megszakítás szerű esemény következik be, a program végrehajtása a 0x2004 címen levő utasítás végrehajtásával lép be a debugger executive -be. A hozzászólás módosítva: Jún 6, 2017
Működne így a dolog, de ha az ember picit nem oda figyel, sok bosszúságot tud okozni, szóval én nem ajánlom.
Szia!
Ez így jó, de az 5. sorban a goto START a 3. memóriahelyre került, így felesleges az org 0x0004, mert már úgy is az következik !!
... na az ilyenekből szoktak a problémák születni (mármint hogy nem írja oda az org direktívát, aztán ha módosul valami, akkor jön a fejvakarás)
![]() A hozzászólás módosítva: Jún 6, 2017
Így már érthető annak a kihagyásnak az értelme. Így sem fogom egyhamar ezt a 1,75K memóriát felhasználni.
A gondom az hogy nincs ötletem milyen projektet valósítsak meg gyakorlásképp (csak ez a futófény jutott eszembe) kissi: Ahogy zenetom gondolja, azért hagytam ott, hogy biztosan ott legyen a kód. Örülök hogy mostmár a flash memóriák korában élünk ![]() ![]()
Annyival egészíteném ki, hogy a megszakítást nem csinálnám ugrással, semmi értelme szerintem. Az ORG 0x004 után jöhet maga a megszakítási rutin, ahol annak vége van oda tenni a Start címkét, azt nek kell címezni oda kerül ahová a megszakítás engedi.
Ez már csak szokás kérdése.
Én mindig úgy írok programot, hogy kihagyok egy csomó helyet, majd beteszem az inicializálást, a megszakítást, egyéb előre megírt rutinokat, (pl: osztórutin) majd visszamegyek az elejére, és írom a programot. Így, ha újabb bármit definiálni akarok, vagy újabb elemet tenni a CBLOCK-ba, nem kell végigszkrollozzak olyan dolgok fölött, amiket nem szándékozom már piszkálni. Vagy ha mégis, hát tudom hol vannak. Ha pedig kész vagyok, törlöm az üres területet.
Probléma bármiből lehet...
![]() A 4 utasítás egy pillantással átlátható ( ez a jó az assemblyben, hogy látod, hogy mi kerül be / persze itt is lehet használni a fordító kényelmét... ! / !) Minden esetre "kinek a pap, kinek a papné" ![]()
Ezt jó ötletnek tartom, mert egy kapásból 2 utasításciklussal gyorsabb a dolog, és a főprogramra kb. semmi hatással nincs ez a változtatás!
![]() |
Bejelentkezés
Hirdetés |