Fórum témák

» Több friss téma
Fórum » PIC programozása C nyelven, C-Compiler
Lapozás: OK   86 / 153
(#) potyo válasza zenetom hozzászólására (») Nov 12, 2013 / 1
 
A függvény neve előtti void azt jelenti, hogy a függvény nem ad vissza értéket. Régen, amikor a C-t kitalálták, az int típusú visszaadott értéket jelölték meg alapértelmezettnek, így elvileg ha nem írsz void-ot a függvény neve elé, akkor az ugyanaz, mintha int-et írnál oda. Régi fordítók warningot csináltak, ha egy függvénynek nem használtad a visszatérési értékét, ezért kellett a void típust bevezetni, mert ha egy void függvénynek nem használtad a visszatérési értékét (ami értelemszerűen nemis létezik), akkor nem generált warningot a fordító. Kicsit fura ez az elgondolás, manapság már nyílván nem így csinálnánk, és manapság nemis generálnak warningot a fordítók, ha nem használod egy függvény visszatérési értékét, de a void dolog talán szokás miatt megmaradt.

A függvény paraméterlistájában viszont a (void) és a () két külön dolgot jelentett. A (void) azt jelentette, hogy a függvény nem fogad paramétert, a () viszont azt jelentette, hogy a függvény ismeretlen, de konstans számú paramétert fogad - gondolom valami más módon kellett a stackről kiszedni a paramétereket, nem direktben a paraméterlistáról. Ez a () forma viszont C99 óta deprecated-nek van jelölve, tehát olyan dolog, ami elavult, és ne használjuk. A fordítók valószínűleg simán elfogadják majd ezt a formát ezután is, de úgy fogják értelmezni, mintha (void) lenne, tehát nem ismeretlen számú paraméter jelölésére, hanem arra, hogy nincs paraméter.

Tehát továbbra is a void main(void) a szabványos forma, de a mai fordítók már nem csinálnak warningot, ha egy függvénynek nem használod a visszatérési értékét, ezért a main(void) forma is megfelel nekik, és nyílván ki is tudják optimalizálni azt a kódrészletet, ahol a visszatérési értéket adná a függvény át.

Én valahogy így tudom a dolgot
(#) zenetom válasza potyo hozzászólására (») Nov 12, 2013 /
 
Na, így már kerek, értem.
Köszönöm a kimerítő választ!
(#) kissi válasza zenetom hozzászólására (») Nov 12, 2013 /
 
Én is !
(#) kontár hozzászólása Nov 13, 2013 /
 
Sziasztok !
Segítségetek kérem .Van két nyomógombom amivel az (sz) számot 10-től 35-ig tudom egyesével növelni illetve csökkenteni. Csak egy dologgal nem boldogulok. A számolást oly módon csinálja,hogy a nyomógomb benyomásakor léptessen egyet majd a következő léptetést a nyomógomb visszaengedése után az újbóli gombnyomás váltsa ki.

  1. #include <system.h>
  2.  
  3. main ()
  4. {
  5.        
  6. int i=1, sz=10;    
  7.        
  8.        
  9. {
  10.   while (true)
  11.        
  12.   if  ((portb==0b00000001) && sz<35)
  13.      sz=sz+1;
  14.    
  15.    
  16.   else if  ((portb==0b00000010) && sz>10)
  17.      sz=sz-1;
  18.    
  19.  
  20.  
  21.  
  22.  }
  23.  }
A hozzászólás módosítva: Nov 13, 2013
(#) potyo válasza kontár hozzászólására (») Nov 13, 2013 / 1
 
A megoldás lényege, hogy tárolni kell a gomb előző állapotát, és csak akkor reagálni, ha változás volt az állapotban. Valami ilyesmi:

  1. portb_uj=portb;
  2. if ((portb_uj ^ portb_elozo)&0b00000001)        // ha a 0. biten volt változás
  3. {
  4.         if (portb_uj & 0b00000001)      // és most a bit 1
  5.         {
  6.                 sz=sz+1; // C-ben ezt inkább úgy szokás írni, hogy sz++
  7.         }
  8. }
  9. if ((portb_uj ^ portb_elozo)&0b00000010)        // ha az 1. biten volt változás
  10. {
  11.         if (portb_uj & 0b00000010)      //és most a bit 1
  12.         {
  13.                 sz=sz-1;
  14.         }
  15. }
  16. portb_elozo=portb_uj;


Persze ez még mindig több sebből vérzik, mert még a pergést nem küszöböltük ki, de az elv ez lenne - ki nem próbáltam, nem garantálom, hogy hibátlan. Ha egy pergésmentesítéssel egyesített megvalósítás érdekel, akkor nézd meg ebben a cikkben feltett forráskódot, a 65-125 sorok között foglalkozik a bemenetek kezelésével.
A hozzászólás módosítva: Nov 13, 2013
(#) kontár válasza potyo hozzászólására (») Nov 13, 2013 /
 
Nagyon szépen köszönöm a gyors választ tanulmányozom.
(#) potyo hozzászólása Nov 20, 2013 /
 
XC8 fordító, 16F887 kontrolleren akarnék egy meglévő kódot menet közben választható módon kétnyelvűsíteni. Eddig ilyen megoldás volt:

  1. #define NYELV   'S'
  2.  
  3. #if NYELV=='M'
  4.         #define DS_HIBA                 "Senzor %1d hiba   "
  5.         #define FAZIS_HIBA              "Fazishiany      "
  6.         #define MAGASNY_HIBA    "Magasny. hiba   "
  7. #elif NYELV=='S'
  8.         #define DS_HIBA                 "Senzor %1d greska "
  9.         #define FAZIS_HIBA              "Fali faza       "
  10.         #define MAGASNY_HIBA    "Maks. pritisak  "
  11. #endif


És akkor utána sprintf-nek van átadva pl. a DS_HIBA. Tehát fordítottam vagy egyik vagy másik nyelvű kódot, és utána azt töltöttem fel. Viszont most csinálnék egy ilyet:

  1. const char * DS_HIBA;
  2. const char * FAZIS_HIBA;
  3. const char * MAGASNY_HIBA;
  4. void nyelv(char nyelv)
  5. {
  6.         if (nyelv=='M')
  7.         {
  8.                 DS_HIBA                 = "Senzor %1d hiba   ";
  9.                 FAZIS_HIBA              = "Fazishiany      ";
  10.                 MAGASNY_HIBA    = "Magasny. hiba   ";
  11.         }
  12.         else
  13.         {
  14.                 DS_HIBA                 = "Senzor %1d greska ";
  15.                 FAZIS_HIBA              = "Fali faza       ";
  16.                 MAGASNY_HIBA    = "Maks. pritisak  ";
  17.         }
  18. }


Ez a kódrészlet lefutna induláskor és nyelvváltáskor, és utána ugyanúgy használnám sprintf-ben pl. a DS_HIBA pointert. Viszont nekem úgy tűnik, hogy a konstans szövegeket RAM-ban akarja tárolni, mert azt mondja, hogy nincs elég RAM (természetesen további szövegek is vannak még). A régi kódban még van 80 bájtnyi szabad RAM, ez a függvény nem fogyaszthat el annyit, mást pedig még nem csináltam, csak kiszedtem a #define-okat, beraktam a const char *-okat, és betettem ezt a függvényt. Így szerintem nincs más magyarázat, mint hogy a konstans szövegeket is RAM-ban akarná tárolni. Nos, hogyan lehet rávenni, hogy mégis a ROM-ban tárolja?
(#) potyo válasza potyo hozzászólására (») Nov 20, 2013 /
 
Közben gondolkoztam ezen, és tény, hogy valamennyivel több RAM-ra lenne így szükség, hiszen a const char * pointereket a RAM-ban kell tárolni, viszont annyira nincs belőlük sok, hogy megegyék a 80 bájtot. Kb. 20 szövegről van szó jelen állás szerint, az 40 bájtot jelentene, ha két bájtot foglal egy-egy pointer.
(#) kissi válasza potyo hozzászólására (») Nov 20, 2013 /
 
Szia!

Nem tudom próbálni, de mi lenne, ha beírnád a ROM kulcsszót is ?!
pl. const ROM char * DS_HIBA;
A hozzászólás módosítva: Nov 20, 2013
(#) _vl_ válasza potyo hozzászólására (») Nov 20, 2013 / 1
 
Szerintem meg:

  1. #define NYELV_MAGYAR 0
  2. #define NYELV_X 1
  3. #define NYELV_Y 2
  4.  
  5. unsigned char nyelv = NYELV_MAGYAR;
  6.  
  7. #define DS_HIBA (nyelv == NYELV_MAGYAR ? "magyarul" : nyelv == NYELV_X ? "x" : "y")
(#) potyo válasza _vl_ hozzászólására (») Nov 20, 2013 /
 
Kipróbálom estére, most nem vagyok a közelben.
(#) _vl_ válasza potyo hozzászólására (») Nov 20, 2013 /
 
Lehet, hogy a ?-es részre még kell egy zárójel, most nem emlékszem, hogy merre asszociatív a ? operátor.
(#) potyo válasza kissi hozzászólására (») Nov 20, 2013 /
 
ROM kulcsszó elvileg C18-nál kell, XC8 szerintem el sem fogadja 16F esetén. Nem próbáltam, de a doksijában sem rémlik, hogy találkoztam volna ilyennel.
(#) Hp41C válasza potyo hozzászólására (») Nov 20, 2013 / 1
 
Fix mennyiségű és fix hosszúságú szövegek esetére:
A programmemóriában alakítanék ki két egymásutáni táblázatot a két nyelv szövegeinek. Ezek belépési pontjainak címeltérése fix, a fordításkor kiszámolható. A szövegek azonosítására egy sorszámot vagy a címtáblában elfoglalt relatív kezdőcímüket használnám. A kiíratásra egy függvényt írnék, ami a kiválasztott nyelvnek megfelelő táblából és a paraméterként megkapott sorszámból vagy relatív címből határozná meg a szöveg kezdőcímét. Az ott található szöveget írná ki a kijelzőre.
(#) potyo válasza Hp41C hozzászólására (») Nov 20, 2013 /
 
Jól sejtem, hogy valami ilyesmire gondolsz?

  1. const char * nyelvek[2][20]={
  2.         {
  3.                 "Senzor %1d hiba   ",
  4.                 "Fazishiany      ",
  5.                 "Magasny. hiba   "
  6.                
  7.         },
  8.         {
  9.                 "Senzor %1d greska ",
  10.                 "Fali faza       ",
  11.                 "Maks. pritisak  "
  12.                
  13.         }
  14. };
  15.  
  16. enum {
  17.         DS_HIBA,
  18.         FAZISHIANY,
  19.         MAGASNY_HIBA   
  20. }


Használata pedig pl. így:
  1. char tmp[32];
  2. sprintf(tmp, nyelvek[nyelv][DS_HIBA], hibas_szenzor_sorszama);
A hozzászólás módosítva: Nov 20, 2013
(#) Hp41C válasza potyo hozzászólására (») Nov 20, 2013 /
 
Igen, valami hasonlóra...
(#) kontár hozzászólása Nov 21, 2013 /
 
Ha lehet megint kérem a segítségeteket. Az sz értékét szeretném a porta porton megjeleníteni,de sehogy se megy próbálkoztam több helyre írni az sz=porta-t. és/vagy a mainba a trisa-t és a porta-t konfigurálni.

void main()
{
trisb=255;
portb=0;
trisa=0;
porta=0xFF;
char portb_uj;
char portb_elozo=0;
char sz=10;
while(1)

{

portb_uj=portb;
if ((portb_uj ^ portb_elozo)&&0b00000001)

{
if ((portb_uj & 0b00000001) && sz<35)
{
sz++;

}
}
if ((portb_uj ^ portb_elozo)&&0b00000010)


{
if ((portb_uj & 0b00000010) && sz>10)
{
sz--;

}
}
portb_elozo=portb_uj;


}

}
(#) potyo válasza kontár hozzászólására (») Nov 21, 2013 / 1
 
Ha porta-ra akarsz írni, akkor azt porta=sz; formában kell. sz=porta az beolvassa a port állapotát az sz változóba. Nem írod, milyen pic, lehet, hogy analóg bemenetet is tiltani kellene. Fordító gondolom CCS.
(#) kontár válasza potyo hozzászólására (») Nov 21, 2013 /
 
PIC 16F877 a típusa.Elnézést az egyenlőséget már megtanultam hogyan kell írni,de most itt felcseréltem.
(#) kontár válasza potyo hozzászólására (») Nov 21, 2013 /
 
Áttettem a portd-re miután megnéztem a datasheeten a lábak tulajdonságát,ami itt tényleg analóg bemenet.Lás csodát ! Szuperál.Sose jöttem volna rá magamtól.örök hála.Ezzel is tanultam.
(#) janimester hozzászólása Nov 22, 2013 1 /
 
Üdv. 18f4550-re csináltam egy termosztát programot mikroc-vel. Az a problémám hogy csak az előre megírt értéken tudom kapcsoltatni a kimenetet. Hogy tudnám ezt a kódot úgy módosítani hogy mondjuk lenne egy select gombom és egy érték növelő meg csökkentő gombom? Itt lenne az érték amit át kéne változtania és elmenteni a flash memójában hogy köv. induláskor ugyanazzal az értékkel induljon a 16x65 és a 17x65-öt kéne átvariálnom a gombokkal :
  1. Ow_Reset(&PORTA, 1);                         // Onewire reset signal
  2.    Delay_ms(15);
  3.    Ow_Write(&PORTA, 1, 0xCC);                   // Issue command SKIP_ROM
  4.    Delay_ms(15);
  5.    Ow_Write(&PORTA, 1, 0x44);                   // Issue command CONVERT_T
  6.    Delay_us(15);
  7.    Ow_Reset(&PORTA, 1);
  8.    Delay_ms(15);
  9.    Ow_Write(&PORTA, 1, 0xCC);                   // Issue command SKIP_ROM
  10.    Delay_ms(15);
  11.    Ow_Write(&PORTA, 1, 0xBE);                   // Issue command READ_SCRATCHPAD
  12.    Delay_ms(15);
  13.    temp =  Ow_Read(&PORTA, 1);
  14.    temp = (Ow_Read(&PORTA, 1) << 8) + temp;
  15.    Display_Temperature(temp);
  16.    Delay_ms(30);
  17.  
  18.    if(temp >= 16*65 )       //hűtőventillátor bekapcsolása 65foknál 1.es szint.
  19.     {
  20.     PORTE.B1 = 0x01;
  21.     }
  22.     else
  23.     PORTE.B1 = 0x00;
  24.  
  25.     if(temp >= 17*65 )       //hűtőventillátor bekapcsolása 70foknál 2.es szint.
  26.     {
  27.     PORTE.B2 = 0x01;
  28.     }
  29.     else
  30.     PORTE.B2 = 0x00;
(#) Hp41C válasza janimester hozzászólására (») Nov 22, 2013 /
 
  1. if(temp >= 16*65 )

helyett
  1. if(temp >= 16*Hatar )
(#) janimester válasza Hp41C hozzászólására (») Nov 22, 2013 /
 
Vagyis kellene csinálnom egy Hatar nevű változót aminek az értéke a gomboktól csökken vagy nő és akkor a kapcsolási értékekhez nem fokot hanem Hatar változót hívatnám meg ami mögött egyenlőség jellel utána lenne ott az érték?
(#) Hp41C válasza janimester hozzászólására (») Nov 22, 2013 /
 
Igen. Egy kis olvasni való.
A hozzászólás módosítva: Nov 22, 2013
(#) kontár hozzászólása Nov 22, 2013 /
 
Van egy ilyen függvényem,amiben van egy visszaszámlálási késleltetés.Kérdésem az lenne,hogy lehetne megoldani azt,hogy a ciklusból való "kiugrás" késleltetés lehessen akár tíz perc is, (persze , ha másik feltételnek is megfelel)
while((portc == 0b00000000 ) && cou-- > 0);
(#) Tas84 válasza kontár hozzászólására (») Nov 22, 2013 / 1
 
Egy timer interruptban növelsz egy változót/változókat és azt vizsgálod.
(#) potyo válasza _vl_ hozzászólására (») Nov 25, 2013 /
 
Végülis a #define-os módszert választottam. Amit Hp41C írt, az is jó lett volna, csak ha nem azonos hosszúságúak a szövegek, akkor a leghosszabb helyfoglalásának megfelelően lesz mindegyik lefoglalva, ami még a kisebbik probléma lett volna. A nagyobbik, hogy egybefüggő területet kell a tömb számára a fordítónak találnia, és mivel kezd szűkös lenni a hely a kontrollerben, ezért nemnagyon tudta összelinkelni a kódot. A #define-os megoldás viszont nem igényel nagyméretű összefüggő területet.

Próbálkoztam egy ilyen megoldással is:

  1. const char * mDS_HIBA="Szenzor %1d hiba  ";
  2. const char * mFAZISHIANY="Fazishiany      ";
  3. const char * mMAGASNY_HIBA="Magasny. hiba   "
  4.  
  5. const char * sDS_HIBA="Senzor %1d greska ";
  6. const char * sFAZISHIANY="Fali faza       ";
  7. const char * sMAGASNY_HIBA="Maks. pritisak  ";
  8.  
  9. const char **magyar={mDS_HIBA, mFAZISHIANY, mMAGASNY_HIBA};
  10. const char **szerb={sDS_HIBA, sFAZISHIANY, sMAGASNY_HIBA};
  11.  
  12. enum {
  13.         DS_HIBA, FAZISHIANY, MAGASNY_HIBA
  14. };
  15.  
  16. const char ** nyelv=magyar;
  17.  
  18. sprintf(tmp, nyelv[DS_HIBA], 3);


De nem sikerült rávenni a fordítót, hogy ezek közül a "nyelv" pointert kivéve a többi mind flash-en legyen tárolva. Most jut eszembe, hogy lehet úgy kellett volna, hogy const char ** const magyar=..., de ez a const dolog az XC8-ban azért valahogy kevésbé egyértelmű számomra, mint a C18 rom módosítója... Illetve ez a megoldás kevésbé átláthatónak és karbantarthatónak is tűnik számomra, mint a define-os megoldás, és valószínűleg nemis hatékonyabb.
(#) potyo hozzászólása Nov 25, 2013 /
 
Amúgy XC 1.10->1.20 váltásnál eltűnt a sprintf-nél az előjelet megadó módosító. Ilyen volt, hogy sprintf(tmp, "T%1d:%+2d T%1d:%+2d", 1, sz[0], 2, sz[1]); és nem került be az sz[0] és sz[1] változó értéke a szövegbe. Pedig a paraméterlistát elfogadta, hogy négy paraméterre lenne szükség - úgy rémlik, hogy ha nem azonos számú paraméter szerepel a függvényben, mint amire a szöveg alapján szükség van, akkor arról szól a fordító. Szóval ki kellett szednem a + jeleket, lett helyette %3d, és akkor ismét jó.

A másik, ami az én hibám volt, hogy volt egy CRC számoló kód, ami táblázatot használ (maximtól az 1wire CRC számoló direktben átvéve). Nos a táblázat valamiért meg volt adva az 1wire.h fájlban is, unsigned char CRC_TABLA[]; formában, majd az 1wire.c fájlban unsigned char CRC_TABLA[]={0, 94, 188, 226, ...}; Nos ezt az 1.10 verzió eddig "elfogadta", viszont az 1.20-nál a táblázat végig csupa nullát tartalmazott a kódmemóriában. Kijavítottam a header fájlban extern unsigned char CRC_TABLA; alakra, és egyből jó lett. Persze erre két nap után jöttem rá, mert azt hittem, valamit a DS18B20 szenzorok olvasásánál az időzítésekkel rontok el, mert azon a részen változtattam dolgokat, és nemis néztem, hogy mit olvas ki valójában, csak folyton megbukott a kiolvasott érték a CRC ellenőrzésen.
A hozzászólás módosítva: Nov 25, 2013
(#) g.scorpio.d hozzászólása Nov 29, 2013 /
 
Sziasztok !
Segítségetek kérem. Ez egy kis tömb kezelés;
a problémám hogy a C18 fordító - 21:Error: syntax error hibával nem tudok mit kezdeni.
Nem látom a hibát. Előre Köszönöm a segítségeteket!
  1. #include <p18f4550.h>
  2.  
  3. main()
  4. {
  5.         const unsigned char chLedKep[3][5]=
  6. {
  7.         {
  8.                 0b00000001,0b00000010,0b00000100,0b00001000,0b00000000
  9.         },
  10.         {
  11.                 0b10000000,0b01000000,0b00100000,0b00010000,0b00000000
  12.         },             
  13.         {
  14.                 0b00011000,0b00100100,0b01000010,0b10000001,0b00000000
  15.         }
  16. };
  17.         int iIdo;
  18.         unsigned int wIndex=0;
  19.         unsigned int wStrIndex=0;
  20.         const char szSzoveg[]=*ABC*;
  21.         const unsigned int wKarakterHossz=5;
  22.         TRISD=0x00;
  23.         LATD=0x00;
  24.         while(1)
  25.         {
  26.                 for(wStrIndex=0;szSzoveg[wStrIndex]>0;wStrIndex)
  27.                 {
  28.                         for(wIndex=0;wIndex<wKarakterHossz;wIndex++)
  29.                         {
  30.                                 LATD=chLedKep[szSzoveg[wStrIndex]-*A*][wIndex];
  31.                                 for(iIdo=0;iIdo<2000;iIdo++)
  32.                                 {
  33.                                         Nop();
  34.                                 }
  35.                         }
  36.                 }
  37.         }
  38. }
(#) pipi válasza g.scorpio.d hozzászólására (») Nov 29, 2013 /
 
Hali!
A 20-as sorban van a hiba nem a 21-ben. A stringet illik idézőjelbe tenni. (a latd sorában is)
Ha rákattogsz a hibaüzenet ablakban a hibajelzés sorára, akkor a forrás megfelelő sorára ugrik a kurzor
mintha hiányozna a wStrIndex++
megj: a stringet dupla időzéjel közé, a karaktert egyes idézőjel közé....
A hozzászólás módosítva: Nov 29, 2013
Következő: »»   86 / 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