Fórum témák
» Több friss téma |
A fenti kód bitenként 5 utasításciklus. Hogy mennyit gyorsul nem tudom, próbáld ki. Mindenesetre nincs benne ciklus és shiftelés.
Értem, megnézem majd, mit művel vele.
Köszi előre is. for() ciklusos megoldás egyébként több utasításra jön ki? Vagy a függvényhívás miatt problémás lehet a dolog? Nem tudom tesztelni, mert a debug lefagy futás közben, valamiért. (majd utána kell néznem miért)
Köszönöm, ez tovább növelte a sebességet.
Nyilván itt már vagy 50%-ot jelentett az is, hogy most már 16bit-ben tolja az adatokat, de gondolom azért az az 5utasítás/bit is tolt rajta nem keveset. Most egy 16e-s címet alig 2 másodperc alatt léptet végig. Egy 1MB-os címzést az eddigi 6perc helyett most kevesebb mint a fele idő alatt léptet végig, 6kb-os átviteli sebességet elérve ezzel. Ez már szerintem azért nem olyan rossz ![]() Kösz mindenkinek a segítséget. Nem sokára összedobok egy leírást mi is ez amin dolgozok.. A hozzászólás módosítva: Feb 26, 2016
Üdv!
Lehet, hogy hülyeséget kérdezek. Elképzelhető e, hogy egy PIC 32 -ből kiolvassuk a programot? Az ic sérült. Köszönöm
Sziasztok!
C18-as fordítóhoz kérnék egy kis segítséget. LCD-re akarok szöveget írni, de nem akarom használni a betölthető xlcd-t, hanem saját függvényekkel akarom. Addig jutottam, hogy ha egy karaktertömbbe beteszem a szövegemet ki is írja az lcd-re, de 8-10 soros szövegnél nem akarok annyi tömböt létrehozni. Milyen más lehetőségek vannak? Próbáltam így: lcd_display("xy"); az lcd_display fv-nek átadni a szövetet, de ha nem teszem tömbbe nem működik (bár lefordítja). Csak így működik: char words1[]="xy"; lcd_display(words1); Egy pointerrel meg végigmegyek a tömb elemein: void lcd_display(char *disp){ int x=0; while(disp[x]!=0){ lcd_data(disp[x]); x++; } } ........ Szóval valami hatékonyabb módszer, beépített lcd függvények nélkül?
Tartok tole, hogy a "xy" az (const rom char *) tipus, az lcd_display() meg sima (char *) tipust var. Ha a fuggvenyt atirod igy:
akkor elvileg a "text" kiiras menni fog, de a hagyomanyos tomb, ami RAM-ban van, az nem.
Szimulációba működik úgy is ahogy írtam, csak kell egy tömböt definiálni, amit el akartam kerülni. Bár gondlom a c18 xlcd könyvtára is hasonlóan működhet.
Közbe megoldottam printf-el, csak az időzítést kell még belőni. Mennyi az a legkisebb biztonságos idő, amivel még elmegy az lcd(hd44780) (parancsra és az enable-re külön-külön)?
A hozzászólás módosítva: Feb 27, 2016
Nem maga a tomb a lenyeg, hanem az, hogy a tombod RAM-ban van, a sima szoveg meg ROM-ban. A C18 fordito pedig a szabvany C-tol elteroen ezt a kettot ilyen hulyen kezeli.
Az en fuggvenyemben nem az a lenyeg, hogy ket sorban csinalja azt, amit a tied 4-ben egy felesleges valtozoval, hanem az, hogy a bemeneti valtozo tipusa const rom char *.
Hali!
Kijelzője válogatja, van amelyik gyorsabb, van amelyik lassabb, gyártófüggő
Ha úgy csinálom ahogy írtad és const rom char ként kapja meg az s pointer akkor hülyeségeket ír ki. Ha kiveszem a const rom-ot akkor normálisan megy.
De azt nem értem hogy kerül sima szöveg a romba, mert én létrehozok egy tömböt aminek az elemei a szöveg karakterei. Egyébként most így csinálom (még csak bohóckodás szintjén vagyok): stdout=_H_USER; int i=10; printf("%d óra van", i); Delay10KTCYx(250); lcd_write_command(0xC0); printf("...."); A késleltetést még be kell lőnöm. A hozzászólás módosítva: Feb 27, 2016
Idézet: Akkor is, ha azt adod at neki, hogy lcd_display("ird ki!"); ? „Ha úgy csinálom ahogy írtad és const rom char ként kapja meg az s pointer akkor hülyeségeket ír ki.” A hozzászólás módosítva: Feb 28, 2016
Így már tényleg jó, kösz!
Már csak az a kérdés melyiket használjam, bár gondolom ez gyorsabb mint a printf-es változat. Most már értem mire akartál kilyukadni, ezzel a romba kerüléses dologgal. A hozzászólás módosítva: Feb 28, 2016
Kipróbáltam néhány variációt a C18 fordítóval:
WREG = WREG; // Optimalizálás meghagyja, 2 utasítás végrehajtásnyi idő WREG = WREG + WREG; // Optimalizálás meghagyja, 3 utasítás végrehajtásnyi idő stb. A fordítás körülményeitől függően 6 vagy 7 utasítás végrehajtásnyi idő:
Továbbgondolva a mydelay(void) már tartalmazhat assembly utasításokat, hiszen csak ezt a rövid függvényt nem optimalizálja. A hozzászólás módosítva: Feb 28, 2016
Még egy olyan kérdésem lenne, hogy ha egy változó értékét akarom kiírni ezzel a módszerrel azt hogy tudom megtenni? Printf-nél egyszerű, de így nem sikerült. Próbáltam unsigned intre változtatni a függvények változóit, de így sem megy, vagy próbáltam egyből a portra kitenni (közbe félbájtra bontogat egy függvény, mert 4 bites üzemmódban menne), de úgy sem sikerült.
Ezzel a modszerrel sehogy, mert ez a modszer csak a a rom-ban levo szoveget tudja kiirni. Maradj a printf-nel...
Értem, valahogy sejtettem.
Közbe az adc-t is próbálgattam volna, csak nem sikerült biztos a confignál néztem el valamit, de nem is minden teljesen egyértelmű az adatlapban. PORTA=0; TRISA=0X03; ANSEL0 = 0b00000011; //AN0, AN1 ANALOG OTHERS DIGITAL ANSEL1 = 0X00; ADCON0 = 0X00; //SINGLE CHANNEL ADCON1 = 0X00; ADCON2 = 0b00110010; //32Tosc 6TAD ADCON3 = 0b11000000; //ADC INTERRUPT DISABLED .... Közbe figyeli a nyomógombot és ha meg van nyomva akkor ezt végrehajtja: ADCHS = 0b11111100; //AN0 SELECTED ADCON0bits.ADON = 1; //ADC ENEABLE Delay1KTCYx(1); ADCON0bits.GODONE = 1; //ADC START while(ADCON0bits.GODONE); POT1 = ADRESH; ADCON0bits.ADON = 0; Majd kiírná a D portba az eredményt (elég a felső 8 bit). Lefordulni lefordul, csak az ADRESH szerintem mindig 0, mert valamit nagyon elrontottam, de eddig nem jöttem rá mit. Próbáltam az adc.h betöltésével így: OpenADC(ADC_FOSC_32 & ADC_6_TAD & ADC_INT_OFF); Delay10TCYx(5); SetChanADC( ADC_CH0 ); ConvertADC(); while ( BusyADC() ); POT1=ReadADC(); CloseADC(); Ha kiveszem s SetChanADC-t akkor is hibát ír ki a fordító, persze azt nem hogy mi a hiba. Egyébként nem ragaszkodnék az adc.h könyvtárhoz, csak elég kellemetlen hogy egyiket sem tudom működésre bírni. A hozzászólás módosítva: Feb 29, 2016
Ehhez nem nagyon tudok hozzaszolni, mert a PIC-eket ilyen melysegig nem ismerem. Azt azert jo ha tudod, hogy a *.h file az header es nem konyvtar. A konyvtar az elore megirt es mar leforditott fuggvenyek gyujtemenye, ami linkeleskor lesz a programodhoz hozzacsatolva. A .h meg csak C forraskodot tartalmaz.
Ok, egyébként már sejtem miért nem ment az adc.h header. A beállítások kissé kiesen vannak leírva abban a pdf-ben amit eddig néztem, de most találtam egy bővített verziót, elég rosszul adtam meg neki a beállításokat. Amiatt eleve nem mehetett, remélem más hiba nem lesz.
A hozzászólás módosítva: Feb 29, 2016
Sikerült megoldanom már megy az adc szépen, legalább is szimulációban. Jól megszenvedtem vele.
![]() A hozzászólás módosítva: Feb 29, 2016
Sikerült ismét elakadnom, esetleg abban tudsz segíteni, hogyan is kell kezelni az interruptot c18 fordítóval? Nézegettem a fordító leírást, de egy rövidke példa van amikor bemutatja a 2 szintű megszakítást. Nekem nincs szükségem rá, az alapbeállítással próbáltam, de nem működik. A normál interrupt szintaktikájáról nem igazán ír sokat.
Ugyanaz, mint a kétszintű, csak a magas prioritású rutin kezel le mindent. Ugyanúgy is kell megadni emlékeim szerint, mert az alacsony prioritásúnál kell jelölni, hogy ez most az alacsony prioritású rutin.
Ezek kellene, hogy be legyenek állítva, hogy legyen megszakítás: a konkrét periféria megszakítás engedélyező bitje = 1 INTCON.PEIE = 1 INTCON.GIE = 1 Esetleg kimaradt a PEIE?
Nézd meg pl. a 18F242 adatlapjában (DS39564C) a Figure 8.1 -et és a PICkit2 firmware forrását.
A hozzászólás módosítva: Márc 1, 2016
Sajnos nem potyo, de hossza nézegetés után addig állítgattam, hogy most elvileg megy, de azért bemásolom a config egy részletét, hátha csak a véletlen műve:
... #define TROUT2 LATDbits.LATD5 //TRANZISTOR OUTPUT2 RD5 void Timer_ISR(void); #pragma code vector=0x08 void vector08(void){ _asm goto Timer_ISR _endasm } #pragma code #pragma interrupt Timer_ISR void Timer_ISR(void){ LATCbits.LATC5=LED1; INTCONbits.TMR0IF = 0; T0CONbits.TMR0ON=0; TMR0H=0b10011000;//40MHz clock 40/4*10^6*128*39062=0,33sec TMR0L=0b10010110; T0CONbits.TMR0ON=1; } //ADC-PORTA INITIAL INI_PORTS(){ ... A megszakítás configja így jó? Elvileg az alap regisztereket wreg, stb automatikusan menti.
Egy gyors kérdés: a tmr0on bit ki-be kapcsolása nullázza az éppen aktuális értékét a számlálónak vagy onnan folyatja ahol abbamaradt?
Nem találtam konkrét utalást erre így azt gondolnám onnan folytatja ahol abbahagyta.
Elvileg onnan (valóban nincs utalás rá), de miért nem próbálod ki?
Kipróbáltam úgy tűnik onnan folytatja.
Még két problémám lenne mára. Az egyik, hogy az adc-ből beolvasok két változóba az ADRESH-t (AN0, AN1-ről) ami két 8 bites szám lesz(0-255), de szeretném átkonvertálni tetszőleges tartományba pl.: 0-100 vagy 10-200. Ezt hogy lehet megtenni? A másik problémám, hogy az adc-ben beolvasott és átkonvertált értéket ki is szeretném írni egy lcd kijelzőre. Eddig úgy oldottam meg, hogy kiír egy szövet utána pedig az értéket, de későbbiekben már csak az értéket írja ki pl az 0A címtől kezdve, viszont ha kiír pl 127-et majd 0-t kéne akkor a 0A címtől kiírja a nullát de a 27 ott marad a 0 után. Törölni nem akarom a kijelzőt mert újra be kéne írnia szöveget ráadásul kb, 0,3 mp-ként frissíti a szám értékét (már ha változott), így nincs is túl sok idő 2 sorba írogatni a szövet. Megoldás, javaslat? Olyat lehet hogy csak egy adott címtartományt törlök? Még csak futólagosan néztem bele a hd44780 adatlapjába így nem is találtam semmi hasznosat. A hozzászólás módosítva: Márc 2, 2016
Idézet: „Az egyik, hogy az adc-ből beolvasok két változóba az ADRESH-t (AN0, AN1-ről) ami két 8 bites szám lesz(0-255), de szeretném átkonvertálni tetszőleges tartományba pl.: 0-100 vagy 10-200. Ezt hogy lehet megtenni?” Legegyszerűbb egy 256 elemű táblázattal / tömbbel C-ben /, ahol a bemeneti értékhez hozzárendeled a kiírandó számot ![]() Egyébként "matekolással" ! A kijelzőnél, ha 3 karakterhez tartozó adatot kell frissítgetni, akkor a nem használt helyet is felül kell írni pl. a Te példád szerint "0 "-t kiküldeni ( azaz lehet egy adott pozíciótól kezdődően tetszőleges számú adatot kiküldeni!)! A hozzászólás módosítva: Márc 2, 2016
Pl. bejövő érték (x) 0-255, kimenőt (y) szeretnéd 0-100 -ig: y=(x * 100)/255.
LCD: Kiírod a nullát, majd két szóközt. Ha az eredmény kétjegyű, akkor csak egy szóköz kell, ha háromjegyű, egy sem.
És hogy tudom, hogy az eredmény hány jegyű? Mert az érték 0-255 között változik a poti helyzetétől vagy van hozzá valami vizsgáló függvény?
A map utasítás gondolom nem működik c18-nál. |
Bejelentkezés
Hirdetés |