Zdravim Vas, mam jeden problem s vypoctom percentualneho podielu pomocou jedneho PICka. Uvediem priklad:
unsigned int A = 10000;
unsigned int B = 10000 * 0.5;
V tomto pripade bude mat premenna B hodnotu 5000. Samozrejme keby som pouzil ako nasobiacu konstantu cislo s vacsim poctom desatinnych miest tak sa vysledok zaokruhli co mi vobec nevadi. Problem je v tom ze pouzivam float premennu a stava sa mi ze mi raz za cas pride chybny vysledok. Ked natvrdo napisem ze B = 5000, alebo B = A - 5000 tak vsetko slape ako ma, problem je ak pouzijem konstantu float, comu by som tiez chapal nakolko MCU ma omnoho viac prace s vypoctom a nemusi to stihnut. Potreboval by som nejako nakopnut s tym, ze ako dokazem vypocitat percentualny podiel z premennej bez toho, aby som pouzil float hodnotu. Uz nad tym sedim moc dlho tak mi nenadavajte ak je to moc jednoduche
Dakujem vam
Takhle Ti asi moc neporadím - ukaž ten kód.
No a bez float to jde. Záleží samozřejmě na absolutním rozsahu operandů, ale většinou se vejdeš buď do stejného typu nebo o jeden typ výše. Vynásob číslo ze kterého chceš spočítat procenta třeba 1000 a proveď výpočet. Výsledek “procent” tak získáš na 3 des. místa.
Vacsinou je pouzitie float uplne zbytocne. Jednosucho staci cisla pouzivat vynasobene na pozadovanu presnost. Napriklad prud z cidiel psracovavam v uA a nie v mA na tri desatinne cisla vo forme float.
Ako presne to myslite? Uvedte nejaky priklad.
Ja som to robil nasledovne:
int A = 10000; //Namerana hodnota
int B = 80; //Pozadovane percenta
int C = (A * B) / 100; Vysledok v percentach
Problem je v tom ze stale to nechodi dobre. Neviem presne co sa deje ale pripada mi to akoby MCU nepocital spravne. Vysledok je uplna blbost, ak ale zapisem (A * B) / 100UL tak vysledok je spravny ale zasa mam problem s tym ze sem tam hodi zly vysledok. Skuste popisat ako to myslite vy. Dakujem Vam
80 * 1000 je 80000 a to je predsa viac ako 32767. MCU vysledok jednoducho zarovna na dany typ a je to. Musite si konrolovat velkost cisel.
da sa to spravit nasledovne bez float
#define DELACA_KONSTATNA 100 // 100L moze byt pozadovane, aby prekladac vedel, ze konstatna bude pouzita pre vacsie cislo ako je bajtovy rozsah konstatny
int16_t a, b, v;
// medzivysledok sa spracovava v 32b integeri, co je vypoctovo daleko menej narocne ako vo floate.
int32_t c;
a = 1000;
b = 80;
// premenne treba dosledne pretypovavat
c = (int32_t) a * (int32_t) b / 100;
// kontrola, ci vysledok nahodou nie je vacsi ako 16bit integer
if (c > INT16_MAX) c = INT16_MAX;
// premenne treba dosledne pretypovavat
v = (uint16_t) c;
pouzitie desatin v ramci integeru sa robi sposobom pevnej desatinnej ciarky a nie pohyblivej ako je to vo float. Jednoducho sa dohodnem, ze cislo 16234 znamena 162.34 a cislo 7589 znamena 75.89.
Zdravim Vas, ano viem ze s tym int-om som napisal blbost, pisal som to ako priklad a neuvedomil som si to tak sa ospravedlnujem. No ale aj napriek tomu to nechodilo dostatocne rychlo ale problem som uz vyriesil inak a slape to, samozrejme ale dakujem za pomoc. Mal by som ale este jednu otazku:
Potrebujem pripojit na port paralelny d/a prevodnik a teda potrebujem 8 pinov, len ide o to ze piny ktore mozem pouzit su rozne. Potreboval by som vytvorit nieco ako pole kde kazdy prvok bude nazov portu v mnou zadanom poradi a tento prvok bude predstavovat 8bit premennu. Uvediem priklad:
unsigned int pole[3] = {LATAbits.LATA0, LATAbits.LATA1, LATAbits.LATA3};
pole = 0b1111; //vsetky vystupy budu v log.1
pole = 0b010; //PA1 bude v log.1 a ostatne v log 0
...atd
Neberte to ako spravne zadanie, je to len priklad no neviem akoby som to mohol takto rozdelit aby som s tym mohol pracovat ako s jednou premennou. Dakujem Vam za pomoc
Ospravedlnujem sa, skusim to inak. Mam A/D prevodnik ktory mam pripojeny k MCU nasledovne:
D0 -> PORTA.0
D1 -> PORTA.1
D2 -> PORTA.2
D3 -> PORTB.2
D4 -> PORTB.3
D5 -> PORTB.4
D6 -> PORTB.5
D7 -> PORTB.7
Chcel by som vediet ako ‘‘zlucim’’ tieto vystupne porty do jednej, povedzme premennej, aby som mohol zapisovat na tieto porty cez tu danu premennu. Napriklad zapisem do premennej hodnotu 255 a cez nu sa nastavia vsetky porty do log.1 a pod. Pripadne ako by ste Vy riesili zapis hodnoty na tento prevodnik. Keby som mal AVRko tak by som si cely prevodnik hodil na jedne port a ked zapisem na tento port hodnotu tak ono si to automaticky porozdeluje lebo pracujem s celym portom naraz lenze teraz mam niektore vystupy na jednom a dalsie na inom porte. Snad som sa uz vyjadril spravne, ale samozrejme chapem ze cez net sa tazko nieco vysvetluje a este tazsie potom chape. Dakujem Vam
Buď jak píše Milo a nebo dvě konverzní tabulky pro rychlý přístup a pak 2x read-modify-write operace. Všechno záleží na tom jak rychle potřebuješ hrnout data ven a taky nezapomeň, že pokud nemá ten převodník triger, tak obě výše popsané metody vyprodukují na výstupu D/A glitche.
Zeptám se blbě, ale taky se C teprv učím, tak mi to kdyžtak snad odpustíte… a nešlo by vytvořit něco jako bitová struktura (resp. ona by vytvořit asi šla, ale - fungovalo by to)?
Možná jsem to blbě pojmenoval - myslím tím takový ten vstup STR (jako strobe). Obvod převezmě data na hranu/nebo úroveň a v ten moment provede konverzi. Píšu to proto, že nevím co tam bude mít za D/A. Třeba taková R2R je úplně bez inteligence )