Fórum témák

» Több friss téma
Fórum » PIC programozása C nyelven, C-Compiler
Lapozás: OK   95 / 153
(#) Wudoou válasza potyo hozzászólására (») Márc 12, 2014 /
 
Értem. Mostmár egész jól alakul a dolog. Már csak azt szeretném megkérdezni, hogy szerintetek ha megkaptam a Modbus csomagot, leellenőrzöm, ha helyes elkészítem a választ és utána amikor elküldöm, akkor "karakterenként", vagy "egy az egybe" küldjem el?
Szóval:
  1. if (soros_flag)
  2.                 {
  3.                         RCIE=0;
  4.             RTS_ON();
  5.             vWait_us(100);
  6.                         MB_control = ReadMBFrame();
  7.                         if (MB_control == Read_Holding_REG)
  8.                         {
  9.                                 readRegResponse(&atlag);       
  10.                         }
  11.                        
  12.                         else
  13.                         {
  14.                                 writeBadRequest(MB_control);
  15.                         }
  16.                         soros_flag=0;
  17.  
  18.                 }
  19.  
  20.                 if (kimeno_puffer.hatralevo && TXIF)    //ha tx üres és van mit küldeni/* set when register is empty */
  21.                 {
  22.                         TXREG = kimeno_puffer.kimeno_adat[kimeno_puffer.hossz-kimeno_puffer.hatralevo];
  23.                         TXEN = 1;
  24.                         while (!TRMT);
  25.                         kimeno_puffer.hatralevo--;     
  26.                         if(kimeno_puffer.hatralevo==0)
  27.                         {
  28.                                 RTS_OFF();
  29.                                 RCIE=1;
  30.                         }
  31.                 }

Itt minden egyes program lefutáskor elküld egy karaktert és csökkenti a puffer számlálót. Előnye, hogy közben mással is tud "foglalkozni" a program.
Azt tapasztalom, hogy a modscan programmal 100-ból 2-3 csomag timeout-tal elveszlik. Ez lehetséges azért, mert amikor bejön a soros_flag, akkor letiltom a megszakítást, kielemzem a csomagot, válaszolok és majd csak utána engedélyezem ismét az olvasást. Igazából nem tudom, hogy le kell-e tiltani a megszakítást, attól tartok, hogy válasz előkészítés közben ismét kapok egy kérést, és akkor a program elkezdi felülírni a még el nem küldött üzenetet. Vagy esetleg azért van a timeout mert a hőmérséklet érzékelők olvasásakor is le van tiltva a megszakítás és pont akkor kapok kérést?
(#) potyo válasza Wudoou hozzászólására (») Márc 12, 2014 /
 
Nem ismerem a modbus protokollt, akár mindkettő lehet, de utóbbi biztosan lehet az ok. Miért tiltod a megszakítást a hőmérők olvasásának idejére? Ha esetleg attól tartasz, hogy egymásra fut két kérés a modbus felől, akkor csinálhatsz ping-pong pufferelést. Ez azt jelenti, hogy két-két bemenő és kimenő puffert csinálsz, és felváltva dolgozol velül. Ha egy adatcsomag bejött, akkor átállítod, hogy az esetleg jövő újabb adatcsomag a másik pufferbe kerüljön, amíg ezt feldolgozod. De érzésem szerint az lesz a gond, hogy a hőmérők olvasásakor tiltod a megszakításokat.
(#) watt válasza Wudoou hozzászólására (») Márc 13, 2014 /
 
Szia! Ha megszakításonként karakterenként veszel és megszakítással karakterenként adsz, akkor a soros port alig vesz el időt. Egy karakter beérkezésének, elküldésének ideje hosszú, nem érdemes közben ácsingózni. Így többek között a hőmérő kiolvasására is lesz idő. A kimenő puffert csak akkor töltsd fel az új adatokkal, ha befejeződött az előző megkezdett csomag elküldése(jelzők használata).
Gondolom a DS hőmérőket nem úgy használod, hogy várakozol, míg 750msec alatt elkészül a konverzió???
(#) Wudoou válasza watt hozzászólására (») Márc 13, 2014 /
 
Természetesen nem. Flageket állítok be tmr0 megszakításban és ott növelek egy unsigned char típusú változót, ha elér 245-öt, akkor a flaget 1-be írom, jelezvén a főprogramnak, hogy lejárt a 750 ms (például) és akkor mehet a kiolvasás. Kiolvasom a ds-eket, majd törlöm a flaget.
  1. codevoid interrupt isr(void)
  2. {
  3. BYTE cgetchar;
  4. static BYTE kijelzo_idozito=0;
  5. static BYTE meres_idozito=0;
  6. static BYTE Modbus_timeout=0;
  7. if (T0IE && T0IF)
  8. {
  9. T0IF=0;
  10. kijelzo_idozito++;
  11. if (kijelzo_idozito==254)
  12. {
  13. kijelzo_idozito=100;
  14. kijelzo_frissites_flag=1;
  15. RA0^=1;;
  16. }
  17. meres_idozito++;
  18. if (meres_idozito==245)
  19. {
  20. meres_idozito=0;
  21. meres_flag=1;
  22. }
  23. if(MB_start_flag)
  24. {
  25. Modbus_timeout++;
  26. if(Modbus_timeout==5)
  27. {
  28. MB_start_flag=0;
  29. bejovo_puffer.hossz=0;
  30. Modbus_timeout=0;
  31. }
  32. }
  33. }
  34. while (RCIF) // soros port dolgai
  35. {
  36. if (OERR)
  37. {
  38. // overrun - eldobáljuk a puffer tartalmát, majd reset
  39. while (RCIF)
  40. {
  41. (void)RCREG;
  42. CREN = 0;
  43. CREN = 1;
  44. continue;
  45. }
  46. }
  47. frameerr = FERR != 0;
  48. cgetchar = RCREG;
  49. if (frameerr)
  50. {
  51. // frame error - karakter eldobása
  52. (void)RCREG;
  53. }
  54. else
  55. {
  56. if ( MB_start_flag == 0 && soros_flag == 0 && cgetchar == SlaveAddress )
  57. {
  58. MB_start_flag=1; //ezzel elindítunk egy timert, ha lejár, akkor reseteli a
  59. vételi puffer hosszt
  60. bejovo_puffer.hossz=0;//ezzel jelezzük, hogy megjött az első karakter, vagyis a cím
  61. bejovo_puffer.adat[bejovo_puffer.hossz++]=cgetchar; //cím mentése
  62. }
  63. else if ( MB_start_flag == 1 && soros_flag == 0 ) //itt már meg kellett jönnie e címnek
  64. {
  65. bejovo_puffer.adat[bejovo_puffer.hossz++]=cgetchar;
  66.  
  67. if (bejovo_puffer.hossz>7)
  68. {
  69. soros_flag=1;
  70. MB_start_flag=0;
  71. Modbus_timeout=0;
  72. // RTS=1; //írás előkészítés
  73. } //end if
  74. } //end else
  75. } //end else
  76. } //end RCIF
  77. }


Ez a megszakításom, a főprogramomban pedig így kezelem le:
  1. if (meres_flag)
  2. {
  3. for(char d_index=0;d_index<eszkoz_szam;d_index++){
  4. if(d_index>=0 && d_index<8)
  5. which_pin=1;
  6. if(d_index>=8 && d_index<16)
  7. which_pin=2;
  8. if(d_index>=16 && d_index<24)
  9. which_pin=3;
  10. hom=(signed int)read_after_getstartalldev(which_pin,d_index);
  11. atlag[d_index]=hom;
  12. }
  13. // konverzió parancs kiadása a szenzoroknak
  14. start_allds1820();
  15. meres_flag=0;
  16. }
A hozzászólás módosítva: Márc 13, 2014
(#) potyo válasza Wudoou hozzászólására (») Márc 13, 2014 /
 
Nem látom azt a részt, ahol tiltanád a megszakítást a hőmérséklet olvasás idejére. Egyébként az is csak akkor okoz gondot, ha túl hosszú ideig tiltod, hiszen ha közben jött be adat, és nem csordult túl a hardveres FIFO, akkor az rendben le fog kezelődni, amint ismét engedélyezed a megszakítást.
(#) Wudoou válasza potyo hozzászólására (») Márc 13, 2014 /
 
Igen, mert az a 1wire rutinban van implementálva.
De akkor is tiltom az usart megszakítást, ha bejött egy modbus csomag.
  1. if (soros_flag)
  2. {
  3. RCIE=0;
  4. MB_control =ReadMBFrame();
  5. if (MB_control == Read_Holding_REG)
  6. {
  7. readRegResponse();
  8. }
  9. else
  10. {
  11. writeBadRequest(MB_control);
  12. }
  13. soros_flag=0;
  14. RCIE=1;
  15. }
  16. /*
  17. if(OERR)
  18. {
  19. (void)RCREG;
  20. CREN=0;
  21. CREN=1;
  22. }
A hozzászólás módosítva: Márc 13, 2014
(#) potyo válasza Wudoou hozzászólására (») Márc 13, 2014 /
 
És az 1wire rutinban mikor tiltod és engedélyezed?

Az említett kódrészletben szerintem felesleges tiltani. Milyen gyakran jönnek csomagok a modbuson? Van valami előírt minimális idő az egyik csomag utolsó bájtja és a következő csomag első bájtja között?
(#) Wudoou válasza potyo hozzászólására (») Márc 13, 2014 /
 
Igazából a felügyeleti rendszerét is én fogom programozni (Vision x9), így ez elég rugalmas határok közt mozoghat, most 150ms-onként kérdezek és 100ms után van modbus_timeout.
Ez majd valószínüleg több 10s is lehet.
A 1wire rutinban pedig így tiltom:
  1. static void DisableAllInterrupts(void);
  2. static void ResumeAllInterrupts(void);
  3.  
  4. static void DisableAllInterrupts(void)
  5. {
  6.         GIE=0;
  7. }
  8.  
  9. static void ResumeAllInterrupts(void)
  10. {
  11.         GIE=1;
  12. }
  13.  
  14.  
  15. /*
  16.  * OW_reset
  17.  * visszatérési érték: 0 = van eszköz, 1 = nincs eszköz, 2 = rövidzár a buszon
  18.  */
  19.  BYTE OW_reset(BYTE pin)
  20. {
  21.        
  22.         BYTE i, LastLow;
  23.  
  24.  
  25.         switch(pin)
  26.                 {
  27.                 case 1:
  28.                 DisableAllInterrupts();
  29.                 OW_HI1();
  30.                 for (i = 240; i; --i);
  31.                 OW_LO1();
  32.                 for (i = 160; i; --i);
  33.                 OW_HI1();      
  34.                 OW_HIZ1();
  35.                 for (i = 160; i; --i) // Watch for presence pulse
  36.                 if (OW_DATA1 == 0) break;
  37.                 ResumeAllInterrupts();
  38.                 if (!i)
  39.                 return 1;
  40.                 for (i = LastLow = 500; i && i + 20 > LastLow; --i)
  41.                         {
  42.                         if(OW_DATA1 == 0) LastLow = i;
  43.                         }
  44.                         OW_HI1();      
  45.                         OW_HIZ1();
  46.                         if (!i) // Handle another exception case
  47.                         return 1;
  48.                         return 0;
  49.                         break;
  50.        
  51.                 case 2:
  52.  
  53.                 DisableAllInterrupts();
  54.                 OW_HI2();
  55.                 for (i = 240; i; --i);
  56.                 OW_LO2();
  57.                 for (i = 160; i; --i);
  58.                 OW_HI2();      
  59.                 OW_HIZ2();
  60.                 for (i = 160; i; --i) // Watch for presence pulse
  61.                 if (OW_DATA2 == 0) break;
  62.                 ResumeAllInterrupts();
  63.                 if (!i)
  64.                 return 1;
  65.                 for (i = LastLow = 500; i && i + 20 > LastLow; --i)
  66.                         {
  67.                         if(OW_DATA2 == 0) LastLow = i;
  68.                         }
  69.                         OW_HI2();      
  70.                         OW_HIZ2();
  71.                         if (!i) // Handle another exception case
  72.                         return 1;
  73.                         return 0;
  74.                         break;
  75.        
  76.                 case 3:
  77.  
  78.                 DisableAllInterrupts();
  79.                 OW_HI3();
  80.                 for (i = 240; i; --i);
  81.                 OW_LO3();
  82.                 for (i = 160; i; --i);
  83.                 OW_HI3();      
  84.                 OW_HIZ3();
  85.                 for (i = 160; i; --i) // Watch for presence pulse
  86.                 if (OW_DATA3 == 0) break;
  87.                 ResumeAllInterrupts();
  88.                 if (!i)
  89.                 return 1;
  90.                 for (i = LastLow = 500; i && i + 20 > LastLow; --i)
  91.                         {
  92.                         if(OW_DATA3 == 0) LastLow = i;
  93.                         }
  94.                         OW_HI3();      
  95.                         OW_HIZ3();
  96.                         if (!i) // Handle another exception case
  97.                         return 1;
  98.                         return 0;
  99.                         break;
  100.              default:break;
  101.                 }
  102. }


Vagy itt:
  1. void OW_write_bit(BYTE pin,BYTE val)
  2. {
  3.         DisableAllInterrupts();
  4.         switch(pin)
  5.                 {
  6.                 case 1:
  7.                         OW_HI1();      
  8.                         OW_LO1();
  9.                         vWait_us(6);
  10.                
  11.                         if (val)
  12.                                 OW_HIZ1();
  13.                
  14.                         vWait_us(70);  
  15.                         OW_HI1();              
  16.                         vWait_us(10);
  17.                         break;
  18.  
  19.                 case 2:
  20.                         OW_HI2();      
  21.                         OW_LO2();
  22.                         vWait_us(6);
  23.                
  24.                         if (val)
  25.                                 OW_HIZ2();
  26.                
  27.                         vWait_us(70);  
  28.                         OW_HI2();              
  29.                         vWait_us(10);
  30.                         break;
  31.                
  32.                 case 3:
  33.                         OW_HI3();      
  34.                         OW_LO3();
  35.                         vWait_us(6);
  36.                
  37.                         if (val)
  38.                                 OW_HIZ3();
  39.                
  40.                         vWait_us(70);  
  41.                         OW_HI3();              
  42.                         vWait_us(10);
  43.                         break
  44.                 default: break;
  45.                 }
  46.         ResumeAllInterrupts();
  47. }
(#) Wudoou válasza potyo hozzászólására (») Márc 13, 2014 /
 
Arra gondoltam, hogy lehet célszerűbb lenne és átláthatóbb, ha a bejovo_puffer és kimeno_puffer helyett valami ilyesmit csinálnék:
  1. typedef struct
  2. {
  3.         UCHAR slaveAddress;
  4.         UCHAR functionCode;
  5.         UINT startAddress;
  6.         UINT quantity;
  7.         UINT chSum;
  8.         UCHAR errorCode;
  9. }modBUS;

És így nem a pufferhosszt növelgetném bejövő karakterenként, hanem a megfelelő változókat tölteném fel.
Csak ezeket a megszakításban hogy?
A hozzászólás módosítva: Márc 13, 2014
(#) DJozso hozzászólása Ápr 13, 2014 /
 
De jó lenne, ha valaki tudna segíteni rajtam. Egy 16f628 PIC-kel küzdök, aminek egy szenzor adatait kellene megjelenítenie egy 2*16 karakteres LCDn. A baj a következő: A szenzor küld 40 bit adatot (amelyből az első 16 bit a pára értéke (0-999 közti érték, melyet 10-el osztva megkapjuk az értéket egy tizedes pontossággal), a második 16 bit a hőmérséklet, majd az utolsó 8 bit az ellenőrző kód).
Nekem ott van a bajom, hogy az ellenőrzés lefut, minden rendben. Viszont a
kijelzőn minden 25.5-es érték után 0.1 következik. Tehát pl. 25.6 fok az 0.1 foknak írja. És így van ez a páránál is, 25.5-enként átfordul. Ez biztosan abból van, hogy a RH_Byte1 illetve T_Byte1 adatait nem használja. Pedig megkapja, mert az ellenőrzés nem talál hibát. Ime a kód:
  1. RH_Byte1 = ReadByte();
  2.      RH_Byte2 = ReadByte();
  3.      T_Byte1 = ReadByte();
  4.      T_Byte2 = ReadByte();
  5.      CheckSum = ReadByte();
  6.      // Ellenorzés, hogy minden adat jól jött-e át
  7.      if (CheckSum == ((RH_Byte1 + RH_Byte2 + T_Byte1 + T_Byte2) & 0xFF))
  8.      {
  9.       message2[10]  = RH_Byte1 * 256  + RH_Byte2 / 100 + 48;
  10.       message2[11]  = RH_Byte1 * 256  + RH_Byte2%100 / 10 + 48;
  11.       message2[13] = RH_Byte1 * 256  + RH_Byte2%100%10 + 48;
  12.       message1[10]  = T_Byte1 * 256  + T_Byte2 / 100 + 48;
  13.       message1[11]  = T_Byte1 * 256  + T_Byte2%100 / 10 + 48;
  14.       message1[13] = T_Byte1 * 256 + T_Byte2%100%10 + 48;
  15.       message1[14] = 223;     // Celsius karika
  16.       Lcd_Cmd(_Lcd_Clear);
  17.       Lcd_Out(1, 1, message1);
  18.       Lcd_Out(2, 1, message2);
  19.       Delay_ms(2000);

message1 [10]- hőmérséklet érték tizes helyiérték
message1 [11]- hőmérséklet érték egyes helyiérték
message1 [12]- pont (definiálva)
message1 [13]- hőmérséklet érték tizedes helyiérték és a páránál hasonlóképp (message2). A T_Byte1 és RH_Byte1 azért van 256-al szorozva, mert ezek a 16 bites számnál a felső 8 bit, így első bitjük az 2 a nyolcadikon (256). A sorok végén lévő +48 pedig az ascii kód miatt van (48 érték egyenlő a nullával). Tudna valaki valamit mondani arra, hogy miért nem játszanak szerepet a felső 8 bit adatai a kódban?Próbáltam záró jellel is az sem segített.
A hozzászólás módosítva: Ápr 13, 2014
(#) potyo válasza DJozso hozzászólására (») Ápr 13, 2014 / 1
 
Két dolog is lehet:

- egyrészt a C a műveletek eredményét is annyi biten képzni, ahány bitesek az operandusok. Namost ha az RH_Byte1 is és a 256 is nyolc biten szerepelnek, akkor az eredmény is 8 bites lesz, vagyis gyakorlatilag levágja azt, ami az értelme lenne az egésznek. Ha azt írod, hogy 256U, azzal kényszeríted, hogy 16 bitesnek értelmezze a 256-ot, és így az eredményt is 16 biten képezze. Esetleg írj 256UL-t, ha a 256U nem elég. Bár nem tudom, mi a helyzet, ha az operandus eleve nem fér el 8 biten, mint ez esetben a 256

- másrészt nem maradt ki onnan egy zárójel? Mert ha a message tömb 8 bites elemekből épül fel, akkor hiába számolunk 16 biten, ha a végén az eredményt úgyis levágjuk. Valahogy így kellene szerintem:
  1. message2[10]  = (RH_Byte1 * 256U  + RH_Byte2)/ 100 + 48;]
(#) DJozso válasza potyo hozzászólására (») Ápr 14, 2014 /
 
Köszönöm a választ. Délután ki is próbálom (most épp melózom). Van logika abban amit mondasz. Én úgy gondolom, hogy a fenti számítás ad egy értéket (16 biten, mert csak úgy fér el) ehhez hozzáadjuk a 48-at, ami eredményként egy decimális számot eredményez (szerintem valahogy így kellene), ami megfelel valamely ascII kódnak 0-255-ig (8 bites). De lehet igazad van abban, hogy akkor mikor beírjuk a tömbbe levágjuk a 8 bit felletti részt. Esetleg valahogy úgy lehetne, hogy előtte a 3 helyi értéket meghatározzuk külön-külön, majd ezt tároljuk egy 8 bites változóban, és ezt írjuk a tömbbe. Csak azt nem tudom, hogy ha pl. egy 16 bites számot osztok mondjuk 100-al (ami 8 biten elfér), hogy tudom megadni, hogy az eredmény 8 bites legyen (tudom alapból 16 bites lesz)?
(#) potyo válasza DJozso hozzászólására (») Ápr 14, 2014 / 1
 
Próbáld ki először, amiket írtam, a zárójelek és a 256U hozzáadásával szerintem jó lesz. Ha véletlen nem, akkor majd megyünk tovább.

Idézet:
„Csak azt nem tudom, hogy ha pl. egy 16 bites számot osztok mondjuk 100-al (ami 8 biten elfér), hogy tudom megadni, hogy az eredmény 8 bites legyen (tudom alapból 16 bites lesz)?”

A C automatikusan levágja a felső 8 bitet róla, ha egy 8 bites változóba akarod belerakni az eredményt.
A hozzászólás módosítva: Ápr 14, 2014
(#) DJozso válasza potyo hozzászólására (») Ápr 14, 2014 /
 
Köszönöm a segítséget, jó lett. Már programozom a két szenzoros változatot.
(#) killbill válasza potyo hozzászólására (») Ápr 15, 2014 /
 
Idézet:
„egyrészt a C a műveletek eredményét is annyi biten képzni, ahány bitesek az operandusok.”
Ez igy pontatlan. A muveletben szereplo operandusokat egyforma tipusuva konvertalja ugy, hogy a nagyobb bitszamu operandust veszi alapul. (es meg ez sem egeszen pontos igy...) Tehat egy int es long eseten, elobb az int-et long-ra konvertalja. A char-t es short-ot automatikusan mindig int-re konvertalja, float-ot mindig double-re. Ha signed es unsigned keveredne, a signedbol unsigned lesz es az eredmeny is az lesz. Ha integer es float keveredik, akkor az egesz muvelet float lesz (double). K&R 2.7 fejezet.
Idézet:
„Namost ha az RH_Byte1 is és a 256 is nyolc biten szerepelnek, akkor az eredmény is 8 bites lesz”

A konstanskent leirt 256 az int lesz, de meg az 1 is. A 256u csak annyit tesz, hogy unsigned int, semmit tobbet.
Az eredei problemara meg nagyon egyszeru a valasz: A C nyelvben az operatoroknak precedenciajuk van, ezert a vegrehajtasi sorrend nem feltetlenul balrol jobbra halad. A fenti peldaban az RH_Byte1 * 256 + RH_Byte2 / 100 + 48 azt csinalja, hogy megszorozza 256-tal RH_Byte1-et, aztan RH_Byte2-t elobb elosztja 100-zal, majd hozzaadja az elobbi szorzas eredmenyehez, majd ehhez meg hozzad 48-at. Mindezt 16 biten csinalja, csak a legvegen konvertalja 1 byte-osra az eredmenyt. A helyes sor:

(RH_Byte1 * 256 + RH_Byte_2) / 100 + '0';

Az '0' az ugyanaz, mint a 48, csak igy szemleletesebb, hogy itt a 0 ASCII kodjarol van szo.
(#) Beles hozzászólása Ápr 15, 2014 /
 
Sziasztok!
Hogyan tudom azt megcsinálni, hogy egy 7szegmenses kijelző szegmensei két különböző portra van kötve, de egy változóval tudjak rá hivatkozni? Valami struktúrára gondoltam, de nem tudom hogyan lehetne c-ben megvalósítani.
(#) watt válasza Beles hozzászólására (») Ápr 15, 2014 /
 
Írj rá egy függvényt, mert a portokat nem lehet struktúrába szervezni.
(#) Beles válasza watt hozzászólására (») Ápr 15, 2014 /
 
Rendben, sajnálattal tudomásul veszem
(#) watt válasza Beles hozzászólására (») Ápr 15, 2014 /
 
Esetleg makrót lehetne még, de az nagyon pazarolja a helyet a program memóriában, mert minden alkalommal több sort fordít be. Egy jó függvény egyszerűvé teszi a szabdalt portlábak kezelését program áttekinthetőségi szempontból, csak egy értéket adsz át neki és kész.
(#) Beles válasza watt hozzászólására (») Ápr 15, 2014 /
 
Értem. Elkezdtem már a függvényt megírni rá! Köszi!
(#) Brienter hozzászólása Ápr 17, 2014 /
 
Üdv!
Most váltanék Assembly-ről C-re a környezet: MPLABX v2.05 +CCS-C 5.011.
MPLAB látja is a fordítót, de nem tudja értelmezni már delay_ms parancsot sem
  1. #include <16F877.h>
  2. #fuses NOWDT,HS,NOLVP,BROWNOUT,NOPUT,NOPROTECT
  3. #use delay(clock=4000000)
  4. void main()
  5. {
  6.     while (1)
  7.     {
  8.         output_toggle(PIN_D2);
  9.         delay_ms(1000);
  10.     }
  11. }


Erre a kódra azt mondja: Unable to resolve identifier delay_ms.
Úgy sejtem hogy az IDE-ben van valami rosszul beállítva vagy nem include-oltam be valamit amit kéne?
Köszi.
(#) foxi63 válasza Brienter hozzászólására (») Ápr 17, 2014 /
 
#include "delays.h" ez kell még!
(#) vicsys válasza foxi63 hozzászólására (») Ápr 17, 2014 /
 
CCS C-nél? Biztos?
(#) kissi hozzászólása Ápr 18, 2014 /
 
Sziasztok!

Van egy kis problémám a C18-al és nem tudom, hogy mitől lehet ...?! A változók definiálásánál adtam nekik kezdőértéket, de mintha nem vennék fel rendesen ( nem tudom jobban kifejezni )! A program néha elindul megfelelően, néha nem... Ha ugyanezeknek a változóknak a program elején külön megadom a kezdőértékeket, akkor megfelelően megy !? Ha a programozó rajta van, akkor a deklarációs változat is elég, ki- és visszakapcsolva a tápot működik rendesen ( külön tápról megy!), de ha lehúzom a programozót, akkor már nem indul stabilan. Amennyiben beillesztem a külön inicializáló részt, akkor jól működik ( LVP letiltva, MCLR felhúzva, RELEASE módban fordítva ) !

Mondjatok valami ötletet, mert így most jól megy, de nem értem, mit nem veszek észre !

Előre is köszönöm az ötleteket!
(#) watt válasza kissi hozzászólására (») Ápr 18, 2014 /
 
Biztosan a változók miatt van? Nem lehet, hogy valaminek pont annyi idővel kell több a felépüléshez, amennyi a változók újradeffiniálásához kell? (teszteld egy időzítés beszúrásával).
Elég időt hagysz a ki és bekapcsolás között, hogy a táp teljesen megszűnjön(RAM kiürülése)? I2C eszközök nincsenek vonalon, amiknek szintén több táp szünet kell egy sima ki-be kapcsolásnál(kondik)?
(#) kissi válasza watt hozzászólására (») Ápr 18, 2014 /
 
Próbáltam több időzítést, nem működött. I2C nincs a rendszerben !

Idézet:
„lég időt hagysz a ki és bekapcsolás között, hogy a táp teljesen megszűnjön(RAM kiürülése)”


Pont ez a gond, ha meg tudott szűnni egy működő fázis után, akkor a "normál" inicializálás nem elég neki!
Most nem volt időm vele többet foglalkozni ( már jó ideje ezzel szívtam! ), most így működik, de utána akarok járni, mert nem értem, hogy mi a gond, ezért kérnék ötleteket!

Köszi az eddigi segítséged !
(#) Brienter válasza foxi63 hozzászólására (») Ápr 18, 2014 /
 
Közben megtaláltam a megoldást. Leírom hátha másnak is segít: MPLAB->Tools->Options->C/C++ fül-> Highlight Unresolved Identifiers és akkor most már nincs pirossal aláhúzva a fél kódom. Bár ez csak tüneti kezelés jó lenne ha értené az MPLAB és akkor talán még színezné is.
(#) Hp41C válasza kissi hozzászólására (») Ápr 18, 2014 /
 
Ha jól emlékszem a startup állomány végzi az inicializált adatok feltöltését. A linker vezérlőben milyen startup van megadva? A névben az i utal az inicializálásra: pl. c018i.o
A C forrásban milyen szekcióban deklaráltad őket? ... idata ...
(#) kissi válasza Hp41C hozzászólására (») Ápr 18, 2014 /
 
Köszi a segítséget!

Azt látom a "MPLAB® C18 C Compiler User’s Guide"-ban (még most kezdtem el nézegetni, 2.9.1.2. fejezet ), hogy ha adok neki kezdőértéket, akkor az idata-ba kerül, ha nem, akkor az udata-ba !? Illetve ahogy nézegettem, úgy láttam, hogy már nincs ilyen c018i.lkr, hanem c018g.lkr van, amit úgy értelmeztem, hogy az előbb leírtaknak megfelelően pakolja be az adatokat ( persze nem vagyok benne tuti ! ).
A linker vezérlőt egyébként hol kell beállítanom ( a projekt *.lkr útvonalánál ?) ?
(#) Hp41C válasza kissi hozzászólására (») Ápr 18, 2014 /
 
Ott van a nave a Project ablakban a (mcw) a Linker script -ben.
Következő: »»   95 / 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