Fórum témák

» Több friss téma
Fórum » PIC programozása C nyelven, C-Compiler
Lapozás: OK   123 / 153
(#) ktamas66 válasza c27 hozzászólására (») Márc 11, 2016 /
 
Ha azt szeretnéd, hogy max. 50% legyen még egy tolás kell a végére (nem 4-gyel, hanem 8-cal osztani.
Nem tudom mit hajt a H-híd ( táphoz kicsit alacsony a freki, motorhoz minek a frekit variálni), de lehet a híd vezérlés nem szereti a 0 vagy 100% kitöltést (főleg a bootstrap meghajtás).
Az első ábra nem komplementer kimenet.
A hozzászólás módosítva: Márc 11, 2016
(#) c27 válasza ktamas66 hozzászólására (») Márc 11, 2016 /
 
Így működik:

PDC1=PTPER*2;
PDC1=PDC1*255/255;

Így már nem:
PTPER*255
PDC1*2/255
Lehet mégis valami túlcsordulás a baja. (Ismét így írom, mert a másik adc-t még nem indítottam el.)
Kipróbálom a te verziódat is.

Foxié nem fordult le.
void szoroz(unsigned int*,unsigned char*,unsigned int*); sorral van probléma, de egyelőre megpróbálom asm betét nélkül.

Egyébként most találtam egy ilyen példát:
k = (i*j,PROD);
Így kéne használni a hardveres szorzást?
A hozzászólás módosítva: Márc 11, 2016
(#) Wezuv válasza c27 hozzászólására (») Márc 11, 2016 /
 
Használj segéd változókat, nézd meg a köztes eredményeket. Próbáld úgy szervezni a műveleteket, hogy nagy szamokban ossz kicsiket(azaz először szorozz, utána osszd el az eredményt), valamint ha két 8bites számot szorzol, mindenképpen 16bites változóba tedd az eredményt. Ha nem számítasz neagtív számokra, akkor unsigned változókat használj, ha igen, akkor dupláznik kell a bitszélességet, hogy ugyanakkora számok beleférjenek mindkét irányba...
A hozzászólás módosítva: Márc 11, 2016
(#) c27 válasza Wezuv hozzászólására (») Márc 11, 2016 /
 
A PDC1 ráadásul 24 bites változó szóval még így is mennie kéne short long típusú, de mintha levágná az elejét amikor egy sorba írom, vagy ahogy hibásan csinálja 2 sorban.
Közbe a hsz végére írtam egy kiegészítést szorzás után (....,PROD) erről valami vélemény?
Amúgy kösz a segítséget, majd délután még kipróbálom 2 adc-vel és megnézem hogy akkor így működik e, illetve kicsit rendszerezem majd a programot. Eddig mindig csak egy részt írtam meg és amikor működött kezdtem egy üreset az egyesítéssel még lehetne problémák.
A hozzászólás módosítva: Márc 11, 2016
(#) don_peter hozzászólása Márc 11, 2016 /
 
Srácok a while() és a for() ciklus közt van sebesség különbség?
Vagy ez nem lehet számot tevő?
Nagyméretű fájlok adatfeldolgozásánál mindenképp szükségem van ciklusra, de nem tudom melyik lehet a jobb választás.
Előre is köszi.
(#) Wezuv válasza c27 hozzászólására (») Márc 11, 2016 /
 
Ha short long, akkor pozitív irányban 12 bited van, abba nem fér bele két nyolc bites egész szorzata nagyobb számok esetén.
(#) Wezuv válasza don_peter hozzászólására (») Márc 11, 2016 /
 
Attól függ, milyen módon használod. Ha a while-be csak egy feltételt vizsgálsz, ami hatására belép, vagy kilép és ezt a feltételt a cikluson belül teljesíted, akkor gyorsabb lehet, maga a ciklus.
(#) don_peter válasza don_peter hozzászólására (») Márc 11, 2016 /
 
Közben emlékeztem, hogy egyszer már mondtátok, hol nézzem meg mire fordítja a fordító.
Megnéztem a Disassembly Listing-et és kiderült, hogy a for() ciklus 25 a while() 8 utasítással oldja meg a feltételt.
Szóval ezzel meg is válaszoltam, hogy a while() sokkal gyorsabb.
Köszi srácok.

  1. WordDataTemp = Buffer[i];
  2. i++;
  3. WordDataTemp = (WordDataTemp<<8) | Buffer[i];

Uraim a fent belinkelt kódot fel tudnám írni egyszerűbb hatékonyabb alakba?
Buffer csak 8bit lehet és WordDataTemp pedig 16bit-es.
A hozzászólás módosítva: Márc 11, 2016
(#) Wezuv válasza don_peter hozzászólására (») Márc 11, 2016 / 1
 
While-ben is tudsz olyan feltételt írni, ami meg egyezik a for-al, akkor nem gyorsabb...
A sebesség nem attól függ, hogy mennyi sorból oldja meg a fordító a feladatot, hanem attól, hogy egy adott feltétel esetén a szál milyen gyorsan fut le. Nem az összes sor fut le az eltérő feltételek teljesülése esetén.

Szemnek egyszerűbb, hattékonyabbnak nem valószínű...
  1. WordDataTemp = Buffer[i++];
  2. WordDataTemp = (WordDataTemp<<8) | Buffer[i];
A hozzászólás módosítva: Márc 11, 2016
(#) don_peter válasza Wezuv hozzászólására (») Márc 11, 2016 /
 
Igen ez csak szép, de azért javít 2 utasításnyi időt.
Nagy adat mozgatásánál ez is számít.
Köszi.
(#) Wezuv válasza don_peter hozzászólására (») Márc 11, 2016 /
 
Valóságban csak a C sorok lesznek kevesebbek, gyanítom, hogy ugyanarra fordul, de lehet, hogy nem!
(#) c27 válasza Wezuv hozzászólására (») Márc 11, 2016 /
 
Bocs lehagytam, hogy unsigned short longot használok.
(#) Hp41C válasza Wezuv hozzászólására (») Márc 11, 2016 /
 
Sajnos nem! A C18
for(statement1; statament2; statement3
{
cycle?statement;
}
utasítást így fordítja:
statement1; goto ide1;
ide;
if (statement2) goto ide2;
ide3:
statement3; goto ide;
ide1:
cycle_statement;
goto ide3;
ide2:

Az alábbit pedig így:
do
{
cycle_statement;
}while (statement1)
utasítást így fordítja:
ide:
cycle_statement;
if (statement1) goto ide;

Ebből az hámozható ki, hogy az utasításokat a fordítás sorrendjében teszi le a memóriába, a for -nál 3, a while().. esetén 2, a do while() esetén egy ugrást helyez el a kódban. Az első kettőben a feltétel a ciklus lefutása előtt kiértékelődik, a harmadiknál csak a ciklus lefutása után.
(#) foxi63 válasza c27 hozzászólására (») Márc 11, 2016 /
 
Szia!
Valószínű hogy a te fordítód már a dekralálásnál is kéri a változó nevet..
tehát:
void szoroz(unsigned int*_arg1,unsigned char*_arg2,unsigned int*_result);
(#) Wezuv válasza Hp41C hozzászólására (») Márc 11, 2016 /
 
Ezt nem a ciklusoshoz írtam, hanem don_peter optikai tuningjához.
De nem gondoltam, hogy ekkora eltéréssel fordítja a két hasonló ciklus utasítást.
(#) usane hozzászólása Márc 11, 2016 /
 
Sziasztok!

SFR regisztereket tömbbe tudom valahogy (egyszerűen) rakni?
Konkrétan most az OC modulok regisztereit szeretném 1-6ig egy 6 elemű tömbbe tenni.
pl: OCH[] = {OC1R, OC2R.... }
Persze ez a példa csak elmélet, de azt szeretném elérni, ha adok egy értéket az OCH[x] elemnek akkor azt írja be a megfelelő SFR-be. Nyilván erre a 6 elemre nem kerül sokba #define -al megírni, de ezt majd többféle SFR-re át szeretném örökíteni és jó lenne ha ki tudnám kerülni az egyenkénti definiálást.
(#) c27 hozzászólása Márc 11, 2016 /
 
Még lenne már egy utolsó kérdésem:
Szóval van ez a változó 0-255 között átkonvertáltam 0-100 közé, mert ki kéne írni az lcd-re a frekvenciát ahol jár. Annyira nem szükséges hajszál pontosan, de mivel 1-5kHz között jó lenne 2 tizedes jegyet kiírni és számítással biztos nem fogom megcsinálni ezért arra gondoltam, hogy letárolom egy 100 elemű táblázatban az értékeket. (Ezért is konvertáltam át 0-100 közé, bár így pont 101 elemű tömb kell.)
A lényeg, hogy le kéne tárolni egy tömbbe ilyen számokat pl: 4,81 3,54 stb és kiíratni az lcd kijelzőre. Hogy is lehetne ezt megoldani a lehető legegyszerűbben?
unsigned char tomb[]=(5, 4.81, 4.5, ...); Így meg lehet valahogy? Még nem próbáltam ki, de van egy olyan érzésem nem lesz jó az lcd-re íráskor lesznek még galibák. Ezt a tömböt a romba tárolja?


Kösz, foxi, de most őszintén megvallva már 300 sor fölött járok ezért nem akarom ezzel is növelni a sorok számát. Így is kezdek elveszni benne. De azért tényleg köszönöm, hogy fáradtál vele és megírtad, azért lementem, lehet máskor még szükségem lesz rá.
(#) Bakman válasza c27 hozzászólására (») Márc 11, 2016 /
 
Számolni könnyebb és célravezetőbb is lehet. Egyész számokat használj, majd a végén kiírásnál a megfelelő helyre szúrd be a tizedesvesszőt és készen is vagy.
(#) foxi63 válasza c27 hozzászólására (») Márc 11, 2016 /
 
Szia!
Legalább volt egy kis feladat...
A tömböt const rom char tipus esetén tárolja a programmemóriában.
A hozzászólás módosítva: Márc 11, 2016
(#) c27 válasza Bakman hozzászólására (») Márc 11, 2016 /
 
Számolás esetén ismét 2 hiba van.
ismét egy 0-255 közötti változót kellene szorozni 400-al. unsigned int kiesett maradt az unsigned short long. És most jöt az érdekes dolog, nem tudom kiíratni az lcd-re. Minden hülyeséget ír ki csak nem azt amit kéne.
Annyira leszűkítettem a hibát, hogy pl beírom egy változóba =500 és 100-at ír ki, ha átírom az adattípust unsigned intre ugyan ebben az esetben kiírja az 500-at.
A printf("%d",valt); formában van. Esetleg a "%d"-nek van baja?
A másik hiba, hogy ha 100-500 között vannak az értékek nekem be kéne szúrnom egy pontot az első számjegy után. Azt hogy tehetem meg?
A hozzászólás módosítva: Márc 11, 2016
(#) c27 válasza c27 hozzászólására (») Márc 11, 2016 /
 
Jó az első problémát megoldottam, kell egy típuskényszerítés. A pont beszúrása már kicsit nehezebb. Esetleg tehetném a számjegy elé és akkor 0.100 Mhz lesz, de ez csak a végső megoldás szebb lenne az 1.00kHz.
Ötletek?
(#) killbill válasza c27 hozzászólására (») Márc 12, 2016 /
 
A %d int parametert var, annak nem adhatsz at annal nagyobb tipust.
Ha longot akarsz kiiratni, akkor %ld kell. A short long az nem szabvany C, ehhez nem tudom, hogy mi kell.

printf("%d %ld" ", int, long);
(#) c27 válasza killbill hozzászólására (») Márc 12, 2016 /
 
Mindegy a típuskényszerítéssel is működött, mert a végén úgy is csak 8 bites lesz.
Amúgy valószínűleg mégis át kell térni a tömbös megoldásra. A tizedespont miatt is és a PTPER értéke miatt szintén. Nem vettem figyelembe, hogy a 250-1270 között változó érték ami 5-1kHz-nek felel meg az adc (0-255) értékének átalakításai után, nem lesz lineáris a frekvencia léptetése. ahogy csökken a frekvencia és nő a PTPER értéke úgy lesz egyre inkább kisebb a léptetés, amíg 5khz közelében nagyobb lépések vannak. Ha PTPER 250 ->5kHz adc 0, ha PTPER 500 ->2,5kHz adc 62. Úgy kéne hogy 127-nél lenne a 3KHz az 1-5kHz középértéke, és ezt számolós módon nem lehet megoldani, legalább is egyszerű számításokkal nem.
(#) Lamprologus válasza c27 hozzászólására (») Márc 12, 2016 /
 
A tizedespontot is ki lehet iratni:
  1. printf(lcd_putc,"TEMP: %3.1wßC ", Homerseklet);

Az első számjegy (3) a teljes hossz, a második (1) a tizedesjegyek száma.
Legalábbis CCS-C -ben így működik ...
(#) c27 válasza Lamprologus hozzászólására (») Márc 12, 2016 /
 
Nálam kicsit bonyolultabb a helyzet. Az értékek 100-500 között és az első számjegy után kéne egy pontot beszúrni.
(#) benjami válasza c27 hozzászólására (») Márc 12, 2016 /
 
Én ilyesmihez egész számokat használok, a tervezésben pedig visszafelé szoktam elindulni. Mi az a legnagyobb érték amit ki akarok íratni (ha két tizedes is kell akkor az értéket százzal felszorzom)? A megjeleníteni kívánt legnagyobb értéket elkezdem szorozni a kettő hatványaival. Amikor még éppen beleférek a számítások során használt 16, 32 vagy 64 bitbe akkor megállok. Az így kapott szorzóm lesz majd a képletembe az osztó, és mivel csak a 2 egész hatványával kell osztanom, ez csak bittologatást fog majd jelenteni. A szorzatot (ami még pont belefért a 16, 32 vagy 64 bitbe) pedig elosztom az adatforrás legnagyobb értékével. A kapott hányados lesz a szorzóm.
Ezt az egészet legegyszerűbb excel-ben (vagy hasonlóban) kisakkozni (lásd a mellékletben).
(#) Lamprologus válasza c27 hozzászólására (») Márc 12, 2016 /
 
Akkor %3.2 mivel 2 tizedest akarsz megjeleníteni!
(#) Kovidivi válasza Lamprologus hozzászólására (») Márc 12, 2016 /
 
Talán egyszerűbb lenne egy sima fv.-t használni, ami mindig csak 1 karaktert ír az LCD-re, gotoxy() -vel együtt, amivel a pozíciót lehetne beállítani. Így azt ír ki az ember, amit akar, számonként, betűnként (vagyis karakterenként). Ehhez kell egy másik fv., ami hosszabb szövegeket, és egész számokat is kiír, de ezek már készen vannak valószínűleg, csak meg kellene találni. A printf is jó, de csak ha tudja az ember használni.
(#) c27 válasza Lamprologus hozzászólására (») Márc 12, 2016 /
 
Nem próbáltam ki, de én úgy értelmezném ezt a %3.2, hogy ha 500-as értéken van akkor ezt írja ki: 500.00 míg nekem 500-as érték az 5.00-t jelent azaz a 100x értékek vannak letárolva.
De lehet hogy én tévedek, nem próbáltam még ki ezt a módszert.

Közbe egy újabb kérdésem merült fel:
unsigned char POT1;
unsigned char POT_1;
...
POT1 = ADRESH;
POT_1=POT1*100/255;
...
printf("%d", POT_1);

Van ez a programrészlet és az a bajom vele, hogy nem hajlandó kiírni az LCD-re a POT_1 értékét, kivéve ha a POT1 unsinged int típusú változó, akkor jó. Ha a pl. átírom a sort erre POT_1=300; akkor normálisan megcsinálja. A POT1 az adc felső 8 bitjét kapja meg 0-255 között. Ha megszorzom 100 majd osztom 255-tel 0-100 közötti érték lesz. Nem tudom miért kellene a POT1 változónak int-nek lennie amikor 8 biten vígan elfér, mialatt a POT_1 a szorzás miatt 15 bites lesz, az osztás után pedig 7 bites.
A hozzászólás módosítva: Márc 12, 2016
(#) Lamprologus válasza c27 hozzászólására (») Márc 12, 2016 /
 
A második szám azt jelenti, hogy hány tizedes jegyet jelenít meg. (w az unsigned int típus.)

  1. int homerseklet=543;
  2. printf(lcd_putc,"Temp: %3.1wßC ", Homerseklet);


LCD megjelenő szöveg:

Temp: 54.3°C
Következő: »»   123 / 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