Fórum témák
» Több friss téma |
Van megint pár kérdésem:
1.- Ennek mi a C-nyelvű megfelelője?
2.- Hogyan tudok bájtnál kisebb dolgot definiálni? Mondjuk egyetlen bitet! Ezt olvastam valahol a Kónya-könyvben de már tíz perce lapozgatom és egyszerűen nem találom hol volt, pedig írta...
Több opció van.
Ezek mind azért működnek csak, mert a megfelelő (processzoronként külön-külön) include fájlban definiálva vannak a megfelelő memóriaváltozók ill. makrók:
Hogy éppen hogy nevezik az adott regiszter/bitet, van-e bitenkénti definíció, vagy csak a regisztert definiálták, azt innen érdemes kinézni mindig. Byte-nál kisebb dolgot nem akarsz definiálni! Azért nem, mert azt valahová raknia kell a fordítónak, és ahova rakni tudja, azok mind byte méretű memóriaterületek. Jobban jársz, ha magad pakolod össze byte-okba a bit méretű változóidat. Pl.:
Ezután a var.bit7 a legfelső bitet jelenti, a var.nibble pedig a legalsó 4-bites területet. Ha így csinálod:
Ez annyiból jobb, hogy lehet hivatkozni a var egyes bitjeire: var.bit7, vagy var.nibble, de egyben is el tudod érni: var.byte. A hozzászólás módosítva: Szept 18, 2013
Köszönöm a válaszokat, emésztem őket. Közben egy dolog; bepötyögtem szó szerint ugyan azt ami a könyvben van:
De a fordító sytax error-t ír a "for"-al kezdődő sorra. Miért?
Az előtte levő sor végéről lemaradt a pontosvessző.
Ja igen. Hozzá kell szoknom hogy a pontosvesszőt itt nem akkor kell írni amikor kommentelni akarok...
Viszont most meg az utolsó kapcsos zárójel zavarja. Így néz ki eddig amit kalimpáltam:
És az include-olt:
Mit rontottam el ebben? Szeretném majd a függvényeket a második fájlban gyűjtögetni de gondolom valamit elrontottam.
A main függvénynél meg kéne adni a visszatérési értéket (void, ha nincs visszatérési érték):
Persze a PIC esetén nem kéne visszatérni a main()-ből, egy végtelen ciklust kéne oda beírni.
Nagyon-nagyon-nagyon nem javaslom, hogy a fájlnevekben - space-t, - ékezetes betűt, - random nem alfanumerikus karaktereket (kapcsos/szögletes zárójelek, csillag, kérdőjel, idézőjel, aposztróf, /) akarjál használni. Betű, szám, pont, kötőjel, ha nagyon muszáj, akkor aláhúzás. A könyvtárnevekben (pl. projektkönyvtár neve) is kerülném a space-t és az ékezetes betűket, az IDE által a háttérben indított programoknak lehet velük gondja. Mivel minden projektnek illik saját könyvtárának lennie, azon belül a fájlok neveibe értelmetlen dolog a projekt nevét még egyszer belekódolni. A hozzászólás módosítva: Szept 18, 2013
Include fájlok működése:
A C nyelvben a .h fájlok arra vannak kitalálva, hogy az adott .c fájlokon kívül létező, máshol definiált változókat, függvények létezését a fordító tudomására hozzuk. Nem csak erre használhatók, de erre szokás használni. Ez a .c fájl fordításakor lényegében egy külső hivatkozást fog eredményezni a lefordított kódban. Ahhoz, hogy ebből a lefordított kódból egy futtatható kód keletkezzen, egy linkelés nevű fázisban ezeket a külső hivatkozásokat fel kell oldani. Mondjuk ha van két .c fájl, amiket külön-külön fordítunk le (a fordító egyszerre mindig egy .c fájllal foglalkozik), és az egyik fájlból szeretnénk a másikban levő függvényt meghívni, akkor a hívó .c fájl fordításakor meg kell mondani a fordítónak, hogy hogy néz ki az a függvény (mik a paraméterei, visszatérési értéke), amit meg akarunk hívni. A hivatkozás a függvény neve alapján történik (ebből következik, hogy ugyanazzal a névvel nem lehet két függvénypéldány). Ez a "megmondás" pont úgy néz ki, mint a függvény, de csak a függvény fejlécét kell megadni, a "testét" nem. Változóknál az extern kulcsóval lehet ugyanezt megtenni. Azaz: a.c:
b.c:
Az "int fuggveny(int param1, char param2);" sor mondja meg a b.c fordításakor, hogy valahol van egy fuggveny nevű függvény, ezekkel a paraméterekkel. A fordítás során a fordító nem tudja, hogy valójában hol van ez a függvény (vagy a valtozo nevű változó), csak a típusokat tudja. A lefordított kód is csak egy külső hivatkozást tartalmaz. A fordítás végén, amikor az a.c is meg a b.c is le van fordítva, a linker a két lefordított kódot összelinkeli, és ekkor mindegyik külső hivatkozást fel kell oldania. Ha ugyanaz a függvény/változó több forrásfájlban is megtalálható, akkor abból hiba lesz. Ha sehol nincs meg a hivatkozott név, akkor megintcsak sikertelen lesz a linkelés. Ha a típusokat elrontottuk, azt nem biztos, hogy kiszúrja a linker, viszont futás közben gondok lesznek. Azért, hogy ne tévesszük el a történetet, szokás ezeket a külső hivatkozásokat külön .h fájlba rakni: a.h:
a.c:
b.c:
Ez azért jó, mert így ugyanazt a fájlt be tudjuk include-olni abba a .c fájlba is, amiben ott van a függvény implementációja. Ekkor ha nem stimmelnek mondjuk a paramétertípusok, arra már ordítani fog a fordító, így könnyebben észrevesszük. A .h fájlba nem szokás implementációt rakni (azaz a függvénynek csak a fejléce kerül bele szokásos módon, a konkrét függvénykódot egy .c fájlba rakjuk). Ha ugyanis implementáció is belekerül, akkor azt a .h fájlt nem tudjuk egynél több .c fájlba include-olni (hiszen akkor a több .c fájlban az adott függvényből külön-külön példányok keletkeznének, amik a linkelésnél összeütköznének). Ha valaki a függvény implementációját akarja valamilyen okból include-olni, akkor azt az include fájlt .c kiterjesztéssel szokás ellátni (ez utal rá, hogy azt csak egyszer, egy fájlba szabad include-olni).
Na most már kezdenek összekuszálódni a dolgok. az a.c-nél és az a.h-nál miért írtál a fuggveny elé int-et? Illetve az a.h-nál mi az az extern?
Azt int a függvény neve előtt azt mutatja meg, hogy milyen típusú a függvény visszatérési értéke. asm-ben ilyen nincs, C-ben van, tehát ez újdonság számodra. Vagyis végülis van, kb. olyan, mint amikor a W-ben adták vissza értéket a hívott szubrutinból, csak itt több bájtos is lehet a visszatérési érték, float is lehet, stb. Ez azért jó, mert pl. van valami függvényed, ami csinál valamit, pl. beolvas egy hőmérsékletet, akkor nem kell azt a beolvasó függvénynek egy globális változóba raknia, majd a hívó függvénynek onnan kiszednie, hanem egyszerűen a visszatérési értékben azt visszaadja, és azt közvetlenül fel tudod használni a kódban máshol.
Pl.
Itt a ho_olvasas() függvény vár egy bemenő paramétert, mondjuk azt, hogy melyik szenzor hőmérsékletét akarjuk lemérni, ez lesz az egyes. És a függvény visszaad egy - például unsigned char- értéket, amit közvetlenül bemenő paraméterként használunk az lcd_kiir() függvény hívásánál, ami tiszta véletlenül épp unsigned char típust vár. Persze belül ebből lesz valamilyen változó használat, vagy legalábbis W regiszter, de C szinten nem kell plusz változót beállítani. Sőt, a fordító akár azt is megoldja, ha nem azonosak a típusok, pl. a ho_olvasas unsigned char értéket ad vissza, viszont az lcd_kiir meg unsigned int típust vár, akkor feltölti a felső bájtot nullákkal. Ugyanez fordítva is megy, akkor viszont levágja a felső bájtot, tehát lehet vele szívni ugyanúgy, mint az 1byte*1byte szorzásnál, amikor az eredményt is 1byte-ra rakja. float-int típusok esetén pedig konvertál, ott mondjuk kisebb pontatlanság lép fel. Függvény lehet olyan is, hogy nincs visszatérési értéke, ekkor írjuk azt a neve elég, hogy void. Meg ha bemenő paramétere sincs, akkor ott is némelyik fordító kéri, hogy szerepeljen a void kulcsszó a zárójelben, de ezt sok fordító elnézi, és elég a () Az extern pedig azt jelenti, hogy azt a változót nem ott hozzuk létre, hanem tudatjuk a fordítóval, hogy az a változó majd létezni fog valahol, és majd a linker össze tudja rakni, hogy hol. Nagyjából ugyanarra való, mint az, hogy tudatjuk fele, hogy az a függvény létezik valahol, és majd szintén a linker összerakja, hogy hol. A fordítás folyamán amikor az szerepel, hogy "include a.h", akkor azt úgy képzeld el, hogy ahol ez a sor szerepel, oda bemásolod az a.h fájl tartalmát, és amit úgy kapsz, azt fordítja a fordító. És lassan majd elérkezünk a pointerekhez, az még egy szép dolog a C nyelvben ----------------------- Egyébként ha valami nem megy, akkor javaslom idemásolni a fordító hibaüzenetét is, nem csak annyit, hogy nem tetszik neki valami. A hozzászólás módosítva: Szept 18, 2013
Megpróbáltam átírni ezek alapján átírni de így sem jó. A fő program:
A másik c fájl, amiben a függvényeket gyűjtögetném majd:
És a fejléc fájl:
A fejléc fájl void-dal kezdődő sorát jelöli hogy syntax error. A hozzászólás módosítva: Szept 19, 2013
Másold már be a pontos hibaüzeneteket, mert ezen én nem látom, hogy mit kifogásolhat.
syntax error-on kívül semmi mást nem ír? Szoktak a fordítók ott még mást is írni
Idézet: „---------------------------------------------------------------------- Debug build of project `D:\Elektronika\Projektek\Projektek-2013\PIC-es panelmero III - C\PIC-es panelmero III - C.mcp' started. Language tool versions: mpasmwin.exe v5.44, mplink.exe v4.42, mcc18.exe v3.41, mplib.exe v4.42 Preprocessor symbol `__DEBUG' is defined. Thu Sep 19 17:57:07 2013 ---------------------------------------------------------------------- Clean: Deleting intermediary and output files. Clean: Done. Executing: "C:\Program Files (x86)\Microchip\mplabc18\v3.41\bin\mcc18.exe" -p=18F25K80 "PIC-es panelmero III - C.c" -fo="PIC-es panelmero III - C.o" -D__DEBUG -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa- D:\Elektronika\Projektek\Projektek-2013\PIC-es panelmero III - C\fejlecek.h:4:Error: syntax error Halting build on first failure as requested. ---------------------------------------------------------------------- Debug build of project `D:\Elektronika\Projektek\Projektek-2013\PIC-es panelmero III - C\PIC-es panelmero III - C.mcp' failed. Language tool versions: mpasmwin.exe v5.44, mplink.exe v4.42, mcc18.exe v3.41, mplib.exe v4.42 Preprocessor symbol `__DEBUG' is defined. Thu Sep 19 17:57:07 2013 ---------------------------------------------------------------------- BUILD FAILED” A hozzászólás módosítva: Szept 19, 2013
Namost ez azt mondja, hogy nem találja a szubrutinok.c nevű fájlt, nem pedig syntax errort ír...
Mellesleg ha lokális (függvényen belüli) változó az uIdo, akkor a header fájlban semmi keresnivalója az extern unsigned uIdo sornak, mert nincs mire hivatkoznia. Nem kell a header fájlban az összes változót felsorolni extern-ként, hanem csak azokat kell, amiket el kell, hogy lehessen érni máshonnan is. A hozzászólás módosítva: Szept 19, 2013
Úgytűnik van, én is úgy emlékeztem, hogy bőbeszédűbb szokott lenni a fordító...
De a 4. sorra panaszkodik, miközben csak 2 sort másoltál be lent... Nem lehet, hogy valami "szemét" karakter maradt a fájl végén? Valami normális editorból meg kéne nézni a fájlt (pl. Far manager-ben van hexa nézegető: F3 view file -> F4 hex mode, abban látszódni fog, ha valami nem kóser).
Van egy új sor a void-os sor után? Azt mintha kiírnák nomálisan, hogy hiányzik az újsor, de hátha. Ha nem megy, akkor töröld ki az extern-es sort, hagyd csak ott a void-osat, meg próbáld ki, hogy átnevezed ezt a fájlt valami másra, csinálsz a helyére egy újat, és oda újra beleírod. Lehet, hogy valami nem látható karakter van ott még. Esetleg hexben megnézheted, pl. Total commander, F3, majd ott valamelyik menűpont alatt van olyan, hogy hex nézet.
A hozzászólás módosítva: Szept 19, 2013
Jó, hogy eszembe juttattad, megyek is gyorsan egyet impossibile missionözni...
Sziasztok!
A körünkben van a PIC-es panelmérő program írója is?! Vagy valahonnan letölthető a forrás? (Egy hasonló kis buta egyszerű műszerrel próbálkozom én is). Megmondom őszintén, kedvet kaptam egy teljesítmény mérő elkészítésére. Hobbi szinten foglalkoztat a téma, nem tanultam C nyelvben programozni. Beszereztem az MPLAB C18 fordítót, van már HI-Tech fordítóm is, és immáron a mikroC is. Próbálgattam mindegyiket, de a legkönnyebben átlátható számomra a mikroC. Ezért elkészítettem életem első végre valamit csináló programját... A miértek, hogyanok topicba is írtam, potyo erre a fórumra terelt át, és olvasgattam már sok mindent is, de nem áll össze a kép. Hogy kell az időzítőket használni, megszakításokat konkrétan kezelni az én problémámra... Azt már tudom, hogy a delay függvényt kerülni kell, időzítőt kell indítani. De hogy tudom megvillogtatni a LED-et, ha a feltétel teljesül úgy, hogy ne kelljen kivárni azt az időt amíg a LED ki/be kapcsolgat?!
Az első két sor üres, ott csak nyomtam két entert. Ide meg nem másoltam be mert gondoltam minek.
Szia!
Én készítettem a PIC-es panelmérőket és én írtam a szoftverüket is. De nem C-ban hanem assembly-ben. Amiket most másolgatok be ide kódrészletek, abban csak azért van benne a "PIC-es panelmero III" név mert ennek az áramkörnek az egyik prototípus-paneljére írom (írnám) ezt a C programot és majd ha mindent tudok C-ül akkor végül ténylegesen a panelmérő III lesz majd. Bár megjegyzem a panelmérő III szoftvere kb 95%-ban készen van assembly-ben, ezt csak azért csinálom hogy megtanuljam a C nyelvet.
A void-os sor után nincs semmi. Az extern sor kitörlésével nem változott semmi a hibaüzenet tekintetében.
Gratulálok hozzá! Szép munka!
Én is csak a C nyelv tanulása miatt gyúrom a dolgot. De már itt az elején ilyen problémákba ütközök... Kicsit magas nekem ez a nyelv. Idézet: Azért írta potyo, mert kell egy üres sor ( az első próbálkozásaimnál én is így jártam !)! „Van egy új sor a void-os sor után?”
Köszi. Ahogy látom egyenáramú teljesítménymérő lesz. Az nem lesz annyira nehéz, csak szorozni kell hozzá!
Én AC teljesítmény-mérőn dolgozom most, na az már nem piskóta! Figyelni kell a nullátmeneteket, teljes periódusokat mintavételezni, aztán pillanatértékek szorzatát és valódi effektív-értéket számolni, ezekből hatásos és látszólagos teljesítményt kiszámítani, pitagorasz tétellel meddő teljesítményt számolni, kis trigonometriával cosFI-t... Ráadásul mindezt assembly-ben. Nem véletlen próbálkozom a C-vel.
Ohh, köszönöm! Érteni nem értem de nem is érdekel, a lényeg hogy most jó.
A hozzászólás módosítva: Szept 19, 2013
Én sem tudom, hogy miért kell, de így megy ! Annak idején én is néztem egy darabig, hogy mi maradt bent !
Váltakozóáramú meg sem fordult a fejemben Ez jó lesz a kis kapcsiüzemű tápomhoz a végfokba... Már így is jó, csak tovább akarok fejlődni, hogy működik az interrupt...
Amúgy assembly-ben le a kalappal ha a 95%-át megcsináltad. Az nagyon nagy meló! Ezzel is amit én csinálok már egy jó ideje szívatom magam. A hozzászólás módosítva: Szept 19, 2013
Idézet: „Ampere = (5000 * ADC_Value2 / 1023) * 4; //AD értékének Árammá alakítása” Idézet: „Voltage = (5000 * ADC_Value1 / 1023) * 10; //AD értékének Feszültséggé alakítása” Az átalakított mennyiségel alsó bitjei mindig 0 -k lesznek...
Így azokban a bitekben is értékes információ lesz. Azt a rengeteg osztást, ami a decimálisre való alakításban van, lehetne csökkenteni. A hozzászólás módosítva: Szept 19, 2013
|
Bejelentkezés
Hirdetés |