Fórum témák

» Több friss téma
Fórum » PIC programozása C nyelven, C-Compiler
Lapozás: OK   136 / 153
(#) cross51 válasza szuperman hozzászólására (») Okt 17, 2016 /
 
Nekem ez a kód működik az SW spi részt megoldható úgyis ahogy te csináltad, ez kicsit hw közelibb.

Header:
  1. #define NoOp 0
  2. #define DIG0 1
  3. #define DIG1 2
  4. #define DIG2 3
  5. #define DIG3 4
  6. #define DIG4 5
  7. #define DIG5 6
  8. #define DIG6 7
  9. #define DIG7 8
  10. #define _decodeMode 9
  11. #define _intensity 10
  12. #define _scanLimit 11
  13. #define _shutdown 12
  14. #define _displayTest 15
  15.  
  16. #define shutdownMode 0
  17. #define normalOperation 1
  18. #define noDecode 0
  19. #define codeB1 1
  20. #define codeB2 15
  21.  
  22. #define shutdown(addr, state) setMaxMatrix(addr, _shutdown, state);
  23. #define setScanLimit(addr, limit) setMaxMatrix(addr, _scanLimit, limit);
  24. #define setIntensity(addr, intensity) setMaxMatrix(addr, _intensity, intensity);
  25. #define clearDisplay(addr) clrDsp(addr)
  26. #define setRow(addr, row, value) setMaxMatrix(addr, row+1, value)    
  27.  
  28. void setMaxMatrix(uint8_t addr, uint8_t opcode, uint8_t data);
  29. static void writeSPI(uint8_t data);


Source:
  1. void setMaxMatrix(uint8_t addr, uint8_t opcode, uint8_t data)
  2. {
  3.     int8_t i;
  4.  
  5.     for(i = (maxDevices - 1) ; i >= 0; i--)
  6.     {
  7.         if(i == addr)
  8.         {
  9.             writeSPI(opcode);
  10.             writeSPI(data);
  11.         }
  12.         else
  13.         {
  14.             writeSPI(0);
  15.             writeSPI(0);
  16.         }
  17.     }
  18.    
  19.     CS = 1;
  20.     CS = 0;
  21. }
  22.  
  23. static void writeSPI(uint8_t data)
  24. {
  25. #ifdef SW_SPI
  26.     for (uint8_t i = 0; i < 8; i++)
  27.     {
  28.         data = data <<= 1;
  29.  
  30.         if (STATUSbits.C)
  31.         {
  32.             SDO = 1;
  33.         }
  34.         else
  35.         {
  36.             SDO = 0;
  37.         }
  38.         SCK = 1;
  39.         SCK = 0;
  40.     }
  41.    
  42. #else  
  43.     SSPBUF = data;
  44.     while(!PIR1bits.SSP1IF);
  45.     PIR1bits.SSP1IF = 0;
  46. #endif
  47. }


Szerk:
Az init kód lemaradt.
  1. void ledControlInitalize(void)
  2. {
  3.     for(uint8_t i = 0; i < maxDevices; i++)
  4.     {
  5.         setMaxMatrix(i,_displayTest, 0);
  6.         setScanLimit(i, 7);
  7.  
  8.         clearDisplay(i);
  9.         shutdown(i, normalOperation);
  10.         setIntensity(i, 0x04);
  11.     }
  12. }


Ja és mint látod ez a kód alkalmas több max7219-es kezelésére is.
Ja és az uint8_t, ha esetleg nem ismerős unsigned char.
A hozzászólás módosítva: Okt 17, 2016
(#) Lamprologus válasza Attila86 hozzászólására (») Okt 17, 2016 /
 
Köszi!
Az első verzió volt nálam is a kiinduló ... csak több hőmérsékletet kell beolvasni és a 3. sorban lévő if-nél is több feladatot kellett végrehajtani. Ezért kellett egy külön függvény ...

Második verzió: lassan azt hiszem meg kell barátkoznom a mutatókkal is ... idáig még megúsztam a használatukat! Még nem teljesen világos a dolog, valahol a mutató mutatójára mutató mutatónál elvesztettem a fonalat!
(#) cross51 válasza Lamprologus hozzászólására (») Okt 17, 2016 /
 
Pedig a C csodálatossága a mutatókban az indirekt címzésben rejlik. De azért nem kell mindenképpen ilyen végeláthatatlan mutató fonalat létrehozni, valahol szükséges lehet, de szerintem egyszerűbb és közép szinten nem szükséges.
(#) Wezuv válasza Lamprologus hozzászólására (») Okt 18, 2016 /
 
Nem kell félni a mutatóktól Ez olyan, mint amikor a feleségednek nem azt mondod meg, hogy mi van a fiókban, hanem azt, hogy melyik fiókot nyissa ki. Ha ezt egy papírra írva adod át, akkor a papír egy mutató típusú változó, amire egy cím van felvésve. A változó típusa a fordítónak fontos, a tartalma (a cím, amin az érték van amit keresel) neked.
(#) Attila86 válasza Lamprologus hozzászólására (») Okt 18, 2016 /
 
Idézet:
„lassan azt hiszem meg kell barátkoznom a mutatókkal is ... idáig még megúsztam a használatukat”

Rossz hozzáállás!
A mutatókhoz nem úgy kell viszonyulni hogy örül az ember amíg nem használja őket merthogy valamiféle nyűg lenne. Épp ellenkezőleg, majd azt fogod bánni hogy miért csak most barátkoztál meg a mutatókkal és nem jóval korábban, mivel brutálisan meg tudják könnyíteni a programozást.
A mutatók a legcsodálatosabb dolgok a világon, közvetlen a p*na után. A C-ben csodákat lehet velük művelni de nagyon bele is lehet gabalyodni sajnos. Néha már nekem is zavaros egy bizonyos szint után...
(#) szuperman válasza cross51 hozzászólására (») Okt 18, 2016 /
 
Ezt mivel lehet lefordítani?
(#) cross51 válasza szuperman hozzászólására (») Okt 18, 2016 /
 
XC8 ban írtam, ha sw SPI-t használsz
akkor a header-ben
  1. #define SW_SPI
  2. #define SDO LATxbits.y
  3. #define SCK LATxbits.y

A hw SPI-hez meg kell egy inicializálás.
(#) szuperman válasza cross51 hozzászólására (») Okt 18, 2016 /
 
Sikerült működésre bírnom. Köszönöm a segítséget. Egy utolsó kérdésem lehet? A 18-as láb mirre való? Nem igazán értem, amit az adatlap ír.
(#) cross51 válasza szuperman hozzászólására (») Okt 18, 2016 /
 
Az ISET, az adatlapban le van írva, hogy milyen ellenállás értékkel, mekkora lehet a maximális átfolyó áram a LED-eken.
(#) szuperman válasza cross51 hozzászólására (») Okt 18, 2016 /
 
Nem teljesen értem. Hogy a félkövérrel szedett rész mi? Ha 40mA folyik be, akkor 12.2mA-t enged a ledekre 1,5V mellett?
(#) cross51 válasza szuperman hozzászólására (») Okt 18, 2016 /
 
Az nem mA, a táblázaton belül az van, hogy a 40 mA szegmens áramhoz 1.5V LED-el az ISET lábat 12.2kOhm-al kel felhúzni.
(#) szuperman válasza cross51 hozzászólására (») Okt 19, 2016 /
 
Köszönöm!
(#) AZoli hozzászólása Nov 19, 2016 /
 
Sziasztok!

XC16 fordító, 24EP512.. család.
Erre a sorra:
  1. uInt DataWord = ...
  2.         **(&emCANrecAdd1 + i) = DataWord;

miért mondja a fordító hogy:
Idézet:
„Com.c:2448:2: error: invalid type argument of unary '*' (have 'uInt')”


miközben így teljesen ok:
  1. uInt DataWord = ...
  2.     uInt *Address = *(&emCANrecAdd1 + i);
  3.     *Address = DataWord;


emCANrecAdd1 egy uInt kétdimenziós tömb egy eleme #define-al "elnevezve", de ez irreleváns, mert az alsó verzióval tökéletes. A kérdés inkább az, hogy mit nézek el, miért nem ugyan az a kettő?
(#) cross51 válasza AZoli hozzászólására (») Nov 19, 2016 / 1
 
Az & akkor kéne ha, pl.: int*/int** lenne hanem mondjuk egy int változó és annak a címét szeretnéd megkapni pl.:
  1. int valtozo;
  2. //...
  3. int* ptr = &valtozo


így jónak kell lennie:
  1. uInt DataWord = ...
  2.         **(emCANrecAdd1 + i) = DataWord;
(#) AZoli válasza cross51 hozzászólására (») Nov 21, 2016 /
 
emCANrecAdd1 egy uInt tömb egyik eleme, és abban, illetve a tömb következő elemeiben most éppen egy - egy memóriacím van. Én az emCANrecAdd1 -edik tömbelem után i-vel következő tömbelemben lévő memóriacímre kell hogy írjam DataWord -őt.
Tehát a tömbben emCANrecAdd1 után i -vel van egy mutató, ahová az mutat, oda kell hogy kerüljön DataWord. Működik is rendesen a 2. verziómmal, csak nem értem mi baja van a fordítónak az elsővel.
(#) killbill válasza AZoli hozzászólására (») Nov 21, 2016 / 1
 
Ha egy uInt tipusu valtozoban cimet tartasz (de miert?), akkor azt cast-olas nelkul nem hasznalhatod cimnek. Igy lesz jo:
  1. *(uInt *)(*(&emCANrecAdd1 + i)) = DataWord;
  2.  
  3. // a *(&emCANrecAdd1 + i)  kifejezes az i-edik uInt elem erteke
  4. // ezt pointerre cast-olod:  (uInt *)...
  5. // es csak utana hasznalhatod fel cimkent
  6. // *(uInt *)...
(#) AZoli válasza killbill hozzászólására (») Nov 21, 2016 /
 
Idézet:
„uInt tipusu valtozoban cimet tartasz (de miert?)”

A változók CAN buszon érkeznek külső egységektől, ezek kerülnek a tömbbe. Csak később, futási időben derül ki, hogy ami érkezett az mutató, adat, vagy kiskacsa.

Igen, kipróbálhattam volna a cast-otlást, csak gondoltam hogy egyértelmű kellene legyen a fordítónak hogy mit akarok. Köszi!

Az volt a furcsa, hogy ilyenkor megoldotta a fordító magától:
  1. *emCANrecAdd1 = DataWord;
A hozzászólás módosítva: Nov 21, 2016
(#) killbill válasza AZoli hozzászólására (») Nov 21, 2016 /
 
Ha CAN buszon memoriacim erkezik, akkor ott valami mar regen rossz...
Idézet:
„Az volt a furcsa, hogy ilyenkor megoldotta a fordító magától:”
Mert sz@r az IDE es nem kapcsolja be az erre vonatkozo Warningot. Esetleg kikapcsolja, mert ez default-bol Warning a gcc-n.
(#) Wezuv válasza killbill hozzászólására (») Nov 21, 2016 /
 
Szerintem az a cím nem olyan cím, amilyenre te gondolsz.
(#) killbill válasza Wezuv hozzászólására (») Nov 22, 2016 /
 
Hat milyen cim? Ha egyszer dereferencialja, akkor az olyan cim. Pointernek hasznalja, adatot tesz arra a cimre.
(#) Wezuv válasza killbill hozzászólására (») Nov 22, 2016 /
 
Ok, de miért lenne ez rossz?
(#) killbill válasza Wezuv hozzászólására (») Nov 22, 2016 /
 
Mert egy pointer az az adott program legbelso maganugye. Barminek megvaltozhat a cime egy ujraforditasnal, ezert kulso eszkozok nem tudhatjak, hogy neked a memoriaban hol mi talalhato. Hacsak nem debugger vagy esetleg firmware upload a kerdes targya, nem hiszem, hogy nincs ra jobb megoldas, mint memoriacimeket kuldozgetni CAN buszon.
(#) Wezuv válasza killbill hozzászólására (») Nov 22, 2016 /
 
Mindig van jobb megoldás, de nem mindig vagyunk elég okosak hozzá...
(#) don_peter hozzászólása Dec 4, 2016 /
 
Uraim, lenne egy kérdésem, vagy is segítséget kérnék, mert kicsit beragadt most az agyam.
Van egy szöveg, (string) tömb, amelyben egy szöveg van.
pl.: "Valami Amerika"
Ezt a szöveget kellene nekem teljesen nagybetűssé alakítani.
Tehát a végeredmény: "VALAMI AMERIKA"

Erre hoztam létre 2 tömböt, egyet kicsi betűkkel, egyet pedig nagybetűkkel.
  1. const char ABC[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  2. const char abc[] = "abcdefghijklmnopqrstuvwxyz";


Az elméletem az lenne, hogy a tömb tartamát egyesével vizsgálom, majd ha egyezést észlelek kisbetűnél, akkor kisbetűt cserélem a nagy párjával..., és így tovább.

Miközben írtam ezt a bejegyzést eszembe jutott egy alternatív megoldás, ami szintén nem jött be most:
  1. char betu = 'a';
  2. if(betu&0x60 == 0x60){  
  3.     eredmeny = betu^0x20;
  4. }

Így próbálom nagyra konvertálni, ami működik is, csak az a baj, hogy ha nagy 'A' betű kerül bele akkor is lefut a feltétel és vissza konvertálja kicsire..
Kérném a segítségeteket.

Közben rájöttem, hogy hiányzik a zárójel.
Így már működik..
  1. char betu = 'a';
  2. if((betu&0x60) == 0x60){  
  3.     eredmeny = betu^0x20;
  4. }
A hozzászólás módosítva: Dec 4, 2016
(#) kissi válasza don_peter hozzászólására (») Dec 4, 2016 / 1
 
Szia!

  1. if (('a' <= betu ) && (betu<='z')) eredmeny = betu^0x20;
A hozzászólás módosítva: Dec 4, 2016
(#) killbill válasza kissi hozzászólására (») Dec 4, 2016 / 1
 
  1. if ( islower( betu ) ) eredmeny = toupper( betu );
(#) Hp41C válasza killbill hozzászólására (») Dec 4, 2016 / 1
 
  1. eredmeny = toupper( betu );
A hozzászólás módosítva: Dec 4, 2016
(#) killbill válasza Hp41C hozzászólására (») Dec 4, 2016 /
 
Teljesen igazad van. Tulajdonkeppen csak az if(...) es n ^ 0x20 helyett hasznalhato standard C fuggvenyekere akartam felhivni a figyelmet.
(#) c27 hozzászólása Jan 1, 2017 /
 
Sziasztok!

Egy 18F4431-es picre írok programot C-ben C18 fordítót használok, a pic 40Mhz-ről futna. Egy olyan problémám van, hogy a beállított megszakítás ideje nem annyi, mint amennyinek kiszámoltam. Biztos, hogy jól számoltam, és sehol máshol nem változtatok a timer1 értékén csak a megszakítás elején kapcsolom ki egy rövid időre amíg pár feltételt vizsgálok, majd megkapja az új értéket és elindítom.
A kérdés az, hogy hol lehet olyan rész ahol a timer1 nem számol. Amikor túlcsordul a számláló belép a megszakítás rutinba ez nem tudom mennyi időbe kerül, illetve amíg beírom az új értéket addig is vesztek időt. Sajnos az mplabban nem jöttem rá, hogy hol lehetne lemérni azt az időt amíg a számláló túlcsordul és az új érték belekerül a timer1-be és ismét elindul.
Proteusban annyi le tudtam szimulálni, hogy a megszakításban amíg belekerül az új érték a timer1-be és elindul kb. 4usec, de kb. 20usec csúszásom van összesen. Jó lenne megtalálni az okát.
A program megszakítás része ami a timer1-et érinti:

#pragma code high_vector=0x08
void interrupt_at_high_vector(void){
_asm goto Timer1_ISR _endasm
}
#pragma code
#pragma interrupt Timer1_ISR

//HIGH Priority Interrupt
void Timer1_ISR(void){

//TIMER1 INTERRUPT
PIR1bits.TMR1IF=0;
T1CONbits.TMR1ON=0;

if(switch1==0 || switch1==1 && run!=9){
TMR1H=(Timer_low_freq[POT2]>>8);
TMR1L=Timer_low_freq[POT2];
}

else{
TMR1H=(Timer_high_freq[POT2]>>8);
TMR1L=Timer_high_freq[POT2];
}

T1CONbits.TMR1ON=1;

Ez a rész kb 4-5usec alatt lefut, ha az if feltétel teljesül, ha nem akkor kb 2usec, de ezt is csak a proteusban szimuláltam egy kimenet be-ki kapcsolásával. Márcsak a maradék hiányzó 16-18usec okát kellene megtalálni. maga az idő amit beállítok mindig változik, de kb. mindig 20usec-ig tovább számol, szóval ki lehet kompenzálni, csak kíváncsi lennék mit nem vettem figyelembe.
(#) kissi válasza c27 hozzászólására (») Jan 1, 2017 /
 
Szia!

Az MPLAB-ban nagyon jó a szimulátor, melyiket használod ( IDE vagy MPLABX ) ?!
Következő: »»   136 / 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