Fórum témák
» Több friss téma |
Köszönöm szépen. Holnap reggel megpróbálom én is. Most nem vagyok már gépközelben.
Mi a leggyorsabb C kódja a 16 bites <<--->> 8 bites változók közti értékátadásnak? Természetesen garantálva azt, hogy a maximális érték 255 nél nem nagyobb előjel nélküli?
Egyik irányban valami ilyesmire gondolok:
És fordítva:
A fenti kódok csak arra példák mire gondolok konkrétan a 16/8 bites átalakítással kapcsolatosan.
Változók közötti értékátadásra gondolsz, vagy eljárások paraméter átadására?
Azért kérdem, mert megtévesztő, hogy komplett eljárásokat másoltál be. Miért van ennek jelentősége? Ennyire ki van hajtva a proci, hogy ez számít? Véleményem szerint beírod az értékadást, a többit a fordítóra bízod; jobb úgysem lesz. b) összehasonlíthatod az egyes módszerek közötti különbséget, ha megnézed a fordított kód hosszát. Rövidebb kód = gyorsabb kód.
Moderátorokhoz kérdés. Mi a hócipő történik, hogy nem tudok postot küldeni a fórumra? Üres üzenet jelenik meg helyette.
Szia!
Próbáltam, ahogy írtad, de nekem veled szemben teljes kudarc. Nagyon az elején vagyok még, s ennyiből nem sikerült megértenem. Próbálkozom még, nem adom fel.
Itt a módosított project. Kitöröltem belőle néhány felesleges search path bejegyzést a "Project" menü "Edit Search Paths" menüpontjával. Ekkor eltűnnek a "Specified search path does not exist:..." sorok is.
Alapvetően 16/8 bites változók közti értékátadásra gondolok. A paraméterbeli átadás ebben a tekintetben - szerintem - hasonlóan kezelendő.
A fenti kód egyébként jól működik, hibátlanul alakulnak a 8/16 bites változók egymásba. Ugyan számomra nem pontosan világos hogyan történik meg mindez. ![]() Például a Write függvény 5. sora így kerül lefordításra:
Értem a ze utasítás lényegét, de nekem ebből nem következik a 8/16 bites konverzió végrehajtása. Gyanítom nem korrektek, csak "éppen működőek" a fenti példa kódok (előző hozzászólásomban), és talán egy ADDRESS ERROR TRAP GENERATED is előáll, csak nem ellenőrzöm. Szóval hogyan is lehetne ezt a 8/16 bites konverziót egyszerűen kezelni C ben? (dsPIC33F) A hozzászólás módosítva: Ápr 18, 2018
Ezer köszönet!
![]() De jó napom volt ma ![]() Idézet: „Szóval hogyan is lehetne ezt a 8/16 bites konverziót egyszerűen kezelni C ben?” Egyszerűen használod a C szintaktikát és nem foglalkozol a generált kóddal. A fordító elvégzi a fordítást és a kód működni fog. { unsigned char b; unsigned int w; w = b; //nyilvan ez a sor torolni fogja w felso 8 bitjet b = w; //ez a sor pedig figyelmen kivul hagyja w felso 8 bitjet } Remélem a kérdésedre válaszoltam.
Igen, magam is így csináltam és jól működik. Kicsit hezitáltam hogy korrekt -e a megoldás, esetleg elvi hibás működés "véletlen" eredményeként kapok mégis megfelelő értékeket. Így akár a 32/8 bites konverzió is megoldható? Persze ügyelve a max. ábrázolhatóságra
Azt gondolom technikailag ugyanaz, csak a változók mérete tér el.
Ha már beszélgetünk róla, aminél tapasztaltam, hogy nem fordítja jól az XC8, az az alábbi kifejezés: w = b*10; //w-word, b-byte Ezt mindenáron bájton akarja kiszámolni, ha meg typecast-et használok, akkor hozzávesz 8 bájt nem inicializált területet és hibás lesz az eredmény. Szóval ehelyett: w = b; w *= 10; Ha valaki tudja, hogy mit kellett volna írjak egysoros kifejezést, az ossza meg velem, had tanuljak.
Nincs kéznél C fordító, de szerintem:
De ha jól rémlik, akkor ez is jó:
C szabályai szerint a unsigned char *Data egy pointer, amit az eljárás előtt a stack -ra tetet a fordító. A hívás után a pointer a W1 regiszterbe kerül. a ze [w1],w0 utasítás a w0 regiszter felső 8 bitjét nullázza, az alsó 8 bitre a [w1] alsó 8 bitjét másolja. A mov.w w0,test utasítás az így a w0-ban keletkezett szót teszi a test címére.
Idézet: „Ha már beszélgetünk róla, aminél tapasztaltam, hogy nem fordítja jól az XC8, az az alábbi kifejezés: w = b*10; //w-word, b-byte” A C szabályai szerint a kifejezéseket az első operandus adatábrázolásának megfeleő adatábrázolással kezdi a fordító. Mivet a b 8 bites (char) a szorzás eredménye is 8 bitesre konvertálódik.
Ebben a sorban azt írjuk elő, hogy a b változót a számítás előtt konvertálja word típusra. Mivel az első operandus ezek után word, a többi művelet is 16 bitesen végződik el.
Ha a konvertáláshoz nem 0x00 inicializált területet használt a fordító és emiatt módosult a változó értéke, az fordító hiba? Mert konkrétan ezt tapasztaltam.
Fejtsd ki bővebben, mert így nem érthető a probléma.
pl. b értéke 175 (0xAF) a művelet előtt
w=(WORD)b*10; és az mplab C18 úgy kezeli a b változót, mintha WORD-ként deklaráltam volna, tehát hozzáveszi a szomszédos memória cím tartalmát. Ha a PIC RAM-ban lévő értékek 0x01, 0x02, 0x03, 0xAF, 0x05, 0x06 akkor a typecast során a fordító a 0x05AF értéket (little endian) veszi a B változó értékének, és w = 0x05AF * 10; lesz. És nem tudom, hogy ez feature vagy bug.
Nem erről van szó.
Amikor előírod a típuskonverziót, a fordító egy átmeneti változót használ fel a konvertált érték tárolására. Ezt a változót használja fel a további számításokhoz. Lássunk egy példát. Sajnos itt és most a C18 nem elérhető, de használjuk a jogutódját (XC8) és hogy ne kelljen új project -et csinálni egy 16F1455 -hoz készültbe írtam bele a következő sorokat: WORD w; BYTE b; ... w = 65000; b = 175; w= (WORD) b * 10; Az első képen a futást megállítottam a b feltöltése után. Látható, hogy a w értéke 65000 - 0xFDE8, a b -é 175 - AF. A w címe 0x1E1, a b címe 0x1E3. A második képen a fordított kód látható. A b értéke épen a WREG -ben marad az előző utasítás után, így nem kell előszedni. Az értékét a 1. lapon a 0x5e címen levő változóba (0x15E) teszi. Az 1. lapon a 0x5f címen levő adatot nullázza. Ezzel előállítja b értékét 16 bitre. Ezután a 10 -et (0x0A) tesz a 0x160 címre (a felső byte-ját kinullázza a 0x161 címen) és meghívja a szorzás eljárást (16 bit * 16 bit). A harmadik képen az eredmény látható. Megfelel az elvárásoknak w új értéke 1750 - 0x6D6. (Az FSR1 = w; utasítás azért kell, hogy az optimalizáló ki ne dobja az amúgy felesleges utasításokat hiszen a w értékét nem használjuk fel.) A hozzászólás módosítva: Ápr 19, 2018
PICkit 4 első teszt. Egy hiper-szuper két LED-es villogó.
![]() Mivel szegény PK3-am túlfeszültség áldozata lett, így beruháztam ebbe, ha már elérhető nálunk is. A régi javítását elkezdtem, de jutányos áron lecsapott rá egy kedves fórumtárs. Remélem sikerül neki rendbe hozni.
Általában csak a vonal végi dual supply bus-(oka)t kell cserélni. (SN74lvc145) Meg esetleg a védődiódát
A hozzászólás módosítva: Ápr 19, 2018
Minden IC, ami az 5V-os vonalon van és egy dióda meghalt. Mindegyik levétele után szűnt csak meg a zárlat. Amúgy is birizgálta már a fantáziámat a PK4, csak nem így akartam a váltást elkövetni.
Idézet: „Nem erről van szó.” Pontosan azt írtam le amibe belefutottam. Amit írtam az egy hibakeresésnek a végeredménye. Köszönöm a részletes magyarázatodat, mert ez alapján látszik, hogy nem úgy kéne működjön a fordító, mint amit leírtam.
Így teljesen világos, köszönöm mindkettőtöknek.
A stack tetején - a hívó program által elhelyezett - paraméter értéket (itt: &Data) a függvényben W1 veszi fel. Ez jól látható a visszafordított kódban. Majd megnézem ha több paraméter is átadásra kerül hogyan használja a függvény ezeket. Várnám a W2 - W13 közti regisztereket, de úgy tudom nincs limitálva a paraméterlista, így ez kicsit ellentmondást szül most.
Nincs ellentmondás. A paramétereknek LNK utasítással foglalnak helyet a veremben, majd elhelyezik őket ott. A szubrutin offszetes indirekt hivatkozással (MOV [Ws+Slit10],Wnd) használja fel őket, tehát csak a W14 regiszterre, ill. egy-két egyéb munkaregiszterre van szükség. (...még többszáz paraméter esetén is.) A visszatérési érték(ek) szintén a verembe kerülnek.
Nem véletlenül az alábbiba futottál bele?
Ezekkel a változókkal a következő utasításokat hajtjuk végre:
A memóriában a b kezdőcímétől az alábbi a adatok lesztek (byte -osan)
Utasításban a ((word*) p) a p -val megcímzett BYTE helyett WORD típusú adatot kezel, így a 175 (0xAF) helyett a 1455 (0x05AF) értéket fogja 10 -zel szorozni. Ekkor valóban nem 1750 lesz az eredmény, hanem 14550.
Sziasztok!
Tanulgatom az assemblyt, pár éve találtam egy jó leírást. Az első megszakítások részéig megcsináltam mindent az MPLAB-ban és a Proteusban kipróbáltam és jól működik. Az RB-megszakítást is beraktam a proteusba, fut a fény de a gombokkal nem lehet váltani a ledek irányát, tehát nem csinálnak semmit. Itt a megszakítás állítaná be az irányt és a főprogram léptet a fényt, de nem csinálja. A programot innen szedtem le: Bővebben: Link
Ránéznétek, hogy mi lehet a gond. Előre is köszönöm a segítséget!
Nem. Visszanéztem mielőtt beírtam.
Nem találtam olyan szintaktikát amivel jól megcsinálta volna a fordító, végül szétszedtem két sorra. Nem az első esete a C18-nak, hogy a különböző méretű változók között a kisebbik méretén végzi a műveletet és ez hibát okoz. WORD és DWORD között is belefutottam. |
Bejelentkezés
Hirdetés |