Fórum témák
» Több friss téma |
Idézet: Szerintem fölösleges összerendelni azokat a jeleket, amelyek amúgy is függetlenek egymástól. „Nem kell egyebet csinálnia, mint 8 bemeneten figyelni a gombokat és ki-be kapcsonli a hozzájuk rendelt kimenetet.”
Hát egy tömbbel ciklusban 1 if elég lett volna, de mint _vl_ is kifejtette ez nem a kényelemről szól.
Megírom az if-eket. Köszönöm a véleményeket.
A C-ben arra kell vigyázni, hogy amit rövidnek és egyszerűnek látsz a forrásban, lehet, hogy a lefordított program méretében sebességében egy agyrém lesz.
Ciklus, tömb, egy if. Lehet, hogy a PORTx es LATx nem volatile unsigned char, de sok mas nem lehet. A kod nem feltetlenul lesz rovid, viszont atlathato. Mondjuk erre a 8 pin-re tenyleg egyszerubb a 8 if. Foleg egy 8 bites PIC-en. Egy komolyabb processzoron, ahol vannak rendes pointerek, ott ebbol eleg jo kod fordul.
Ha egy porton lenne az osszes bemenet es egy masikon az osszes kimenet, akkor egyetlen 256 byte-os tablazattal meg lehetne oldani a dolgot. Idézet: „A C nyelv nem a kényelemről szól.” Mihez kepest? Assembly-hez, Pascal-hoz, Basic-hez? Lenyegesen kenyelmesebb, es mindent meg lehet oldani benne, amit assembly-ben. Persze, egy php, JavaScript vagy egyeb magaszintu nyelv, ahol egy valtozonak a tipusa implicit modon dol el minden ertekadasnal, es mondjuk asszociativ tombok vannak, az sokszor kenyelmesebb, de semmikeppen nem hasznalhato hardverkozeli programozasra. Foleg nem 8 bites mikrokontrollereken. Nem veletlenul talaltak ki a C-t annakidejen. Rendszerprogramozasi nyelvnek indult, es ez a tulajdonsaga meg is maradt. Ezen felul nagyon jo nyelv hardverkozeli programozashoz. A tobbivel egyetertek, jol kell a hw-t megtervezni, es erteni kell a programozashoz annyira, hogy legalabb sejtsd, hogy a kododbol mi fog fordulni. Bar, sokszor nagyon meglepo dolgokat tud produkalni pl. a gcc. AVR-re is, meg ARM-re is. De dsPIC-re is lattam gcc altal forditott kodot.
Érdekes megoldás, tetszik! Azzal is egyetértek, hogy a 8 if jobban vennné ki magát!
Hát ez egy elég gagyi pic. Még LAT regisztere sincs, de a célnak megfelel.
Idézet: „Idézet: „A C nyelv nem a kényelemről szól.” Mihez kepest? Assembly-hez, Pascal-hoz, Basic-hez?” Én is erre gondoltam, azért nem szenvedek az assemblyvel.
Újabb kérdés.
Megírtam a kódot if-ekkel, még kicsit finomításra szorul a debounce meg a delay,de müködik rendesen.
A kérdés az, hogy meg tudom-e oldani valahogy, hogy az if-ek helyett a kikommentezett függvényt használjam, vagy valami hasonlót. Fele akkora helyet foglalna az EEPROM-ban, igaz több RAM-ot, de az bővíthető külső ramokkal. Ennél a kapcsolónál lényegtelen, de a későbbiekben szükségem lehet rá, hogy rövidebb legyen a kód. Próbálgattam a volatile-t beiktatni, de nem jöttem rá hogy kellene, hogy működjön is. A hozzászólás módosítva: Aug 28, 2013
Nem, nem tudod. A dolog lényege az, hogy a lentebb killbill által belinkelt, pointeres-maszkos megoldás kivételével nincs igazából olyan megoldás, ami végül nem 8 if-re fordul le, ha a bitjeid össze-vissza vannak, tehát enni fogja a flash-t.
Továbbá megjegyzem, hogy az, hogy az if-en belül bármeddig várakozol (delay), pláne úgy, hogy akár végtelen ideig is képes vagy várakozni (while (in == 1) delay), az szerintem nem lesz korrekt működés (mivel párhuzamosan kellene a 8 bemenetet figyelni, és a delay-eknek párhuzamosan kéne működniük, mert így feltartják egymást is, és az tuti nem az, mint amit szeretnél). A hozzászólás módosítva: Aug 28, 2013
Idézet: „„A C nyelv nem a kényelemről szól.” Mihez kepest?” A magasszintű nyelvekhez képest. A mondat értelme az lenne, hogy a C nyelv annyira hardverközeli nyelv, hogy a benne megfogalmazott kód elég közvetlenül meghatározza, hogy az assembly kód milyen algoritmust végezzen, hogy milyen assembly kód készüljön belőle - és nem mellesleg pont ezért jó hardverközeli dolgokra. Ebből az is következik, hogy minden olyan nyelvi megoldás, ami az adott platformon assembly-be nehezen, bonyolultan fordítható át, nagyfokú kreativitást enged a fordítónak, így elvesztve a kontrollt a végeredmény felett. A C fordítónak alapvetően nem feladata helyettünk gondolkodni, így ha ezt mi sem tesszük, akkor valami random eredmény fog kisülni
Erdekes, amit mondasz. En utoljara 1988-ban tudtam kiszamolni elore, hogy a Manx C compiler milyen kodot fog generalni, mert az nem optimalizalt egyaltalan. A for( ; ; ) sokkal stilusosabb, mint a while(1), merthogy a nyelv definicioja szerint a for feltetelenek elhagyasa azt jelenti, hogy a feltetel mindig igaz. Ezzel szemben a while(1)-nel az optimalizacio ismeri fel, hogy konstans a feltetel. Szoval van kulonbseg a ketto kozott, de ma mar mindegy, mert ugyanazt forditjak belole a forditok. De a CP/M-es Manx fordito a while(1)-re bizony meg betoltott 1-et a HL-be, majd megnezte, hogy nullatol kulonbozik-e... Tapasztalatom szerint a mai forditok, akarmennyire is nem akarom, helyettem gondolkodnak. Es ez nem mindig jo. Persze a volatile sokmindent megold. A gcc olyan szinten irja at az altalad leirt C kodot, hogy sosem ismersz ra. Azon mar nem is csodalkozom, hogy komplett fuggvenyeket tuntet el (nemhogy par lokalis valtozot). Ciklustorzseket kirakja cikluson kivulre, mert latja, hogy mi lesz a vegeredmeny, stb.. Akarmilyen amator modon leirhatsz egy ciklust, amiben egy tombot olvasol vegig index-szel, a gcc siman atirja az egeszet pointeresre. Szoval, en mar nem hiszek abban, hogy tulzottan tudnam befolyasolni a forditot abban, hogy milyen kodot allitson elo.
De szerintem a C nyelv nagyon kenyelmes. Talan pont azert, met mindenfele adattipus van, csinalhatsz strukturat, uniont, fuggvenypointert, bitmezot (sosem hasznaltam), es gyakorlatilag mindent. A logikai operatorok (== != < > stb) is int eredmenyt adnak, igy nem csak felteteles utasitasoknal lehet oket hasznalni, mint megannyi magasszintu nyelvben.
Minden muvelet eredmenye onmagaban lehet jobbertek, atadhato fuggvenynek, vagy akar lehet feltetel egy felteteles utasitasnal. Ez utobbi persze megint nem nagy dolog a mai forditok ismereteben, de eredetileg segitette a hatekony assembly eloallitasat:
Az elso esetben a forditott kod azt csinalta, amit odairtak. Meghivta a getchar()-t, letette a kodot a 'c' valtozoba, majd felvette onnan az erteket es vizsgalta. A masodik esetben egyreszt tomorebben irhatod a C kodot, masreszt a forditonak segitettel, hogy a kapott int-et tegye le 'c'-be, majd ugyanazt a szamot vizsgalja meg. Megsporolt egy indirekt memoria olvasast, ami draga dolog. Ezt ma mar magatol is igy csinalja a fordito, akarhogy is irod le, es nagy valoszinuseggel a 'c' valtozot eltunteni, nem fog semmit a stack-en irkalni. De maga az irasmod meg mindig megvan, es szerintem nagyon kenyelmes es beszedes. Vagy ott van a C nyelvben kitalalt (ma mar mindenki atvette), ? : operator, meg a logikai && es || kezelese.
egy if, de amig a ptr nulla, addig nem dereferencialja (hogy mondjak ezt magyarul?). Vagy masik ket kedvencem:
Rettentoen jo nyelv, ha ismeri az ember (tudom, hogy te ismered) az osszes lehetoseget. Igazabol kellene egy C topic, mert az itt (es az AVR-en is) felmerulo kerdesek sokszor messze nem az adott architekturarol szolnak, hanem a C nyelv alapjairol. Amig valaki nem tudja, hogy a PORTAbits.PA3 mit is jelent pontosan, addig ez nem PIC kerdes, hanem C nyelvi kerdes. A hozzászólás módosítva: Aug 29, 2013
Idézet: „pláne úgy, hogy akár végtelen ideig is képes vagy várakozni (while (in == 1) delay), az szerintem nem lesz korrekt működés (mivel párhuzamosan kellene a 8 bemenetet figyelni, és a delay-eknek párhuzamosan kéne működniük, mert így feltartják egymást is, és az tuti nem az, mint amit szeretnél).” Működés szempontjából jó. Mint említettem 8 bemenetet figyel, ami manuális gombnyomás, és a normális emberek egyszerre 1 gombot nyomnak meg. (tudom vannak kivételek, pl: billentyűzet shift+ és egyebek, de egy vezérlő eszközön nem. És nem végtelenségig várakozik, csak ameddig nyomva tartják. Viszont amit a főciklusban online figyel, azt a függvénybe nem tudtam még bevinni, mert oda csak a meghívás pillanatában levő érték megy be, a rekurzió meg ugyebár felejtős a uC-erek esetében.Mint mondtam itt próbáltam a volatile-t, de pointerek nélkül, ami eddig sikertelen, úgyhogy mint mondtad valószínűleg csak az említett pointeres megoldással tudom megcsinálni. Idézet: „Igazabol kellene egy C topic, mert az itt (es az AVR-en is) felmerulo kerdesek sokszor messze nem az adott architekturarol szolnak, hanem a C nyelv alapjairol. Amig valaki nem tudja, hogy a PORTAbits.PA3 mit is jelent pontosan, addig ez nem PIC kerdes, hanem C nyelvi kerdes. ” Igazad lehet, bár a uC erősen korlátozó tényező. Esetemben meg ráadásul gagyi is(16f690), de a célnak megfelel.
Eppen ezert kell tenyelg tudni, hogy mi tortenik, mi micsoda. Szerintem _vl_ is errol beszelt.
Mellesleg a rekurzio nem felejtendo el mukrokontrolleren. Miert lenne az??? Csak stack kell hozza. Igaz, a regi PIC-eken nincs igazi rendes stack, de valahogy emulaljak. Viszont a te problemadhoz nem rekurzio kell, hanem az, hogy atadj a fuggvenyednek egy strukturapointert, ami strukturaban benne van a bemenetet leiro pointer es bitmaszk, a kimenetre ugyanez, es mondjuk egy utolso allapota a bemenetnek (abbol latod, hogy most nyomtak meg). A prellmentesiteshez meg csak annyi kell, hogy ezt a fuggvenyt ne esz nelkul hivogasd, hanem mondjuk 20..50ms-onkent.
A hozzászólás módosítva: Aug 29, 2013
Ok, holnap kipróbálom ha esz rá időm.
Köszi szépen az infokat meg a kódot. A hozzászólás módosítva: Aug 29, 2013
Üdv. Ebben a programban mit kéne változtatnom hogyha nincs eredmény ugorjon tovább a program? Azért lenne ez fontos mert több mindent tettem ez mellé a program mellé és ha nincs érték megáll az egész programom ami egyébként tökéletesen működik.
Honnan és hová ugorjon tovább?
Itt van a majdnem teljes progi a kijelző definiálást most nem másolom be de ha nincs érték a hőmérséklet mérés és a feszültség mérés pár másodperc után megáll vagy el sem indul az egész ha nem kap jelet a fentebb említett programrész. Úgy kellene továb ugornia hogy a main programnál ugyanúgy frissítse tovább az értékeket azaz olvassa a hőmérsékletet be az adc értékét és ha elér megint ide és azt érzékeli hogy nincs bemenő impulzus ne álljon meg hanem ugorja át és ha van érték akkor pedig ugyanúgy írja ki a kijelzőre. 137 sor alatt van az a parancs ha az érték 300 alatti írjon ki pár vonalat a kijelzőre de ezzel nem jó így.
A hozzászólás módosítva: Szept 3, 2013
Olvasgatom a páromtól kapott Kónya-féle C-programozós könyvet és ismerkedem a C nyelvvel. Eddig két dolog nem világos:
1.- A main függvény végén van egy kapcsos zárójel, annak is a bezárós fele ugyebár. Ha oda jut a PIC akkor mi történik? Az a zárójel olyan mint assembly-ben az END utasítás, azaz ott megáll a fordító? Hogyha nincs előtte valamiféle ciklus amiben végtelenül szaladgálhat vagy minimum egy goto$, akkor mi történik? A programszámláló az utolsó sor után elszabadul és megy amerre lát? 2.- Nem értem teljesen ezt az utóbb inkrementálunk-dekrementálunk dolgot. Például konkrétan ennek: a=++b+c+++d++ Mi lesz az eredménye ha mondjuk b=1, c=2 és d=3? Egyáltalán értelmezhető ez így, a c-betű után három darab pluszjellel? Az eredmény ez lesz? a=7, b=2, c=3 , d=4 3.- Ha van három számom (a, b, c) és mind a három unsigned char majd ezt írom: a=b*c De a szorzat eredménye már két bájtos lesz, azaz az a-nak az unsigned char már nem elég, akkor mi történik? Beírja csak az alsó vagy csak a felső bájtot az a-ba? És a fordító ilyen esetben szól egyébként hogy gond van? A hozzászólás módosítva: Szept 17, 2013
1, } : Egy szintaktikai egység vége. Egy függvény esetében kilépés a függvényből. Normál (számítógépes) környezetben a main() -ből való visszatérés a programból való kilépés. Mikrokontrolleres környezetben Neked kell gondoskodni, hogy a main() ből soha ne lépjen ki a vezérlés.
2, a=++b+c+++d++, ahol a=7, b=2, c=3 , d=4 : a=(++b)+(c++)+(d++) eredménye a=12, b=3, c= 4, d=5 Sokkal érdekesebb lenne a=(++b)+(c++)+(++c)+(b++)... Sajnos a C optimalizálása megváltoztathaja a műveletek sorrendjét, így a nem egyértelmű műveletsorozatok használata kerülendő. Egyébként a változó előtt álló ++ vagy -- a változó értékének felhasználása előtt növel vagy csökkent, a változó után álló ++ vagy -- a változó értékének felhasználása után növel vagy csökkent. 3, Csonkolódik a megadott számábrázolásnak megfelelő bitszámra - az alsó 8 bitet kapod meg. Van olyan fordító, ami szól érte (worning level beállítása), van amelyik nem. A hozzászólás módosítva: Szept 17, 2013
Köszönöm a válaszokat!
Idézet: „a=++b+c+++d++, ahol a=7, b=2, c=3 , d=4” Ezt akkor jól eltaláltam. Idézet: „a=(++b)+(c++)+(d++) eredménye a=12, b=3, c= 4, d=5” Ezt viszont nem értem, ez hogyan jön ki? Amúgy még csak alig olvastam bele a könyvbe de elképesztő hogy miket lehet így C-ben megvalósítani... Illetve nem is az hogy miket hanem hogy milyen egyszerűen és ami számomra még jobban hangzik hogy sokkal-sokkal átláthatóbban! Egyetlen sorba belefér az ami assembly-ben 30-40 sor meg vagy három szubrutinhívás volt. És akkor csak elosztottam két 32 bites számot (a 8 bites PIC-kel), kivontam belőlük egy harmadikat és megnéztem hogy az eredmény kisebb vagy nagyobb-e mint valamennyi. Ez mostantól akkor csak egy sor lesz?! Te jó ég, és én még komplett menürendszereket írtam assembly-ben!
a=(++b)+(c++)+(d++), ahol b=2, c=3 , d=4: Elírtam...
++b = 3, mivel elöl van a ++, a 3 -at használjuk fel, 3 + 3 + 4 = 10, de közben növeljük c és d értékét is. Ne várj csodákat. Amit így leírsz egyetlen sorban, az minimum kétszer hosszabb lesz assembly kódban, mint amit magad írtál volna... A hozzászólás módosítva: Szept 17, 2013
Abban biztos is vagyok, de hogy nekem könnyebb lesz átlátnom a programot az is biztos! Illetve csökken a hibalehetőségek száma mert én személy szerint mindig azt csinálom hogy ha pl egy három bájtos kivonásra van szükségem akkor lusta vagyok begépelni, inkább rákeresek a programomban a subwfb szóra, mert biztos hogy valahol már leprogramoztam egy ilyet. Onnan kimásolom, beillesztem és átírom címkéket és persze a regiszterneveket. Kb a programhibák felét nálam az okozza hogy valamit ezek közül elfelejtek átírni.
Idézet: Pedig makrókat is használhattál volna erre a célra! Azt pont erre találták ki... „Onnan kimásolom, beillesztem és átírom címkéket és persze a regiszterneveket.”
Használok azokat is, de nem mindig. A bonyolultabb dolgokra amik többek mondjuk 6-8 sornál, ott jön szóba a makró nálam. Osztásra, gyökvonásra, hatványozásra, sokbájtos szorzásra szubrutint hívok de a 2-3 bájtos inkrementálásokat/dekrementálásokat vagy kivonásokat/összadásokat, pár bájtos összehasonlításokat inkább beírogatom csak.
A hozzászólás módosítva: Szept 17, 2013
Idézet: „Eddig két dolog nem világos” Ez három volt
Kis szemfüles! Igen, közben szerkesztettem.
Elolvastam mindent és nagy részben értem is szerencsére. Úgyhogy elkezdenék programozgatni!
1.- Jól gondolom ugye, hogy ha PIC18(F25K80)-at szeretnék programozni akkor a Microchip C18 fordítója kell nekem? Olvastam hogy ez nem freeware, miféle korlátozásokat tartalmaz az ingyenes verzió? És mennyibe kerül a teljes verzió? Bár gondolom mivel ez egy fejlesztőeszköz aminek a segítségével anyagi haszonra lehet szert tenni, nem a hobbistáknak szóló ára van. Ez esetben elég lesz nekem az ingyenes verzió vagy rákeressek az nCore-on? 2.- Assembly-ben van egy csomó szuper jó kis szubrutinom, mint például LCD inicializáló, kiírató, kijelző-törlő rutinjaim, időzítő rutinok, bináris-decimális átalakítók, négyzetgyökvonás és pár hasonló matematikai algoritmus stb. Ezekre itt is szükségem lenne, honnan lehet ilyeneket letölteni? Némelyiket megírom újra de egy hat bájtos négyzetgyökvonást vagy egy 8 digites átalakítót nem szeretnék bepötyögni. Főleg hogy később trigonometriai függvényekre is szükség lesz a fogyasztásmérőmnél. Sőt, úgy hallottam hogy C-re van kész FFT is amit csak beillesztek és megy is. Igaz ez? 3.- A legnagyobb szám a "long long" lehet 32 bittel, oké. Na de nekem már assembly-ben is egy csomószor 48 bites számokkal kellett dolgoznom! Akkor az most hogyan lesz? Ugyan úgy mint ahogy assembly-ben bájtonként számolgattam manuálisan, most "long long"-onként kell majd csak C-ben? 4.- Ha átváltok assembly-re mert bizonyos feladatoknál erre a programrész lefutásának ideje miatt szükségem lesz, akkor ott használhatom konkrétan például ezt: movf regiszter+1, W //regiszter felső bájtjának mozgatása a W-be A "+1"-et úgy fogja értelmezni a C fordító ahogyan én? Nem próbál meg hozzáadni egyet, ugye? (Azt már tudom hogy noha asm-re váltottam de a kommentelés akkor is két /-jellel történik és nem pontosvesszővel mint assembly-ben. A hozzászólás módosítva: Szept 18, 2013
1. XC8 vagy C18, használhatod bármelyiket. C18-ban egyik optimalizálás és a csak egyes chipekben benne levő bővített utasításkészlet használata volt tiltva, minden más tekintetben teljes értékűen működött. Az árát nézd meg chipcad-nél, de szerintem be fogod érni a demo verzióval is. XC8 demóról megoszlanak a vélemények, éppen itt írta vilmosd, ha jól emlékszem, hogy milyen ócska kódot fordít a demó
2. LCD kezelésre van kész C kód a fordító csomagjában is, de én azokat nem szeretem, ezért arra írtam sajátot. Egyszer kell normálisra megírni, aztán újrafelhasználható lesz az is. Van itt az oldalon is ilyen kód már, nemis kell nulláról megírni. Matematikai dolgok ott vannak a math.h-ban. Időzítő (bár ha jól sejtem, inkább késleltetőről lehet szó) rutinok léteznek, valami delay.h vagy ilyesmibe nézz bele. BCD rutinokat nem láttam alapból a csomagban, ezért vagy keresel neten, vagy megírod egyszer. 3. Erre én is kíváncsi lennék, hogy lehet 32 bitnél többet kezelni egyben. Megoldani meg lehet, a kérdés csak az, hogy hogyan. Egyébként a sima long már 32 bites, a long long az 64 bites lenne, de a C18-ban tényleg csak 32 bites az is. 4. Használhatod. Ha átváltasz assemblyre, akkor ott minden úgy fog történni, ahogy assemblyben megszoktad.
Szia! Nem tudom, hogy ismered e, de ez egy nagyon jó könyv a C-hez: Bővebben: Link
|
Bejelentkezés
Hirdetés |