Fórum témák
» Több friss téma |
2 még jó, akkor még ott van, utána veszteség !
A hozzászólás módosítva: Ápr 1, 2015
2 sem jó. mindkettő 2 ciklus. Nekem a sebesség a fontos most. Inkább nekiállok megírom én ASMben minthogy mindig átnézzem milyen szemetet fordított.
Sokáig mérgelődtem, majd ugyan erre a következtetésre jutottam...
Ez egy 16F1705.
Küldöm az egész programot. Egy állítható időzítő lenne, nagyon egyszerűen megoldva, maga a program sem tökéletes, de ez nem baj, csak az ADC-t kéne helyrehozni. A hozzászólás módosítva: Ápr 3, 2015
Így elsőre a "kikapcs" értéke lehet lebegőpontos is, bár ez elvileg nem lehet gond, de nem árt ott a típusokkal variálni.
És azt sem tudom miért kellene long típusokat használnod, szerintem oda short is elég lenne. PIC, hogy van bekötve?
Srácok, nekem is szükségem lenne egy kis segítségre vagy legalább kis lökésre, mert leakadtam.
Van egy függvényem ami nem azt csinálja amit kellene neki:
Ha a példát le akarjuk követni a következőket kellene csinálnia. fok változó értéke 500 lesz, oszto változó értéke 0,0775 vagy is lebegőpontos szám lesz, hofok változó értéke a feltétel lefutása után megkapja fok változó -100 értékét vagy is 400 lesz. result változónk értéke hofok*oszto vagy is 400*0,0775 azaz 31. Jelenleg az eredmény nulla lesz. Arra rájöttem, hogy a típusokkal lesz valami gubanc, de eddig sikertelenül kísérletezgettem. C18, MPLAB A hozzászólás módosítva: Ápr 3, 2015
Tobb hiba is van. Eloszor is nincs olyan, hogy unsigned float. Furcsa, hogy a fordito nem szol erte.
De a fo hiba az osztoban van. az, hogy 31/400 az nem lebegobontos szamitas, hanem egesz, igy annak az erteke 0 lesz. Ha azt irod, hogy oszto = 31 / 400.0; akkor mar jo lesz. De ezt az egeszet meg lehet csinalni float nelkul is. result = (fok * 31) / 400; A hozzászólás módosítva: Ápr 3, 2015
Réges-rég, még PC-n használtam valamennyit a C nyelvet, nem vagyok benne - sajnos - profi. Azt szeretném kérdezni, ha az alábbi mintában egy regiszter bitet, vagy egy regisztert szeretnék paraméterként megadni, azt milyen típusnak kell megadni a hívott eljárás paramétereként, illetve hogyan tudok rá hivatkozni az eljárásban?
(Mivel linuxon nyomulok, MPLAB-X-et és XC8-at használgatom.)
Ha a hivott fuggvenyben a regiszter erteket valtoztatni is akarod, akkor a cimet kell atadnod.
Szerintem regiszter bitjere (bit field) ilyen modon nem tudsz hivatkozni, csak egesz regiszterre. A PIC regiszterek tobbnyire "volatile unsigned char" tipusuak.
Ha nem akarod modisitani a regiszter erteket, akkor sima unsigned char vagy int-nek deklaralod:
A hozzászólás módosítva: Ápr 4, 2015
'csmit. Azert erdemes az elsot is megerteni, mert ez a C alapjaihoz tartozk. Tipusok es implicit konverziok.
Azért nem írtam rá mert az véletlen került oda és maradt ott (float)
Ha erre gondolsz: "oszto = 31/400; //0,0775" Akkor viszont tényleg nem értem. Az oszto változó egy lebegőpontos változó, úgy tudtam ezek szerint rosszul, hogy az eredmény lesz majd lebegőpontos. Ezek szerint csak, akkor lesz valami lebegőpontos, ha a benne elvégzett műveleti értékek is lebegőpontosok, vagy legalább is az egyik? Ha azok viszont egészek akkor a művelet eredménye is egész marad. Bár ezt leírni is fura... A hozzászólás módosítva: Ápr 4, 2015
A short szerintem semmiképp nem elég, az adc_val 1023-ig mehet, oda kell a long, az i változónak 600-ig kell tudni számolni, a kikapcs pedig az (adc_val+120)/2 értéket vehetni fel, ez maximum 571. (Talán nem is kéne külön felvenni a kikapcs változót, de bőven van hely, most nem kell spórolni vele.)
Kapcsolás a mellékletben. A hozzászólás módosítva: Ápr 4, 2015
Ha az osztas mindket operandusa egesz, akkor egesz osztast fog vegezni, es az eredmeny is egesz lesz. Ha a ket operandus nem azonos tipusu, akkor szigoru szabalyok szerint egyforma tipusuakra lesznek konvertalva a muvelet elott, es a muvelet is olyan tipusu lesz. A tipuskonverzio lenyege nagyjabol, hogy a kevesebb bitbol allo valtozot konvertalja a nagyobbra. Ha azonos szelessegu unsigned es signed keveredne, akkor unsigned lesz a signed-bol. Az osszes char-t es short-ot automatikusan int-re konvertalja, az osszes float-ot double-ra. Ez mindig megtortenik, minden muvelet elott.
Ha pl. egy int es egy long van, akkor az int-et long-ra alakitja, es long osztas lesz. Ha az egyik float, a masik int, akkor mindkettot double-ra alakitja, es double osztast csinal. pont azt csinalja, mintha ezt irnad le: int a; long b, c; c = (long)a + b; De neked nem kell odairnod a (long)-ot, mert a C fordito automatikusan beleteszi. ha azt irod, hogy: double oszto; oszto = 31 / 400; abbol ez lesz: oszto = (double) (31 / 400);
Sokkal egyertelmubb a dolog, ha az stdint.h-t include-olod, es onnantol kezdve a int8_t uint8_t, int16_t, stb tipusokat hasznalod. A short, long, int annyi bites, amennyit az adott 'C' fordito jonak lat. Viszont az int16_t az garantaltan 16 bites int.
Mindig megnézem a program súgójában, hogy milyen nevű változót írok a programba, melyikbe "fér bele", amit szeretnék.
Beírtam így, amit ajánlottál, de ugyan azt csinálja, mint eddig, nem regál a potira, akármerre tekerem. Már kipróbáltam úgy is, hogy a pic bemenetét közvetlenül tápra, vagy gnd-re kötöttem, kizárva a poti hibáját, és úgy is ugyan ez van.
Felreertesz. Azt nem tudom, hogy az AD miert nem mukodik, nem ezert irtam, amit irtam. Altalanos jotanacs, hogy ha ezeket a tipusokat hasznalod, akkor az mindig, minden forditon, minden processzoron ugyanzt jelenti. A programod elvileg jo kellene legyen, nem talalok benne semmi elmeleti hibat. (Amig a kapcsolo nyitva van, addig a kimeneti LED vilagit. Amikor a kapcsolo zarva van, akkor a masik LED villog, es a kimenet lekapcsol egy az AD ertektol fuggo ido utan.) Az AD inicializalas, esetleg nem lehet rossz? Nem tudom, hogy kell-e kulon analogra allitani a RA4-es labat.
A lényeg, hogy átírtam, de köszi, hogy megosztottad ezt velem, így legalább nem kell mindig megnéznem, milyen változót kell beírnom.
Igen, pont ezt akartam elérni a programmal, és szépen működik az AD-t kivéve. Biztosan az inicializálás lehet rossz, mert próbáltam több porton is, egyikkel sem működik. Csak nem tudom, hogy kéne inicializálni, hogy jó legyen.
Az egyik jo modszer az inicializalasra, hogy elolvasod az adott PIC adatlapjat, es annak megfeleloen inicializalod a regisztereket. Igy nem fuggsz a gyari vagy gagyi vagy akarmilyen fuggvenykonyvtaraktol.
A read_adc() fuggvenynek nem kell atadni, hogy melyik bemeneten olvasson?
Az a baj, hogy az adatlap assembler-ben adja meg a dolgokat, én ahhoz meg nagyon nem értek. De nem is lenne mit másképp inicializálni, mint ahogy a programban van.
Nem tudom, lehet, hogy valamit itt kéne megadni, de akárhogy írom be a zárójelbe a 3-at, nem akarja elfogadni a fordító.
Az adatlap azt adja meg, hogy a regiszterek egyes bitjei mit jelentenek. Ez se nem assembly, se nem C. Mindegy, hogy egy regiszterbe hogyan irsz be egy erteket, az a fontos, hogy mit irsz bele. Ez van leirva az adatlapban.
A programod meghiv tobb konyvtari fuggvenyt, ami inicializalja az AD-t. Ezteket a fuggvenyeket valaki megirta, es gondolom, azt is leirta, hogy mik a parameterei. Ez igaz kell legyen az adc_read() fuggvenyre is. Milyen fordito ez, milyen konyvtarral?
Ja, így már értem mit írsz. De honnan tudom, hogy az én fordítóm jó regisztereket használ-e?
CCS C Compiler 5.037-et használok, a könyvtárról semmit nem tudok, feltelepítettem a programot, én azóta nem bántottam.
itt egy reszlet a CCS fordito leirasabol:
set_adc_channel(2); delay_us(10); value = read_adc(); Ezt te is elolvashatod, ebben le van irva, hogy melyik fuggveny mit csinal.
Nagyon jó, végre működik, nem írtam be a set_adc_channel sort, és a 10us késleltetést. Pontosabban próbáltam beírni, de nem jó helyre tettem, mert bár a main függvényben, de a while cikluson kívül volt, a setup_adc soroknál.
Köszönöm szépen a segítséget!
Sziasztok. Hi-Tech PICC-18 vagy XC8 adat EEPROM kezelésével lenne egy kis gondom. Lenne néhány változó amit abban tárolnék. Az adatok kezdőértékkel való ellátását a fordító programmal végezném.
Ehhez kicsit módosítottam a beépített __EEPROM_DATA(a, b, c, d, e, f, g, h); makrót, hogy ne csak 8db 8bites, hanem 16 vagy 32 bites értékekeket is el tudjak tárolni.
A fenti kóddal szépen bele is teszi az adatokat az EEPROM-ba, de hogyan tudnám kinyerni az így betett változók EEPROM-beli címeit, mert semmilyen név, cimke nem tartozik az egyes értékekhez?
Hali!
nem tudok róla hogy lehetne automatikusan cimkézni az eeprom területen, én igy csinálom, úgyis tudom mit hová teszek az eepromban: static enum //eeprom kiosztás { EEaddr_nyit_tanit_veg1L = 0x10, // kezdőcím 0x10 EEaddr_nyit_tanit_veg1H, //11 EEaddr_nyit_start_tim1L, //12 EEaddr_nyit_start_tim1H, //13 EEaddr_nyit_tanit_veg2L, //14 EEaddr_nyit_tanit_veg2H, //15 EEaddr_nyit_start_tim2L, //16 EEaddr_nyit_start_tim2H, //17 EEaddr_autcsuk, //18 //byte EEaddr_SETUP, //19 EEaddr_DIP //1a }; .... EE_nyit_start_tim1 = ee_read(EEaddr_nyit_start_tim1L) + ee_read(EEaddr_nyit_start_tim1H) << 8); ... //org 0 __EEPROM_DATA(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff); __EEPROM_DATA(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff); //org 0x10 __EEPROM_DATA(0x72, 9, 0x2c, 01, 0x51, 0x0c, 0x84, 0x03); ...
Köszi, akkor marad az általad felvázolt mechanikus materialista módszer.
Múltkor azt hiszem, nem fogalmaztam meg jól a kérdésem. Az XC8-ban szeretném azt elérni, hogy paraméterként át tudjam adni bármelyik regisztert, vagy annak csak egy bitjét. A bitenkénti elérést ismeri az XC8, csak nem tudom, hogyan kéne ezt paraméterként átvenni az eljárásban. (Mint említettem, nem vagyok kellőképpen otthon a C-ben.)
Szia!
Baj van, mert van 8 bites regiszter és van 16 bites is. Ha 8 bitessel akarsz foglalkozni, akkor egy unsigned char* tipusú mutatóval kell átadni a konkrét regisztert, ha 16 bitessel akkor unsigned int* tipusúval.
A C-ben a legkisebb megcimezheto egyseg a char, ezert egy regiszter 1 bitjenek a cimet kozvetlenul nem tudod atadni egy fuggvenynek.
Ezt csak ugy tudod megoldani, hogy atadod a regiszter cimet es atadsz melle egy maszkot vagy bitpoziciot:
Ehhez hozzatartozik az is, hogy a fenti megoldas hasznalataval a forditott assembly kod nem egy egyutasitasos bitset vagy bitclr utasitast fog eredmenyezni, hanem tobb utasitasbol fog allni a muvelet, amit ha kozben megszakit egy interrupt es az is akarja modositani az eppen modositott regisztert, akkor abbol baj lehet. |
Bejelentkezés
Hirdetés |