Fórum témák

» Több friss téma
Fórum » PIC programozása C nyelven, C-Compiler
Lapozás: OK   59 / 153
(#) _vl_ válasza diablo hozzászólására (») Júl 19, 2012 /
 
Idézet:
„Gondolom akkor ezzel a módszerrel azt is könnyedén már meg tudom csinálni, hogy egy float vagy int típusú változót küldjek ki a soros portra.”

Meg lehet csinálni, bár egyfelől nem értem, mire kell egyáltalán a float típus, másrészt úgy érted, hogy a több byte-os típusokat byte-okra bontani? Mert arra tökéletes a union. Pl.:

  1. union {
  2.   unsigned long data;
  3.   unsigned char bytes[4];
  4. } var;
  5.  
  6. var.data = 0x12345678;
  7. send(var.bytes[0]);
  8. send(var.bytes[1]);
  9. send(var.bytes[2]);
  10. send(var.bytes[3]);
(#) El_Pinyo válasza diablo hozzászólására (») Júl 19, 2012 /
 
A Te verziód nem működik megfelelően. Az union-nak az a speciális tulajdonsága van, hogy a benne szereplő elemek azonos memóriaterületen vannak tárolva, így amikor Te az f0-nak adsz értéket, egyben az f1-nek is ugyanazt az értéket adod.
(#) diablo válasza _vl_ hozzászólására (») Júl 20, 2012 /
 
Igen úgy értem, mert eddig csak 2 byte-os számot tudtam kiküldeni bit tologatás révén, több byte-osnál nem jöttem rá, hogy lehetne a középső byte-okat is kinyerni könnyedén, de így már akkor egyszerűnek hangzik.

(#1264502) El_Pinyo:
De az f0 meg az f1 csak 1 bit méretű. Könyvben én úgy értelmeztem, hogy csak byte-nál ugyanaz, tehát 1 darab 1 byte-os változó deklarálásánál még működne, nem?
*
(#) watt válasza diablo hozzászólására (») Júl 20, 2012 /
 
És, hogy válaszoljak egy jó kérdésedre, mert valószínű azt szeretnéd elérni, hogy egy lebegőpontos számot elküldjél a soros porton bájtonként:

  1. Deklarálás (egy *.h fájlban érdemes):
  2. //floathoz hozzáférés bájtonként.
  3. union{
  4.  float x;
  5. struct {
  6.     unsigned B0:8;
  7.     unsigned B1:8;
  8.     unsigned B2:8;
  9.     unsigned B3:8;
  10. };
  11. }uGazm_Pol_0;
  12. #define Gazm_Pol_0 uGazm_Pol_0.x
  13.  
  14. Használat Float-ként:
  15. Gazm_Pol_0=-0.123123;
  16.  
  17. Elküldése bájtonként:
  18. ....
  19. while(!TRMT);
  20. TXREG=uGazm_Pol_0.B0;
  21. while(!TRMT);
  22. TXREG=uGazm_Pol_0.B1;
  23. while(!TRMT);
  24. TXREG=uGazm_Pol_0.B2;
  25. while(!TRMT);
  26. TXREG=uGazm_Pol_0.B3;
  27. while(!TRMT);
  28. ....

(A PC-n összerakni nehezebb, de az más téma.)
(#) _vl_ válasza diablo hozzászólására (») Júl 20, 2012 /
 
Viszont átszaladtál azon a ponton, hogy miért is használsz float-ot...
Mert szerintem extrém ritka dolog az, amikor egy 8-bites mikrokontrollerben érdemes float típust használni (nekem még konkrétan nem volt ilyen esetem a pályafutásom alatt).
És mielőtt megkérdeznéd: fixpontos integert kell használni helyette.
(#) watt válasza _vl_ hozzászólására (») Júl 20, 2012 /
 
Szia! Én műszerekhez szoktam lebegőpontosat használni akkor, ha polinom együtthatókkal kell számolni a kalibrációnál. Nem okoz gondot egy PIC-nek polinomsor kiszámítása. Sokkal bonyolultabb lenne konvertálgatni fixponotossá, főleg ha soros porton keresztül egyszerűen akarjuk feltölteni az együtthatókat. Legalább is nekem így tűnt egyszerűbbnek.
A kérdésed ugyanakkor jogos, mert nem tudjuk ő mit akar...
(#) diablo válasza watt hozzászólására (») Júl 20, 2012 /
 
*
A jó kérdés az volt, amit El_Pinyo-nak tettem fel, ezt már _vl_ is megválaszolta, de köszi
(#) diablo válasza _vl_ hozzászólására (») Júl 20, 2012 /
 
Játszásiból.
Nem gondoltam volna, hogy ennyire érdekel.
Egyébként szabályozást tervezek.
Bevallom őszintén még nem volt dolgom fixpontossal, így utána kellene néznem hogy is van az. PC-re való programozáskor mindig float-tot használtam, így ezt találtam egyszerűbbnek itt is.
A program még csak kezdeti fázisban van, lehet nem is kell majd float. Csak most jó lenne kiküldeni az értékeket a számítógépre vagy lcd kijelzőre, hogy lássam hol a hiba (az előbbi már megy, az utóbbi még nem).
Meg pár tört számot jó lenne állítgatni a számítógépről vezérelve (pl. hurok erősítést ami lehet, hogy csak 1,86), hogy ne kelljen mindig újra programozni az eszközt. De ha igaz, hogy ha valamilyen terminálon keresztül beküldöm például a 1,86-ot és azt még át kellene konvertálni fixpontosra, akkor jelen esetben a float egyszerűbbnek tűnik.
(#) potyo válasza diablo hozzászólására (») Júl 20, 2012 /
 
Alapvetően az a gond a float és hasonlókkal, hogy a(z egyszerűbb) kontrollereken nincs rájuk hardveres támogatás, emiatt szoftverből kell megoldani velük minden műveletet, ami egyrészt lassú, másrészt sok kódmemóriát foglal. A kódmemória méret még mondjuk tűrhető, mert ha már valahol van pl. két float szám összeadása, akkor másik kettő összeadása már nem fog sok plusz memóriát igényelni, viszont ha valamit sokszor kell kiszámolni, akkor ott már nagyon problémás lehet a float miatti lassúság.

PC-n más a helyzet, a processzorok már jó ideje tartalmaznak matematikai segédprocesszort, ami ezekkel a számokkal történő műveleteket is hardverből megoldja, így nem jelentősen lassúbb a kód, bár azért ott is illik egész típusokat használni ahol lehet, mert azoknál nem jönnek elő a számábrázolási problémák, kerekítések, stb. De kontrollereknél, főleg ha valamit sokszor kell számolni, ott érdemes valamilyen egész típust használni.

Terminálon hogyan küldöd át az 1,86-ot? Küldesz egy egyest, vesszőt, nyolcast és hatost? Mert akkor küldhetnél 186-ot, és akkor a kontrolleren meg akár egész típusokkal elvégzed a műveleteket, majd a végén elosztod százzal az eredményt.
(#) diablo válasza potyo hozzászólására (») Júl 20, 2012 /
 
Tudom, hogy lassabb a művelet végzés vele, de még nem forrott ki teljesen a kód, szóval biztos fog még változni minden. A szorzás/osztáson én is gondolkodtam, de ma még nem volt időm tesztelgetni. Jó lenne még egy saját terminálos progit is írni, csak ezt a visual basic-et kellene áttanulmányozni...:-/
(#) _vl_ válasza diablo hozzászólására (») Júl 20, 2012 /
 
Idézet:
„Bevallom őszintén még nem volt dolgom fixpontossal, így utána kellene néznem hogy is van az.”

Szerintem kezdjed ezzel, aztán rájössz, hogy a világ legegyszerűbb dolga. Tényleg vannak esetek, amikor a float a helyes választás, de ritka, mint a fehér holló.
Alapvetően a PC-d kb. 1000x gyorsabb integer műveletekben, és kb. 100.000x gyorsabb float műveletekben, mint egy PIC. Ami számítást csak tehetsz, tolj át a PC-s oldalra (majd ott dolgozik a CPU).
Sajnos egy 8-bites mikrokontrollernél a lehető legritkább esetben teheted meg, hogy abszolút nem foglalkozol vele, mi mennyi idő alatt hajtódik végre. Ez túl nagy luxus, amit csak a GHz-es CPU-k programozói engedhetnek meg maguknak
(#) watt válasza diablo hozzászólására (») Júl 20, 2012 2 /
 
Már elnézést, de senki nem válaszolta ezt meg eddig, ha azt hiszed igen, nem értesz még pár dolgot...
(#) Atielektro válasza _vl_ hozzászólására (») Júl 20, 2012 /
 
Megkérhetnélek, hogy csatolsz pár fixpont kezelő C rutint, hogy lássam hogy is kell ezt elképzelni?
Írtam egy 32 pontos FFT-t egy 16LF1638-ra és hát ráférne egy kis gyorsítás... Épp át akarok térni 24F-re, de megpróbálkoznék még a fixpontos számábrázolás használatával, hátha azzal nyernék egy kis plusz erőforrást, mert igazából a 24F-et nem használnám ki rendesen.
Előre is köszi bármilyen segítséget!
(#) Moderátor hozzászólása Júl 21, 2012
 
Diablo és watt! Könyörgöm, privibe! Privibe! Köszi!
(#) El_Pinyo válasza diablo hozzászólására (») Júl 22, 2012 /
 
Rosszul értelmezted. Próbáld ki szimulátorral, watch window segítségével. Ott láthatod, hogy a nem módosított union tag is módosul.
(#) diablo válasza El_Pinyo hozzászólására (») Júl 23, 2012 /
 
Mplab-bal nem tudom hogy kell megnézni de megnéztem más szimulátorral a regiszter tartalmát és tényleg ugyanaz az összes bit.
Természetesen struktúrával működik szépen a bit állítgatás is. Köszi a választ!
(#) _vl_ válasza Atielektro hozzászólására (») Júl 23, 2012 /
 
Őket neked kerestem: Bővebben: Link Bővebben: Link
(#) diablo válasza watt hozzászólására (») Júl 23, 2012 /
 
Na volt egy kis időm az összes variációt kipróbálni köztük a tiedet és arra jutottam, hogy mind a 3 ugyanazt csinálja.
  1. union
  2. {
  3. float data;
  4. struct
  5. {
  6. unsigned byte0 : 8;
  7. unsigned byte1 : 8;
  8. unsigned byte2 : 8;
  9. unsigned byte3 : 8;
  10. }bytes;
  11. }var;

_vl_ ezt válaszolta meg, csak annyit változtattam rajta, hogy az unsigned char-t float-ra írtam és 8 bitesekre a byte-okat (ennyi még nekem is megy). Egy szóval ugyanaz, de ezt ránézésre is meg lehetett mondani. A változókat kicserélni meg bárki kitudja.

De mégis a legkézenfekvőbb megoldás a struktúra nélküli union amikor egy union-ban hozzuk létre a változót és mellette egy 4 elemű tömböt. A hivatkozás is sokkal egyszerűbb.
(#) Atielektro válasza _vl_ hozzászólására (») Júl 24, 2012 /
 
Köszi a linkeket! Feltétlen megnézegetem őket.
(#) trudnai válasza diablo hozzászólására (») Júl 25, 2012 /
 
Miert jobb neked amugy a bitfield mint a karakter tomb?

  1. union
  2. {
  3.     float data;
  4.     unsigned char byte[4];
  5. } var;
(#) diablo válasza trudnai hozzászólására (») Júl 25, 2012 /
 
Én nem mondtam hogy jobb, jelenleg is azt használom amit beszúrtál most kódot.
Kivéve 1db flag byte-hoz amihez struktúrát használok. Vagy azt is lehet unionnal? pl. bit[8] : 1 is érvényes kód lenne? 8 elemű 8 bites tömböt is lehet létrehozni? Még nem próbáltam.
(#) _vl_ válasza diablo hozzászólására (») Júl 26, 2012 /
 
A union arra való, hogy ugyanazt a memóriaterületet többféleképpen érhesd el (mondjuk bitenként is, meg byte-ként is). Azaz a unionban felsorolt mezők mind ugyanott (egymás hegyén-hátán) laknak a memóriában.
A struct mezői (bitek, byte-ok) egymás mellett laknak a memóriában. Tehát ha az a célod, hogy legyen 8 külön címezhető bited, akkor azt csak struct-tal tudod megcsinálni, mert ha unionba raksz 8 bitet, azok mind ugyanabban az egy szem memóriabitben fognak lakni.
(#) trudnai válasza diablo hozzászólására (») Júl 26, 2012 /
 
Tombot bitekre nem lehet letre hozni. Arra jo a bitfield. Amit irtam kodot csak azert irtam, mert ugy veltem ez neked arra kell, hogy a float valtozod egyes byte-jaihoz hozza ferhess, hogy azt at tudd kuldeni a soros vonalon.

A bit fieldet akkor szoktam kerulni, ha erdekes melyik bitet hova pakolassza. Ugyanis a C szabvanyban nincs definialva hogyan kell azt csinani. Egyes forditok optimalizalnak -- pl. PIC-nel az also ill felso 4 bithez (nibble) egyszerubb a CPU-nak hozza fernie, emiatt nem tartom elkepzelhetonek, hogy a
  1. struct
  2. {
  3.     unsigned char byte0 : 1;
  4.     unsigned char byte1 : 4;
  5.     unsigned char byte2 : 3;
  6. } bytes;

eseteben a 'byte1' mezo nem kozepen lesz, hanem legalul vagy legfelul. Van olyan compiler ami nem csinal ilyet, masok meg csak azzal vacakolnak, hogy a byte0 az most a 0. biten vagy a 7. biten van-e -- kvazi mint az LSB/MSB tarolasi problemak tobb byte-os adat strukturak eseten.
(#) diablo válasza trudnai hozzászólására (») Júl 26, 2012 /
 
Azt a struktúrásat csak watt kedvéért próbáltam ki.
Viszont a 2. bekezdésed nem teljesen világos, hogy mire akarsz kilyukadni, de most szerintem számomra az nem is olyan fontos.
(#) trudnai válasza diablo hozzászólására (») Júl 26, 2012 /
 
Idézet:
„Viszont a 2. bekezdésed nem teljesen világos, hogy mire akarsz kilyukadni, de most szerintem számomra az nem is olyan fontos.”


Mindegy is, lenyeg, hogy ha csak lehet en kerulom a bitfield-et, mert mikor egyszerre fejlesztettem 10 kulonbozo platformra akkor nagyon meggyult vele a bajom. Ha csak egyetlen kornyezetre fejlesztesz es nem cserelgeted a forditokat sem akkor valoszinuleg nem is fogsz ezekkel a problemakkal talalkozni.
(#) Amarton hozzászólása Aug 15, 2012 /
 
Helló,

PIC32-ben ez miért nem működik?

  1. unsigned int tps_ad_value = 600;
  2. unsigned int tps_value;
  3. unsigned int tps_lepeskoz = 10;
  4. float tmp_float = 0;
  5.  
  6. tps_value = tps_ad_value * 100 / 1024;       // 600 * 100 / 1024 = 58
  7. tmp_float = tps_value / tps_lepeskoz;        // 5,8


Valami miatt 0 értéket ad vissza a debugger tmp_float értékre.

Mi lehet a hiba?
(#) _vl_ válasza Amarton hozzászólására (») Aug 15, 2012 /
 
Hát, mondjuk az integer osztása integerrel, ez minden C fordítónál integer osztásra fog lefordulni (ettől még nem 0-nak, hanem 5-nek kéne lennie az eredménynek)...

Másrészt a debuggerrel nekem voltak gondjaim, gyakorlatilag teljesen megbízhatatlan, amikor a változók értékét kéne megmutatni.
(#) lokátoros válasza Amarton hozzászólására (») Aug 15, 2012 /
 
Szia,
Egy tipp:
A C fordítók a konstans kifejezéseket fordítási időben értékelik ki, eszerint a 100/1024 =0.
Igy a
tps_value = tps_ad_value * 0 lesz.
Nem ellenőriztem le, szerintem nézz utána az assembly listában hogy tényleg így van-e jelen esetben.
(#) Amarton válasza _vl_ hozzászólására (») Aug 16, 2012 /
 
Hogyan tudom, akkor elvégezni a műveletet?
Castolni mikor kell?
(#) Hp41C válasza Amarton hozzászólására (») Aug 16, 2012 /
 
Szia!

- Zárójelezéssel:
tps_value = (tps_ad_value * 100) / 1024;
- Két lépésben:
tps_value = tps_ad_value * 100;
tps_value /= 1024;
Következő: »»   59 / 153
Bejelentkezés

Belépés

Hirdetés
XDT.hu
Az oldalon sütiket használunk a helyes működéshez. Bővebb információt az adatvédelmi szabályzatban olvashatsz. Megértettem