Fórum témák
» Több friss téma |
helyett írd így:
Sziasztok,
PIC12F1840/MPLAB/XC8 - UART kapcsán a következő rutinom van: A rutin egy stringgel hívható aminek a végét a NULL terminátor ellenőrzésével ellenőrzi. void Write2Serial (const char *DataOut) { while ((DataOut!="\0")) { EUSART_Write(*DataOut++); //__delay_ms(50); } } A rutint az alábbi módon hívom meg de nem érzékeli a végét: const char str1[] ="OK"; Write2Serial(str1); Próbáűltam így is: const char str2[] ={'O','K','\0'}; Write2Serial(str2); Mi lehet az oka? Egyetlen mód ahogy megy az a következő: Write2Serial("OK"); De én egy változóval szeretném meghívni. Előre is kösz, Gacserus
A const char* az XC8 -ban egy ROM -ban tárolt karakterlánc mutató, ezért fogadja el csak a "OK" parametert. Javítsd ki a deklarációt:
Ezt az eljárást már hívhítod így is:
Köszi a tippet,
kijavítottam: void Write2Serial ( char *DataOut) { while ((DataOut!="\0")) { EUSART_Write(*DataOut++); //__delay_ms(50); } } Hibaüzenetet kaptam: can't generate code for this expression Így hívom meg: char str1[] ="OK"; Write2Serial(str1); Idézet: „while ((DataOut!="\0"))” A fenti sor nem jó, mert a macskaköröm használata stringet eredményez, amit egy mutatóval akarsz összehasonlítani. Én inkább így próbálnám:
Tudom, hogy a fórum azért van, hogy kérdezz, de még is megpróbálhatnád leszimulálni a programodat és rögtön kiderülne minden kérdésedre a válasz...
Köszi, ez végül megoldódott annyival hogy a WhitchMap az unsigned int lett.
Viszont most nem tudok double -t csinálni két unsigned int -ből. Az a problémám, hogy PID szabályzó egy hatalmas unsigned int tömb 2 eleméből kéne hogy kapja a "P" értékét, ami double. A double 0.1 az a memóriában 0x3DCCCCCD azaz elvileg össze kéne hogy tudjam rakni 2 int-ből:
valami-be szépen bekerül a 0x3DCCCCCD, de a P -ben 0x4E773333 lesz...
Miért akarod lebegőpontos számításokkal megfojtani szegény PIC-et!? Egészekkel nem lehetne megoldani? (dehogynem ).
24EP512... családból való. Meg se kottyan neki . Régen a 18F -eken asm-ban én is úgy csináltam, de azért váltottam C-re hogy lehessen így. Lemértem szimulátorban, gyorsabb a C-s lebegőpontos PID rutinom optimalizáció nélkül ezen (120MHz), mint a 18F -eken volt asm-ben egész számokkal. Csak az ilyenek miatt haragszom a C -re... évek óta barátkozom vele, de valamiért nagyon nem tudom befogadni néhány hülyeségét.
Akkor ez a megoldás(lásd a képet).
Javaslom neked is a szimulációt!!! Ja igen, a bal felső és a középső alsó számot nézd! Titok a lebegőpontos szám ábrázolás... A hozzászólás módosítva: Szept 16, 2014
Én is szimulátorban (vagyis debug alatt) nézem.
Ezt az összefüggést én nem vettem észre, de nem tudom ez hogyan segít nekem. P-ben 0.1 -et, azaz 0x3DCCCCCD kéne hogy lássak, ehelyett 1.03683194E9 azaz 0x4E773333 van. Mint nálad. Értem én hogy a fordító helyettem próbál gondolkodni, és a hex- ből decimálist csinál, majd azt tárolja el hatvány alakban, de ezzel (hogy okos próbál lenni) az őrületbe kerget. Muszáj lesz asm betétekkel arra a memória címre másolnom azt a 2 word-öt.
Dehogy okoskodik! A lebegőpontos számábrázolás ilyen formában tárolja a long értékét. Igaz kerekíti, mert nem fér bele. 0x3DCCCCCD=1036831949, ami 1.036832E+9, azaz 1036820000.
Na jó, de nekem ne foglalkozzon a long "értékével", hanem a nullákat és egyeseket pakolja át egyik memória címről a másikra. Az hogy az egyik long, a másik double, azon ne gondolkodjon, mert megárt! Főleg nekem...
De érdekel más megoldás is. Akkor hogy csinálnátok azt, hogy pl. soros porton PC-ről átküldeni egy 32biten tárolt double-t? Szét kell szednem 4 byte-á, majd a PIC-ben összerakni. Na ezzel az összerakással van bajom. Persze a PC oldalt még nem néztem, remélem valamennyire szabványosak C -ben ezek a számábrázolások, és ott nem kell assembly, mert különben keresek valami más hobbit. A hozzászólás módosítva: Szept 16, 2014
De hiszen te akarod double típusba pakolni a long-ot, ami nem fér bele!
Simán össze lehet rakni. De egyelőre azt nem értem minek rakod bele, miért nem a long-ot küldöd át azt csak össze kell állítani simán! Közben módosítottál, úgy olvastam az előbb, hogy a PC-re akarod küldeni a double-t. Akkor mi a feladat? A hozzászólás módosítva: Szept 16, 2014
PC-ről PIC-re. És a PIC-ben összerakni, majd double-ként felhasználni.
Idézet: „De hiszen te akarod double típusba pakolni a long-ot, ami nem fér bele!” De hát mind a kettő 32bites, nem?
A megoldás az union: 4 byte, 2 word, 1 longword és egy float elfér 32 biten. A kérdés az, hogy a fordító hány biten ábrázolja e double -t.
Lehet hogy az lesz a megoldás hogy csinálok egy union-t... így ugyan azt a memóriaterületet elérem long-ként a (és char -ként) a soros port kezelő függvényből, majd a PID függvény eléri ugyan ezt a memória területet double-ként.
Szia! A fordító 4 bájton ábrázolja a double-t és a float-ot is. Gyakorlatilag a kettő itt ugyanaz.
Köszi mindkettőtöknek! Így már működik.
Tehát e- helyett:
Ez:
... és még azt a sok léptetést is megúszod...
Ja, hogy a 0x3DCCCCCD egy törtszám lebegőpontosan (0.1)? Ezt eddig nem értettem meg...
A hozzászólás módosítva: Szept 16, 2014
Amúgy lehet ám C-ben cast-olni is, nem muszáj uniont használni. Csinálsz float/double változót, majd castolod az adott helyen long-ra vagy akár char-ra, és ugyanúgy ugyanazt a memóriaterületet éred el. Néha célszerűbb az union, néha a castolás, helyzettől függ.
Pl.
A hozzászólás módosítva: Szept 16, 2014
watt:
Idézet: „Ja, hogy a 0x3DCCCCCD egy törtszám lebegőpontosan (0.1)?” Pontosan így van, bocs ha félrevezető voltam. Két uInt -ből (0x3DCC és 0xCCCD) kéne összeraknom a double 0.1 -et. Persze a konkrét számok csak egy példa. Tökéletesen működik a fenti union-os megoldással, de potyo verzióját is szeretném megérteni. Bár az pont az ellenkező irány mint ami nekem kell, nem is értem teljesen, de az alapján ezt csináltam:
Szerk: De ez még mindig nem castolás... A hozzászólás módosítva: Szept 17, 2014
Nem castolás, de pointer aritmetika. Az is egy jó dolog a C-ben
Ez azt csinálja, hogy kiszedi a P változó címét (ami ugye egy double-re mutató pointer), a címet castolja unsigned-re mutató pointerré, és utána azt a pointert indexeli 0-val és 1-el. Azért lehet indexelni, mert a pointer és egy tömb neve a C-ben majdnem ugyanazt jelenti. Ha egy adott típusra mutató pointert indexelsz, akkor az ugyanaz, mintha az adott típusból lenne egy tömböd, és azt indexelnéd. A hozzászólás módosítva: Szept 17, 2014
Köszi, Értem! Lett néhány megoldás a végére!
Ezt nem ismertem, köszi! Nem is foglal nagy helyet, talán 21 parancs.
Eddig uniont használtam... Az unsigned önmagában gondolom int-et jelent. Megcsináltam char-okkal, úgy is működik bájtonként, tetszik... A hozzászólás módosítva: Szept 17, 2014
Elvileg ez csak C-ben néz ki ilyen rosszul, lefordítva nem kellene, hogy vészes legyen a dolog. Ugyanaz kellene, hogy legyen, mintha a P már eleve egy unsigned típusú tömb lenne. Esetleg próbáld ki, hogy ugyanazt kapod-e, ha ezt csinálod
Na meg szintén elvileg ugyanaz, mintha az ember csinálna uniont és azzal végezne műveleteket egyszer double-ként, máskor másképp. És még lehetne úgy is írni, hogy
int-et nem kötelező kiírni, mert az az alapértelmezett. Mint ahogy azt sem szokás írni, hogy signed int, hanem csak az int-et, mert a signed az alapértelmezett. Persze mindkettő egyszerre nem hagyható el, de ha már az unsigned ott van, akkor az int elhagyható. A hozzászólás módosítva: Szept 17, 2014
Igen, a művelet végzés unionnal szinte azonos méretet igényel. Valójában a fordító mindkét esetben előre elkészíti a kódot, csak a leírás formája más.
A hozzászólás módosítva: Szept 17, 2014
Sziasztok!
Van egy 5*5-ös led mátrixom. Mindenféle képeket rajzolnák ki vele, amit aztán körbeforgatok. Azért, hogy ne legyen olyan nagy fogyasztása, multiplexelve rajzolnám a képeket. most az a bajom, hogy így sokkal halványabban világítanak a ledek. Meg lehet úgy oldani, hogy ne veszítsenek sokat a fényerejükből? Ez a program:
|
Bejelentkezés
Hirdetés |