Fórum témák

» Több friss téma
Fórum » PIC programozása C nyelven, C-Compiler
Lapozás: OK   60 / 153
(#) lokátoros válasza Amarton hozzászólására (») Aug 16, 2012 /
 
Vagy lebegőpontos konstansokkal, és akkor automatikus a castolás:
tps_value = tps_ad_value * 100.0 / 1024.0;
(#) trudnai válasza Amarton hozzászólására (») Aug 17, 2012 /
 
Azt gyanitom, hogy az optimalizalas viccel meg Teged, ugyanis a szorzas es osztas azonos precedenciaval rendelkezik, annak (ill annak a resznek) jonak kell lennie!

Itt egy pelda, leforditottam gcc-vel a peldadat O3 -as optimalizacioval. Ha jol megnezed, akkor a printf jol irja ki az eredmenyt, megis 0 a tmp_float valtozod erteke -- A fordito ugy dontott nem kell az erteket a valtozoba vissza irnia mivel ugyis csak egy helyen hasznalom fel...

  1. Breakpoint 1, main () at testdef.c:15
  2. 15    tmp_float = (float)tps_value / tps_lepeskoz;  
  3. (gdb) p tmp_float
  4. $1 = 0
  5. (gdb) n
  6. 16    printf("hello %f\n", tmp_float);
  7. (gdb) p tmp_float
  8. $2 = 0
  9. (gdb) n
  10. hello 5.800000
  11. (gdb) p tmp_float
  12. $3 = 0
  13. (gdb) q

Megjegyzes: a tps_value-t elobb float-ta castolom, hogy utana az osztasnal a maradekot mar ne veszitse el... Amugy 5.0000-t irna ki, de az sem nulla!

UI: PIC32 is gcc alapu forditot hasznal, ugyhogy ezert mertem sima gcc-vel tesztelni a problemat amit felvetettel...

UI2: Azt elfelejtettem irni, hogy termeszetesen -O0 -val, azaz optimalizacio nelkul a valtozo erteket nyomon tudom kovetni a debuggerrel...
(#) lokátoros válasza trudnai hozzászólására (») Aug 17, 2012 /
 
Idézet:
„Azt gyanitom, hogy az optimalizalas viccel meg Teged, ugyanis a szorzas es osztas azonos precedenciaval rendelkezik, annak (ill annak a resznek) jonak kell lennie!”

Ez így van. A konstans kifejezéseket fordítási időben kiértékeli akkor is ha egyébként ki van kapcsolva az optimalizáció.
Továbbá az azonos precedenciájú műveletek esetén a konkrét kiértékelési sorrend implementáció függő, az AnsiC kompatibilis fordítók átrendezhetik ezeket, ezért soha ne bizzunk abban hogy az a = b*c*d; kifejezésből b*c -t értékeli ki először. Ha konkrét kiértékelési sorrendet akarunk előírni bontsuk szét a kifejezést több utasításra, (lsd. fenti hozzászólások).
(#) lokátoros válasza lokátoros hozzászólására (») Aug 17, 2012 /
 
A fentiekhez hasonló csapdák elkerülése érdekében érdemes ebbe beleolvasni:
BME C referencia
(#) _vl_ válasza lokátoros hozzászólására (») Aug 17, 2012 /
 
Részben igazad van, részben nincs.

Az igaz, hogy a kiértékelés sorrendjét szabadon választhatja meg a fordító, de ez csak függényeknél, a ++/-- operátoroknál, valamint az értékadás operátor, mint kifejezés használatakor lényeges, mivel ezeknek műveleteknek vannak "mellékhatásaik". Annyi a következmény, hogy a mellékhatások egymáshoz képesti, ill. az egész kifejezés kiértékeléséhez képesti sorrendje nem definiált.

Abban viszont nincs igazad, hogy az a = b*c*d kifejezést a fordító szabadon "átrajzolhatja" úgy optimalizálás címén, hogy ezzel a kifejezés valódi értéktartományát lecsökkentse. Jelen esetben pl. a *600/1024-at nem helyettesítheti *0-val, mondván hogy előbb az 600/1024-et értékeljük ki integerként, és az nullát ad...
Ilyet semelyik fordító nem tesz.
(#) lokátoros válasza _vl_ hozzászólására (») Aug 17, 2012 /
 
Igazam van, olvasd át légyszíves a mellékelt linkben az 1. megjegyzést.
De be is másolom.
Idézet:
„1. Megjegyzés: a kétoperandusú *, +, &, ^ és az | operátorok asszociatívak. Ha egy kifejezésben azonos szinten több azonos asszociatív operátor szerepel, akkor a fordítónak jogában áll a kiértékelési sorrendet tetszőlegesen megválasztani. Ez - a részkifejezések mellékhatásai miatt - kihathat az eredmény értékére is, ezért kerülendők az olyan kifejezések, amelyek nem definit kiértékelési sorrendtől függenek. Például az a++ + b[a] kifejezésben a b tömb indexe attól függ, hogy az első vagy a második tag kiértékelése történik előbb, azaz az indexeléshez az eredeti vagy a megnövelt a-t használjuk. Ugyanez a helyzet áll fenn a függvényhívások paramétereinél, ugyanis ezek kiértékelése sem kötött sorrendű. Például a fugg(i++, a[i]) gépfüggően választja meg adott i érték mellett az átadandó tömbelemet.”
(#) lokátoros válasza lokátoros hozzászólására (») Aug 17, 2012 /
 
Ami pedig a konstans kifejezések kiértékelését illeti, csak ismételni tudom magam, az a preprocesszor dolga, fordítási időben. Legalábbis C, C++ esetén.
(#) _vl_ válasza lokátoros hozzászólására (») Aug 17, 2012 /
 
Miről beszélsz?
(#) lokátoros válasza _vl_ hozzászólására (») Aug 17, 2012 /
 
Bocs, de nem értem a kérdést.
Gondolom akor az asszociativitás buktatóit már tisztáztuk, ha nekem nem hiszel ott a BME jegyzet, erről nem érdemes tovább vitázni.
(#) lokátoros válasza _vl_ hozzászólására (») Aug 17, 2012 /
 
Azt hiszem értem mire gondolsz.
A felvetett konkrét esetben, tényleg nem a prepocesszor optimalizál, mert kifejezés belsejében van.
Ezt a compiler értékeli ki, és ha észreveszi hogyez egy konstans részkifejezés amit az asszociativitási szabályok alapján kiértékelhet, megteszi. Ez elképzelhető hogy compiler függő. Arra akartam rávilágítani, hogy nem érdemes olyan kódot írni ahol ez a fordítóra van bizva. Ennek elkerülésére az előzőekben több tippet is adtunk.
(#) _vl_ válasza lokátoros hozzászólására (») Aug 17, 2012 /
 
A kérdés arra irányult, hogy honnan veszed, hogy a preprocesszor bármiféle számot/konstans értéket próbálna kiértékelni. Merthogy a preprocesszor kimenetében az összes konstanst meg fogod találni, azokon semmiféle műveletet nem végez. A preprocesszor string behelyettesítést végez csak, nem értelmezi és nem olvasgatja a C kódot. Simán lehet pl. Pascal vagy Basic forrásra is használni...

A BME-s jegyzet ugyan nem fogalmaz elég pontosan, de abból sem jön le az az értelmezés, amit Te bele próbálsz érteni.
Más dolog a részkifejezések kiértékelésének, előállításának sorrendje (ez a mellékhatások miatt lényeges), és más dolog a végeredmény kiszámolása.
A C szabvány asszociatív műveleteknél annyiban engedi meg a végeredmény számolása szempontjából a sorrend felcserélését, amennyiben az nem változtatja meg az eredményt. Ez integer összeadás, kivonás, szorzás esetén gyakorlatilag bármikor igaz, viszont az integer osztásnál már nem.
A dologhoz hozzátartozik, hogy a K&R-féle kváziszabvány elméletileg ezt is megengedte.
(#) lokátoros válasza _vl_ hozzászólására (») Aug 17, 2012 /
 
A prepocesszor kérdését közben megválaszoltam, a konkrét példára valóban nem vonatkozik.
(#) lokátoros válasza _vl_ hozzászólására (») Aug 17, 2012 /
 
Igazad van, ez a / operátorra nem vonatkozik, elnéztem a kifejezést, akkor ez mégis csak valami optimalizálási probléma lehet. Én is a K&R könyvre emlékeztem. Kipróbáltam, a Microchip C30 (v3_31) fordító például jól kezeli, tiéd a pont.
(#) Amarton hozzászólása Aug 17, 2012 /
 
Na sikerült a problémát megoldani.
Köszönöm mindenkinek.
Most már jól számol.

Van valakinek valamilyen képlete a lineáris interpolációra?
Az én változatom egy egy dimenziós tömbnél jól működik, viszont egy 2 dimenziósnál már nem.

  1. tomb[2][2]{
  2.  10,20,
  3.  30,40
  4. }

Például:
Szeretnék visszatérni a tömb x irányban 0,3 és y irányban a 0,6-es értékével.

Egy dimenziósnál így csinálom (x irányban):
0,3 * 30 = 9
(1-0,3) * 10 = 7
Az interpolációs eredményem: 9+7 = 16
(#) Amarton hozzászólása Aug 27, 2012 /
 
PIC32-nél hogyan működnek a megszakítások?

IFSx regiszterben pl. melyik a timer1 flagje?

Valaki le tudná írni a lényegét, mert nekem nagyon zavaros?
(#) Amarton válasza Amarton hozzászólására (») Aug 27, 2012 1 /
 
Ez a PIC32 sem olyan már, mint a régi 8 bitesek.
Letöltöttem a megszakítás fejezetet is, mert az adott PIC adatlapjában csak megemlítik a megszakítást.
Azt tanulmányozva nem találtam meg a kérdésemre a választ.
Ezután újra megnyitottam a PIC32 adatlapját, és ott benne volt, hogy melyik bit is a megszakítás flag.

Ennek ellenére még mindig nem látom át, hogyan is működik a megszakítás.

Még egy egyszerű kérdés.
Hogyan kell ellenőrizni egy adot bitet c-ben?
if(IFS0.4) nem működik.
(#) Stefan válasza Amarton hozzászólására (») Aug 27, 2012 /
 
A header file-t ha megnézed,
  1. typedef union {
  2.   struct {
  3.     unsigned CTIF:1;
  4.     unsigned CS0IF:1;
  5.     unsigned CS1IF:1;
  6.     unsigned INT0IF:1;
  7.     unsigned T1IF:1;
  8.     unsigned IC1IF:1;
  9.     unsigned OC1IF:1;
  10.     unsigned INT1IF:1;
  11.     unsigned T2IF:1;
  12.     unsigned IC2IF:1;
  13.     unsigned OC2IF:1;
  14.     unsigned INT2IF:1;
  15.     unsigned T3IF:1;
  16.     unsigned IC3IF:1;
  17.     unsigned OC3IF:1;
  18.     unsigned INT3IF:1;
  19.     unsigned T4IF:1;
  20.     unsigned IC4IF:1;
  21.     unsigned OC4IF:1;
  22.     unsigned INT4IF:1;
  23.     unsigned T5IF:1;
  24.     unsigned IC5IF:1;
  25.     unsigned OC5IF:1;
  26.     unsigned SPI1EIF:1;
  27.     unsigned SPI1RXIF:1;
  28.     unsigned SPI1TXIF:1;
  29.     unsigned U1EIF:1;
  30.     unsigned U1RXIF:1;
  31.     unsigned U1TXIF:1;
  32.     unsigned I2C1BIF:1;
  33.     unsigned I2C1SIF:1;
  34.     unsigned I2C1MIF:1;
  35.   };
  36.   struct {
  37.     unsigned :26;
  38.     unsigned U1AEIF:1;
  39.     unsigned U1ARXIF:1;
  40.     unsigned U1ATXIF:1;
  41.   };
  42.   struct {
  43.     unsigned :26;
  44.     unsigned SPI3EIF:1;
  45.     unsigned SPI3RXIF:1;
  46.     unsigned SPI3TXIF:1;
  47.   };
  48.   struct {
  49.     unsigned :26;
  50.     unsigned SPI1AEIF:1;
  51.     unsigned SPI1ARXIF:1;
  52.     unsigned SPI1ATXIF:1;
  53.   };
  54.   struct {
  55.     unsigned :26;
  56.     unsigned I2C3BIF:1;
  57.     unsigned I2C3SIF:1;
  58.     unsigned I2C3MIF:1;
  59.   };
  60.   struct {
  61.     unsigned :26;
  62.     unsigned I2C1ABIF:1;
  63.     unsigned I2C1ASIF:1;
  64.     unsigned I2C1AMIF:1;
  65.   };
  66.   struct {
  67.     unsigned w:32;
  68.   };
  69. } __IFS0bits_t;
  70. extern volatile __IFS0bits_t IFS0bits __asm__ ("IFS0") __attribute__((section("sfrs")));
  71. extern volatile unsigned int        IFS0CLR __attribute__((section("sfrs")));
  72. extern volatile unsigned int        IFS0SET __attribute__((section("sfrs")));
  73. extern volatile unsigned int        IFS0INV __attribute__((section("sfrs")));

Akkor látod, hogy IFS0bits.T1IF = 0; például.
(#) Amarton válasza Stefan hozzászólására (») Aug 27, 2012 1 /
 
Közben egy csomó dologra rájöttem.
Végre működik a timer megszakítás.
Kipróbáltam együtt a timer megszakítást és a portváltozás megszakítást.
Nem mindig úgy működött, ahogyan szerettem volna.
Ezután visszatöltöttem a gyári mintaprogramot, ami 2 LED-et villogtat, az egyiket a főprogramban nyomógombra, a másikat pedig megszakításból a másik nyomógombra.
Az érdekes az az, hogy a gyári program is minden 10. gombnyomásnál meghülyül, nem vált át a LED, vagy világítva marad, ha már a gomb nincs is nyomva.

Kipróbáltam egy másik nyomógombon is, ugyan az a jelenség

Ez azért gáz, hogy a gyári programmal sem működik rendesen én meg már mindent átnyálaztam a saját progimban.

Mi lehet az oka annak, hogy nem mindig lép be a megszakításba (a gyári program sem)?
(#) potyo válasza Amarton hozzászólására (») Aug 27, 2012 /
 
Nem a nyomógombok pergése zavar meg téged?
(#) Amarton válasza potyo hozzászólására (») Aug 27, 2012 /
 
Kipróbálom, hogy várok 100ms-ot a megszakításban.
Ennek ellenére akkor is működnie kellene, max a gombnyomásra többször kellene belépnie a megszakításba, szerintem.
(#) _vl_ válasza Amarton hozzászólására (») Aug 29, 2012 /
 
Idézet:
„ogy várok 100ms-ot a megszakításban.”

Ne próbáld ki. Megszakításban nem várunk, pláne nem 0.1 másodpercet.
Pergésmentesíteni nem így kell. Kell csinálni egy 1ms-os timert, és nézni minden megszakításnál a gomb állapotát. Ha legalább x alkalommal ugyanaz volt a gomb állása, akkor a gomb beállt. Az x-nek olyan 5-8-at érdemes választani.
(#) Amarton válasza _vl_ hozzászólására (») Aug 29, 2012 /
 
Okés,

Kipróbálom.
(#) potyo válasza Amarton hozzászólására (») Aug 29, 2012 /
 
Itt és Itt még mintakódot is találsz.
(#) Amarton hozzászólása Aug 30, 2012 /
 
Most már hülyét kapok.
A prellegés csak egy dolog.
Az miért van, hogy megnyomom a gombot, és a 32bites timer megáll.
Megnyomom a pic32 starterkit-en az SW1-et.
A hozzá tartozó LED1 bekapcsol, és bekapcsolva marad azután is, hogy elengedem a nyomógombot.
A LED2 villogása ilyenkor megáll. Ennek nem szabadna bekövetkezni, mert a timer megszakításból megy.
Ha megnyomom újra a gombot, akkor a LED1 kialszik, és a LED2 újra elkezd villogni.
Olyan, mintha megállna a program futása, amikor a SW1-et megnyomom.

  1. #include <plib.h>
  2.  
  3. #pragma config FNOSC    = PRIPLL        // 011 = Primary Oscillator with PLL module (XT+PLL, HS+PLL, EC+PLL)
  4. #pragma config FPLLIDIV = DIV_2         // PLL Input Divider (PIC32 Starter Kit: use divide by 2 only)
  5. #pragma config FPLLMUL  = MUL_20        // PLL Multiplier (PLL Multiplier bits)
  6. #pragma config FPLLODIV = DIV_1         // PLL Output Divider (Default Postscaler for PLL bits)
  7. #pragma config FPBDIV   = DIV_1         // Peripheral Clock divisor (Peripheral Bus Clock Divisor Default Value bits)
  8. #pragma config FWDTEN   = OFF           // Watchdog Timer
  9. #pragma config WDTPS    = PS1           // Watchdog Timer Postscale
  10. #pragma config FCKSM    = CSDCMD        // Clock Switching & Fail Safe Clock Monitor
  11. #pragma config OSCIOFNC = OFF           // CLKO Enable
  12. #pragma config POSCMOD  = XT            // Primary Oscillator
  13. #pragma config IESO     = OFF           // Internal/External Switch-over
  14. #pragma config FSOSCEN  = OFF           // Secondary Oscillator Enable
  15. #pragma config CP       = OFF           // Code Protect
  16. #pragma config BWP      = OFF           // Boot Flash Write Protect
  17. #pragma config PWP      = OFF           // Program Flash Write Protect
  18. #pragma config ICESEL   = ICS_PGx2      // ICE/ICD Comm Channel Select
  19. #pragma config DEBUG    = OFF           // Debugger Disabled for Starter Kit
  20.  
  21. //  The following is used by the main application
  22. #define SYS_FREQ(80000000)
  23.  
  24. unsigned int dummy;
  25. unsigned int sync = 0;
  26.  
  27. int main(void)
  28. {
  29.  
  30.    SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);
  31.  
  32.         PORTSetPinsDigitalOut(IOPORT_D, BIT_0 | BIT_1 | BIT_2);
  33.  
  34.         PORTClearBits(IOPORT_D, BIT_0 | BIT_1 | BIT_2);
  35.  
  36.         PORTSetPinsDigitalIn(IOPORT_D, BIT_6 | BIT_7);
  37.  
  38.         mCNOpen(CN_ON,CN15_ENABLE, CN15_PULLUP_ENABLE | CN16_PULLUP_ENABLE);
  39.  
  40.         dummy = mPORTDRead();
  41.  
  42.         OpenTimer23(T2_SOURCE_INT | T2_PS_1_256 | T2_32BIT_MODE_ON, 0x8968);
  43.  
  44.         OpenTimer4(T4_SOURCE_INT | T4_PS_1_256, 0x400);
  45.  
  46.         ConfigIntTimer23( T23_INT_ON | T23_INT_PRIOR_4);
  47.  
  48.         ConfigIntTimer4(  T4_INT_ON  | T4_INT_PRIOR_5);
  49.  
  50.         ConfigIntCN(CHANGE_INT_ON | CHANGE_INT_PRI_2);
  51.  
  52.  
  53.         INTEnableSystemMultiVectoredInt();
  54.  
  55.         T2CONbits.TON = 1;              // Start timer
  56.         T4CONbits.TON = 0;              // Stop timer
  57.  
  58.    while(1)
  59.    {
  60.  
  61.        if(!sync)
  62.        {
  63.           LATDbits.LATD2 = 1;
  64.        }
  65.        else
  66.        {
  67.           LATDbits.LATD2 = 0;
  68.        }
  69.    }
  70.  
  71.  
  72. }
  73.  
  74. void __ISR(_TIMER_23_VECTOR, ipl4) handlesTimer23Ints(void)
  75. {
  76.         LATDINV = 2;
  77.         mT23ClearIntFlag();
  78. }
  79.  
  80. void __ISR(_TIMER_4_VECTOR, ipl5) handlesTimer4Ints(void)
  81. {
  82.         mT4ClearIntFlag();
  83. }
  84.  
  85.  
  86. void __ISR(_CHANGE_NOTICE_VECTOR, ipl2) ChangeNotice_Handler(void)
  87. {
  88.     dummy = PORTReadBits(IOPORT_D, BIT_6);
  89.  
  90.     mCNClearIntFlag();
  91.  
  92.     if(dummy == BIT_6)
  93.     {
  94.         PORTClearBits(IOPORT_D, BIT_0);
  95.     }
  96.  
  97.     else
  98.     {
  99.         PORTSetBits(IOPORT_D, BIT_0);     // turn on LED2
  100.     }
  101.  
  102. }
(#) trudnai válasza Amarton hozzászólására (») Aug 31, 2012 /
 
En nem ertek a 32 biteshez, de miert kulonbozokeppen billegteted a ket LED-edet? Az egyik esetben az INV-el, a masikban meg manualisan port firkalasokkal. Nyilvan akorul tortenik valami gubanc aminek a mellekhatasa, pl hogy a LAT-bol nem kerulnek at a modositasok a port-ba...
(#) _vl_ válasza trudnai hozzászólására (») Aug 31, 2012 /
 
Az probléma lehet, hogy a main függvény a LAT regisztert tekergeti, eközben az interrupt megérkezik, és az ISR-ben ugyanazt a regisztert tekergetjük.

A LATxbits használata ugyanis a következő kódot fogja generálni:
LATx = LATx | konstans vagy LATx = LATx & ~konstans.
Ha a LATx kiolvasása és az eredmény visszaírása között jön az interrupt, akkor minden változtatás el fog veszni a visszaíráskor, amit az interrupt rutin csinált.

LATxSET, LATxCLR regisztereket kéne használni a main-ben.
(#) Amarton válasza _vl_ hozzászólására (») Aug 31, 2012 /
 
Érdekes, hogy ma már nem csinálta, azaz a program úgy futott, ahogy kell.
Szerintem a KIT + MplabX + Windows páros meghülyült.
Ma elindítottam a gépet és a tegnapi program gond nélkül működik.
Fura volt, hogy tegnap a debug LED is világított, holott a debug funkció nem volt bekapcsolva.
Ma már a debug LED sem ment, most már az is csak akkor világít, ha debugolok.

Azért köszönöm.
(#) _vl_ válasza Amarton hozzászólására (») Szept 1, 2012 /
 
Idézet:
„Érdekes, hogy ma már nem csinálta, azaz a program úgy futott, ahogy kell.”


Ebben semmi érdekes nincs. Kritikus versenyhelyzet a fogalom neve.
Attól függ az eredmény, hogy éppen sikerül-e a interrupt-nak pont a LAT művelet közben érkeznie = totál véletlenszerű lesz a kimenetel.

A programod nem javult meg, csak most éppen nem érzékeled, hogy rossz. Nem kell félni, majd a legváratlanabb időpontokban pont nem fog jól működni.
(#) trudnai válasza _vl_ hozzászólására (») Szept 1, 2012 /
 
Kicsit olvasgattam utana, igazad lehet! Nem tudtam, hogy ezek a PIC32-ben mar nem atomikus muveletek. Valoban a SET es CLR hasznalata lenne celszeru es egy jo megoldas ide.
(#) Amarton hozzászólása Szept 1, 2012 /
 
Egy olyan kérdésem van még:
Mi a szintaktikája C nyelvben, ha van több tömböm és írok egy általános függvényt, akkor hogyan tudom neki a tömböt átadni.
Itt egy egyszerű példa:
Szeretném, ha a függvénynek azt is megmondhatnám, hogy melyik tömbből vegye az adatot.
  1. unsigned int array1[]={1,2,3,4,5,6,7,8,9};
  2. unsigned int array2[]={10,20,30};
  3.  
  4. unsigned int fuggveny(unsigned int x, unsigned int y)
  5. {
  6. unsigned int tmp;
  7. tmp = array1[x]*array1[y];   //Itt csak a tömb1-ből veszi, de jó lenne, ha a meghívásnál már lehetne rá hivatkozni.
  8. }
Következő: »»   60 / 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