Fórum témák
» Több friss téma |
No ez így már tényleg messzire vezet... Hol is legyen az a konstans? A RAM -ban? Vagy a ROM -ban? Mekkora legyen a pointer hossza? Két byte? Három byte?
A VertAxis egy uint pointer, amibe betolt egy uint poitert, aminek az erteke 0x30ad. Mi ezzel a baj? Azon kivul, hogy int pointer nem lehet paratlan az adott architekturan. Szoval az a konstans a valtozoba fog kerulni. Jelen peldaban a valtozo valoszinulg egy regiszterben van, esetleg a stack-en.
Na csak most tudtam egy kicsit leülni mellé...
Az van amit írtál, nem kellett a Nop () -ot lecserélni, mert utána úgy is egy függvényhívás volt VertAxis paraméterrel. Abban a függvényben aztán már jól jelenik meg, tehát a 0x30AD -t adja neki át... Tehát működik, csak a watch ablakban, és a szerkesztőben (mikor rá viszem a kurzort) akkor jelenik meg rosszul.. megőrülök.. Köszönöm mindenkinek a segítséget! Persze ez azt is jelenti hogy kezdődik a szívás elölről, mert nem csak unalmamban kezdtem el ezzel játszani. Folyt. köv.
Valaki találkozott már ilyennel:
Hi-Tec 98.80 - Nem fordul le : Internal error - no stack allocated to function Lebegőpontos aritmetikán akad ki ! Ugyanazokat a függvényeket és kódkörnyezetet egy másik projektben megeszi..ott nincs gondja...onnan emeltem át. Természetesen a 9.65 is simán fordítja !
Sziasztok!
Menüt szeretnék írni LCD-re és nem igazán tudom, hogyan kell korrektül megcsinálni. Próbálkoztam már különböző eljárásokkal és igazából működik is, csak nem tudom, hogy ez így korrekt-e. Például:
Csak ez aggaszt engem: while(OK). Nem nagyon akarok ilyen végtelen ciklusokat használni, de nem tudok alternatívákat. Tudnátok valami javaslatot adni, hogyan kell felépíteni egy menüt?
Szia.
Én is hasonló cipőben jártam. Elkezdtem használni egy nagymértékben saját SWITCH/CASE menürendszert amit képes voltam minden feladatra ráerőszakolni (nem kellett volna...) Aztán egyszer nagy akadályba ütköztem és kezdtem el túrni a netet. ezt találtam először aztán továbbmentem és ide jutottam Végül felfogtam a működését és irkáltam saját funkciókat bele. Sajnos csak az első verziómat publikálhatom, mert a többiben rengeteg munkám van és most amúgy sem az a lényeg, hanem a menü azt pedig teljes egészében megtalálod benne. Remélem tudott segíteni.
Sziasztok! Egy gyári erősítő igencsak érdekes hangerőszabályzójában levő cél IC-t szeretném kiváltani PIC-kel, mert egyik hazai importőr kínálatában sincsen hasonló tudású IC, a típusa pedig ismeretlen hála a kínaiaknak, akik gondosan lecsiszolták a feliratot az IC-ről. 14 lábú IC-ről van szó, ven egy hangerő+ és egy hangerő- bemenete és 10 kimenete. Az IC működését egy Johnson számlálóhoz tudnám leginkább hasonlítani, annyi különbséggel, hogyha elszámolt 10-ig, nem kezdi 0-ról, és lefelé is számol. Meg is írtam egy programkezdeményt PIC-re, egy változó értékét növelem csökkentem, ez nem volt nagy feladat, viszont arra nem tudok rájönni, hogy azt hogyan írjam meg, hogyha pl a változó értéke 0, akkor a PORTB0 legyen aktív, ha 1 az értéke, akkor a PORTB1 és így tovább. Csináltam már hangerőszabályzást PIC-el, de én R-2R megoldást és reléket használtam, itt pedig 0-9-ig vannak a hengerőlépcsők és valószínűleg analóg kapcsolókkal(szintén semmi felirat az IC-ken) kapcsolgatják a végfokok bemenetét egy soklépcsős feszosztó megfelelő kimenetére.
Idézet: „azt hogyan írjam meg, hogyha pl a változó értéke 0, akkor a PORTB0 legyen aktív, ha 1 az értéke, akkor a PORTB1 és így tovább.” Pontosan így, ahogy írod, annyi feltételes utasítással, ahány különféle értéke lehet a változónak. Lehetne szépíteni, gyorsítani, stb. a kódot táblázattal, de jó lesz az a feltételes utasításokkal is ebben az esetben.
Erre gondoltam én is első körben, de ez annyiran "dedós" megoldásnak tűnt, hogy azt hittem van ennél egyszerűbb és "profibb" megoldás, azért kérdeztem. Köszi, hogy segítettél
Arra, hogy minden lepesnel eggyel tobb bit legyen egyben, arra van sokkal egyszerubb megoldas is:
Nekem nem mindig eggyel több bit kell, hanem egyszerre csak egy bit, a Te megoldásodnál a próbapanelemen a LED-ek egymás után gyulladtak ki szép sorban, és a végén az összes világított, de nekem egyszerre csak egy kimenet kell, hogy magas szinten legyen, tehát 1-es hangerőszint:csak PORTB0 aktív, 2-es hangerőszint: csak PORTB1 aktív stb..., de azért köszi, ebből is tanultam valamit.
Ja, mert eloszor Johnson szamlalot emlegettel, azert irtam ezt a kodot. Akkor, ami neked kell az egy sima shift regiszter. Amugy a Johnson szamlalo is az, csak annak a bemenetere a sajat kimenete van invertalva vezetve.
De az is jo, hogy van egy valtozod, ami 0 es 9 kozott valtozik, ahogy nyomkodod a gombokat, es ebbol a kivant bitmintat eloallithatod igy: LATB = 1 << valtozo; Asszem, ez a legegyszerubb. Nem kell bele if meg switch-case. Persze, ha a PORTB tobbi labat nem akarod, hogy megvaltozzon, akkor kicsit tobb: LATB = (LATB & ~0x3ff) | (1 << valtozo); A hozzászólás módosítva: Júl 30, 2014
Készítesz egy táblázatot, hogy milyen számláló értéknél melyik láb legyen bekapcsolva, és azt a táblázatot a számlálóval megcímezve kiírod a portra. Pl.
Persze mivel nyolcnál több fokozat van, ezért két táblázat kell, és esetleg maszkolni is kell a lábakat a portokon, hogy más funkciót ne zavarjon. De alapvetően ez jut eszembe legelegánsabb módszernek forráskód szinten. A switch-case viszont lehet, hogy futásidőben közelebb van az optimálishoz, mert az ilyen egymás után következő case értékek esetén a fordító készíthet számított ugrótáblát. Killbill megoldása akkor a legegyszerűbb, ha a tíz kimenet egymás után van és ugyanazon a porton - legalább 16 bites kontroller kell hozzá. A hozzászólás módosítva: Júl 30, 2014
Idézet: „Killbill megoldása akkor a legegyszerűbb, ha a tíz kimenet egymás után van és ugyanazon a porton - legalább 16 bites kontroller kell hozzá” Bocsanat, en eleve azt hittem, hogy 16 bites a port. Ez esetben viszont tenyleg jobb a tablazat. Raadasul egy 8 bites processzoron a shifteles sem egy orajel, ha jol gondolom.
Azért ehhez a feladathoz nem kell 16 bites gép.... Csak olyan pontroller, amin van legalább egy 8 bites és egy 2 bites (bit 1..0) port. A program eleje változatlan, ha a valtozo2 int típusú.
Ha a LAT regiszterek nem érhetők el, használható a PORT regiszterek is. Egy union segítségével, amivel egy int változó két byte -ja külön is kezelhető, tovább egyszerűsödne a program.
Persze, hogy nem kell 16 bites gep, csak en abbol indultam ki, hogy a port 16 bites.
A 2. sorban a ket exorolas felesleges, mert mind a nyolc bitet felulirja, eleg a LATB = valtozo2; Az & 0xff sem kell, mert 8 bites a kifejezes bal oldala, ezert automatikusan levagja az intet 8 bitesre az = operator. Csak azert ertettem egyet a tablazatos megoldassal, mert ha nem egymas mellett vannak a bitek a porton, akkor mindenkeppen jobb, raadasul az emlitett shifteles hosszabb ideig tart, mint egy tablazat indexeles. Na, nem mintha nem lenne tok mindegy ebben a feladatban, de altalanossagban igaz az, hogy amit megirhatsz gyorsra, azt ird is ugy, ha ettol nem lesz zavaroan hosszu a kod.
Csak a tisztánlátás végett: a kontroller egy 16F818-as, csak a belső órát tudom használni az adott alkalmazásban, mert minden láb foglalt(kellenek plussz szolgáltatások is, amik gyárilag nagyon-nagyon hiányoznak, pl koppanásgátló). Tehát a PIC lábkiosztása úgy néz ki, hogy a PORTB mind a 8 bitje kimenet, PORTA 0. és 1. bitje a két nyomógomb, 2. bitjén figyeli, hogy be van-e kapcsolva a hálózati fesz, 3., 4. bitje a hiányzó két bit a 10 kimenethez, az 5. ugye kiesik, mert az csak bemenet lehet, a 6., 7. bit pedig a két relé kimenete a koppanásgátlóhoz. Ami a porgramot illeti: mint említettem nagyon mazsola vagyok még C nyelven való programozásban, táblázatkezelés nekem még magas, eddig 99%-ban csak időzítgetéseket, és A/D-vel feszmérést és LCD-re kiírást csináltam csak, most kóstolgatom a szoftveres PWM-et egy hexapod építése kapcsán. A kérdésem jobban illet volna a PIC-es kezdő kérdések topicba, de mivel C nyelv gondoltam inkább ide való. Nyitott vagyok bármilyen megoldásra, és nagyon szívesen tanulok, de lehetőleg nagyon szájbarágósan kellene elmagyarázni pl egy táblázatkezelést, vagy ilyesmit, próbálkoztam if-else és switch-case megoldásokkal, de egyik sem akart működni.
Megoldódott a probléma. Igazából nem értem, hogy mi jelentősége annak, hogy először a változó értékét vizsgálom if-ekkel és utánna azt, hogy van-e megnyomott gomb, és nem fordítva, de így most működik.
Az első próbálkozásomban elöl volt a bemeneteket vizsgáló két if-es elágazás, és utánna a többi, úgy nem akart működni... A hozzászólás módosítva: Júl 30, 2014
A probléma az volt, hogy az if-nek van egy else ága is, amit ha nem használsz, meg kell jelölnöd else {} -vel. Jártam én is így, és néztem, mikor a feltétel igazzá vált, és a pont utána levő soros porti kiírás nem jött át. De csak, ha igaz volt a feltétel! Egyébként logikus, ha nem igaz, akkor a következő sor lép életbe, mintha az if-hez tartozna. Remélem érthetően leírtam.
Hat nem igazan ertheto. Az else agat egyaltalan nem kotelezo kiirni.
Igazabol, hogy miert nem mukodik a fenti program, azt ennyibol senki nem tudja megmodani.
Ha megmutatod az egesz programot, akkor tudunk segiteni. Talan az lehetett egy problema, hogy a goto-k atugrottak az egesz if(volume == 0) es tarsai reszt. C nyelvben goto-t csak igen ritkan szokas hasznalni, kezdokent keruld oket, ha lehet.
A hozzászólás módosítva: Júl 31, 2014
Ez már a működő. A goto-k által meghívott részek a program elejére térnek vissza, és az if-ek miatt ezek csak akkor játszanak szerepet, ha meg van nyomva egy gomb, de amíg nem a progi végén voltak, addig nem volt hajlandó a proci semmit csinálni, de amint a végére tettem a gombfigyelést, tökéletesen működik... Megpróbálom ezentúl kerülni őket, csak még nagyon assembleresen jár az agyam
A hozzászólás módosítva: Júl 31, 2014
Ha feltétel teljesülése estén kell lefutnia egy-egy programrésznek, akkor a goto helyett használj ilyen esetekre inkább saját függvényeket.
Az if feltételes kifejezés után nem kötelező az else ág.
Az egyértelmű (a programozó számára egyértelmű és követhető) kód érdekében érdemes a blokk jelölő zárójeleket ( {} ) használni az if és az else ágak után, mégha az adott blokk üres is. Így egyértelműen látszik, hogy mi fog lefutni és mi nem. Ha nincs blokk, akkor az if kifejezés kiértékelése után ha az true, akkor a következő programsorra adódik át a vezérlés. Ha az if kifejezés kiértékelésének eredménye false, akkor blokk nélküli programkód esetén a következő sor NEM hajtódik végre (mert az csak akkor fut le, ha a feltétel igaz), a vezérlés átadódik az azt követő sorra. Ugyanez érvényes az else ágra is. (Ha van else águnk) Ha nincs blokk jelölve, akkor az if és az else kifejezések között csak egy programsor lehet. (ez a sor fog lefutni akkor, ha az if kiértékelésének az eredménye true) Több sor azért nem lehet a két feltétel között, mert akkor az else ág if előfeltétel nélkül lesz a kódban, ami fordítási és futási hibát eredményez. A hozzászólás módosítva: Júl 31, 2014
Sziasztok!
C30 fordítót használok. C-ben hogyan szokás megoldani az előre nem ismert méretű stringek tárhelyét? Konkrétan arról van szó, hogy egy SD kártyán szeretném kiiratni a file-neveket, de a hosszú file neveknél nem tudni előre hogy milyen hosszú. Meg azt se tudom előre hány file lesz. Lehet valahogyan dinamikusan helyet tárhelyet foglalni(állítsak be heap-et?), vagy előre foglaljak le egy maximális tömböt? Még van egy olyan problémám is, hogy memcpy-nél kifagy a PIC, mikor egy ilyen utasítás következik ASM-ben:
Létezik dinamikus memóriafoglalás nagyobb kontrollereken, de szerintem egy lefoglalt nagyobb méretű fix tömb is megteszi az esetek nagyobb részében.
Nem ismerem a 16 bitesek asm utasításkészletét, így csak sejtem, hogy ez az utasítás mit csinál, de nem az a gondja, hogy nulla a memóriacím, ahová írnia kellene és null memóriacímet nem szoktak megengedni, mert vélhetően valami hiba miatt történik, és egy valamilyen hard fault handlerbe ugrik? (épp ugyanezzel találkoztam a minap ARM-on) |
Bejelentkezés
Hirdetés |