Fórum témák

» Több friss téma
Fórum » PIC - Miértek, hogyanok haladóknak
Lapozás: OK   1198 / 1319
(#) Attila86 hozzászólása Aug 16, 2015 /
 
Valóban, digitálisra kellett állítani az ANSELG-ben. Hogy ez nekem nem jutott eszembe...
Köszönöm a segítséget!
(#) Zsora válasza Attila86 hozzászólására (») Aug 16, 2015 /
 
Ahogy potyo mondja...
A komparátor az analóg funkció, tehát azt tiltani kellene, különben a digitális bemenet fix 0-ra lesz kötve.
Szerk.: Ja bocs! Ezzel már elkéstem.
A hozzászólás módosítva: Aug 16, 2015
(#) Attila86 hozzászólása Aug 21, 2015 /
 
Belegabalyodtam egy kicsit a mutatókba:
Van egy tömböm amely így néz ki:
  1. __prog__ unsigned char ossian[] __attribute__((space(prog))) =
  2. {
  3. 130,127,125,123,124,124,
  4. };

A tömb ennél valójában sokkal nagyobb (több tízezer bájt) de értelem-szerűen nem másoltam ide be az egészet.
A tömbböt egy függvény bemeneti paramétereként szeretném használni:
  1. HangLejatszasStart(&ossian);

A függvény pedig így néz ki:
  1. void HangLejatszasStart(u16 *hangfajlcim)
  2. {
  3.     Hang.lejatszas=1;
  4.     Hang.pozicio=0;
  5.     Hang.fajl=hangfajlcim;
  6.     Hang.meret=sizeof(*hangfajlcim);
  7.     OC1CON1bits.OCM=0b110;  //PWM bekapcsolása
  8. }

A struktúra ami benne van pedig így:
  1. typedef struct
  2. {
  3.     u8  pozicio;       //Megmutatja hogy hangfájlban épp hol tartunk
  4.     u8  *fajl;         //Az épp aktuálisan játszott hangfájl memóriacíme (u8 számok vannak a tömbben amire mutathat)
  5.     u32 meret;         //A hangfájl mérete (bájtban)
  6.     u8  lejatszas :1;  //Ha folyamatban van lejátszás akkor 1, ha nincs akkor 0
  7.     u8  reserved :7;
  8. }HangLejatszas_type;


62,5us-onként meghívódik az alábbi függvény:
  1. void HangLejatszasFolyamat(void)
  2. {
  3.     if(Hang.lejatszas)
  4.     {
  5.         Hang.pozicio++;  //Ha folyamatban van hanglejátszás, akkor inkrementáljuk a hangpozíciót!
  6.         if(Hang.pozicio>Hang.meret) HangLejatszasStop();     //Ha a hangfájl végére értünk, akkor leállítjuk a lejátszást!
  7.         else OC1R=*Hang.fajl[Hang.pozicio];    //Ha még nem értük a fájl végére akkor betöltjük a PWM-be a hangfájl következő elemét
  8.     }
  9. }


A kérdésem az, hogy mit rontottam el? Van egy gyanúm hogy már a struktúrában a tömb-mutató definiálása sem jó, a többi meg még biztosabb hogy nem.
A hozzászólás módosítva: Aug 21, 2015
(#) Zsolt2 válasza Attila86 hozzászólására (») Aug 21, 2015 /
 
A hang lejatszas fuggvenynel nem kell hasznalni az "&" jelet, tombnek a neve mar eleve pointer a tombre, ebben a formaban **u8 tipus adodik at. A sizeof fuggveny poitert var parameternek, itt is folosleges a csillag (igy az unsigned char-nak a meretet adja meg, ami =1). Igy elso ranezesre ezek voltak a hibak.
(#) Attila86 válasza Zsolt2 hozzászólására (») Aug 21, 2015 /
 
Köszönöm!
A fordítónak még ezzel a sorral volt gondja:
  1. else OC1R=*Hang.fajl[Hang.pozicio];

Csillag nélkül már tetszik neki, bár nem vagyok benne biztos hogy jó is lesz.

Illetve, ez a sor & nélkül sem tetszik neki:
  1. HangLejatszasStart(ossian);

Ezt mondja rá:
error: passing argument 1 of 'HangLejatszasStart' from pointer to non-enclosed address space
(#) killbill válasza Attila86 hozzászólására (») Aug 22, 2015 /
 
Idézet:
„Hang.meret=sizeof(*hangfajlcim);”

A sizeof()-ot a C fordito ertekeli ki forditaskor, nem tudja egy pointer alapjan eldonteni, hogy milyen hosszu a hangfajlod. Azt viszont tudja, hogy a hangfaljcim valtozo u16 tipusra mutato pointer, ezert ennek a kifejezesnek az erteke 2 lesz, mert a (* hangfajlcim) egy u16.

A 'pozicio' 8 bites, nem lesz jo pozicionak, hiszen a meret is 32 bites.

Az OC1R sorral meg az a baj, hogy a Hang.fajl[ Hang.pozicio ] az mar eleve egy byte, az ele mar nem kell a '*'. Akkor kellene a *, ha azt irnad, hogy *Hang.fajl + Hang.pozicio;

Egy jo megoldas, ha nem poziciot tarolsz, amit minden egyes hasznalatkor hozza kell adni a fajl kedzocimehez, hanem tarolsz egy pointert, ami folyamatosan novekszik, es tarolsz egy masik pointert, ami a fajl veget jelenti. Igy a lejatszas kozben (ami ugye sokszor fut le) nem kell kiszamolni ugyanazt szazezerszer.

  1. ...Start(u16 *hangfajlcim, u32 meret)
  2. {
  3.   hang.vege = hangfajlcim + meret;
  4.   hang.most = hangfajlcim;
  5. }
  6.  
  7. ...Folyamat(void)
  8. {
  9.   if(Hang.lejatszas){
  10.     if(hang.most == hang.vege)
  11.       HangLejatszasStop();
  12.     else
  13.       OC1R = *hang.most++;
  14.   }
  15. }
(#) killbill válasza killbill hozzászólására (») Aug 22, 2015 /
 
Idézet:
„*Hang.fajl + Hang.pozicio;”
Termeszetesen *(Hang.fajl + Hang.pozicio) akart lenni, bocs!
(#) killbill válasza Attila86 hozzászólására (») Aug 22, 2015 /
 
Még valami. Eleve nem stimmel a pointer tipusa, amit hasznalsz. A tomb unsigned char elemekbol all. Ezert a HangLejatszasStart() fuggveny is ilyen tipusu adatra mutato pointert kellene varjon, nem pedig u16 pointereket. Az u16 * valami; az nem azt jelenti, hogy egy 16 bites valtozo, ami pointer, hanem azt, hogy egy olyan pointer, ami u16 tipusu elemekre mutat. A pointer meg annyi bites, amennyi, ez architekturafuggo. A PIC-en valoszinuleg 16 bites.
Szoval javitva:
  1. static struct {
  2.   u8   *most;      // eppen aktualis minta cime
  3.   u8   *vege;     // az utolso minta utani cim
  4.   u8   lejatszas; // flag
  5. } hang;
  6.  
  7.  
  8. ...
  9.    HangStart(ossian, sizeof(ossian));
  10. ...
  11.  
  12. void HangStart(u8 *fajl, unsigned int meret)
  13. {
  14.   hang.lejatszas = 0;  // biztosan ne dolgozzon a megszakitas rossz adattal
  15.   hang.most = fajl;
  16.   hang.vege = fajl + meret;
  17.   hang.lejatszas = 1;  // indul a mandula
  18. }
A hozzászólás módosítva: Aug 22, 2015
(#) Attila86 válasza killbill hozzászólására (») Aug 22, 2015 /
 
killbill köszönöm! Így már sokkal világosabb. Valóban, még a struktúrában a pozicio változó típusát is elrontottam...
Az meg nagy ötlet hogy nem kell mindig kiszámítani a pozíciót! Mondjuk igazából csak egy összeadás, amielvileg csupán pár utasításciklus. De így tényleg elegánsabb, át is írtam ahogy tanácsoltad.

Viszont továbbra sem fordul le sajnos. Erre a sorra:
HangLejatszasStart(ossian,sizeof(ossian));

Ezt írja:
Idézet:
„megszakitasok.c:91:9: error: passing argument 1 of 'HangLejatszasStart' from pointer to non-enclosed address space”
(#) potyo válasza Attila86 hozzászólására (») Aug 22, 2015 /
 
Keress rá erre a hibaüzenetre, microchip fórumán is írnak róla. Nem olvastam végig, csak láttam, hogy valami fordító verzióról is szó van benne.
(#) killbill válasza Attila86 hozzászólására (») Aug 22, 2015 /
 
Idézet:
„Az meg nagy ötlet hogy nem kell mindig kiszámítani a pozíciót! Mondjuk igazából csak egy összeadás, amielvileg csupán pár utasításciklus.”
Egy osszeadas plusz még egy valtozo felszedese a memoriabol. De valoban nem sok, de az alapelv, hogy ha megszakitast lehet roviditeni, akkor roviditsuk. A masik, hogy ha valamit egy cikluson kivul ki lehet szamolni egyszer, akkor azt nem szabad egy ciklusban szazezerszer kiszamolni. Ez ilyen beidegzodes.

A hibauzenetre az egyetlen otletem, a const. Ha jol emlekszem, a 16 bites PIC-eken a const jol mukodik, tehat:

const u8 ossian[] = {...};

A const miatt csak a flash-be teszi, de valami ravasz trukkel siman tudja olvasni, mintha RAM data lenne. Talan valami legfelso cimbit a pointerben 1. Mar nem emlekszem pontosan. Ez mindig szivas a Harvard architekturas processzorokon, ahol nincs bus matrix... Ki kell probalni, vagy el kell olvasni az adott C fordito leirasat ezzel kapcsolatban.
(#) Attila86 válasza killbill hozzászólására (») Aug 22, 2015 /
 
A sima const előtagos forma korábban azért nem volt jó mert nem engedte a fordító a több tízezer (több mint százezer) bájtos tömböt beletenni a programmemóriába. Eredetileg ugyanis próbaképp beletuszkoltam egy ossian zeneszámból kb 20 másodpercet 16kHz-es mintavétellel. Akkor áttúrtam a netet és találtam valahol hogy így jó lesz:
__prog__ unsigned char ossian[] __attribute__((space(prog))) =

És jó is lett. Most azonban csak nagyon rövid kis hangfájlok kellenek ezért erről lemondtam és átírtam a normál formára:
const unsigned char hangfile_erintes[] = {...};

Így van négy kis hangom egy hangok.c fájlban. És készítettem hozzá egy header fájlt is:
  1. const unsigned char hangfile_erintes[];
  2. const unsigned char hangfile_lezar[];
  3. const unsigned char hangfile_felold[];
  4. const unsigned char hangfile_toltes[];


Majd ezt a headert beinclude-oltam két c fájl tetejére amelyekben szeretnék hanglejátszásokat indítani.
Így hivatkozom (például) a tömbökre:
  1. if(TFT.Uzem!=0) HangLejatszasStart(hangfile_lezar,sizeof(hangfile_lezar));
  2. if(TFT.Uzem==0) HangLejatszasStart(hangfile_felold,sizeof(hangfile_felold));


Viszont a fordító rendre ezt írja ezekre a sorokra:
megszakitasok.c:91:65: error: invalid application of 'sizeof' to incomplete type 'unsigned char[]'

Ha nem a headert hanem magát a c fájlt include-olom be akkor abban a fájlban működik a dolog. Viszont legalább két c fájlnak látnia kellene a const tömbböket hogy a másik fájlból is indítható legyen lejátszás. Ha meg mindkét helyre include-olom a tömböket akkor kétszer annyi helyet foglalnak a hangok a memóriában ami nyilván nem lenne előnyös.
A hozzászólás módosítva: Aug 22, 2015
(#) killbill válasza Attila86 hozzászólására (») Aug 22, 2015 /
 
Igen, a sizeof() csak annak a tombnek tudja a hosszat, amit forditaskor ismer. Mivel te a header-ben ismeretlen meretu kulso valtozot deklaralsz (elvileg illene ele az extern is), igy a fordito nem tudja, hogyu mekkora a tomb. Egyebkent ha csinalsz ket kulon .c file-ban ket azonos nevu valtozot, akkor annak csak egyszer fogja lefoglalni a helyet a linker, azaz csak egyszer lesz meg a memoriaban. Eppen ezert nagyon veszelyes a globalis valtozok hasznalata, foleg a rovid (i, j, stb) valtozonevekkel. A problemadra nincs jo otletem, mert egy inicializalt tomb meretet csak abban a file-ban tudja a fordito, ahol inicializaltak. Max. annyit csinalnek, hogy a lejatszo .c file-ba include-olnam a data .c file-okat (a zeneket) es esetleg adnek sorszamot a zeneknek:
  1. Egy headerben:
  2. enum {
  3.   SOUND_ERINTES = 0,
  4.   SOUND_LEZAR,
  5.   SOUND_FELOLD,
  6.  
  7.   SOUND_MAX
  8. };
  9.  
  10. int HangJatszik(unsigned int which);
  11.  
  12.  
  13. Lejatszo .c file-ban:
  14.  
  15. #include <a_fenti_header_file>
  16.  
  17. static const unsigned char erintes[] = {...};
  18. static const unsigned char lezar[] = {...};
  19. static const unsigned char felold[] = {...};
  20.  
  21. // Maga a harom vagy akarhany tomb lehet fizikailag masik file-ban,
  22. // de ide #include-dal kell behozni.
  23.  
  24. // Ez a tomb tarolja a zenek kezdocimet es hosszat
  25.  
  26. static struct {
  27.  unsigned char *data;
  28.  size_t len;
  29. } sounds[] = {
  30.   [SOUND_ERINTES]  = {erintes, sizeof(erintes)},
  31.   [SOUND_LEZAR]    = {lezar, sizeof(lezar)},
  32.   [SOUND_FELOLD]   = {felold, sizeof(felold)}
  33. };
  34.  
  35. int HangJatszik(unsigned int which)
  36. {
  37.     if(which >= SOUND_MAX)
  38.       return ERROR_TOOBIG;
  39.     hang.megy = 0;
  40.     hang.most = sounds[which].data;
  41.     hang.vege = sounds[which].data + sounds[which].len;
  42.     hang.megy = 1;
  43.     return ERROR_OK;
  44. }
  45.  
  46. Ahonnan lejatszod:
  47.  
  48. #include <a_fenti_header_file>
  49.  
  50.    ...
  51.    HangJatszik(SOUND_ERINTES);
  52.    ...
A hozzászólás módosítva: Aug 22, 2015
(#) Attila86 válasza killbill hozzászólására (») Aug 23, 2015 /
 
Hát... kár hogy nem lehet ezt elegánsabban megoldani. Sikerült megértenem a kódot amit most írtál, de ez már nagyon nyakatekert szerintem.
Létrehoztam 1-1db u16 változót minden hangfájlhoz, melyben a méretüket tárolom. A hangfajlok.c végére pedig beírtam ezt:
  1. void Hangmeretek_kiszamitasa(void)
  2. {
  3.     hangmeret_erintes=sizeof(hangfile_erintes);
  4.     hangmeret_lezar=sizeof(hangfile_lezar);
  5.     hangmeret_felold=sizeof(hangfile_felold);
  6.     hangmeret_toltes=sizeof(hangfile_toltes);
  7. }

Hiszen itt, ezen a fájlon belül ugyebár még "látja" a tömbök méretét a sizeof.
A PIC induláskor pedig meghívom ezt a függvényt és kész.
Ez sem túl elegáns de hát ez van.
(#) killbill válasza Attila86 hozzászólására (») Aug 23, 2015 /
 
Ahogy erzed. Ez elvi kerdes, hogy te a lejatszonak azt akarod megmondani, hogy melyik hangot jatssza le. Ehhez eleg egy parametert atadni neki, megpedig egy sorszamot, vagy nevet, akarmit, amivel az adott hangra hivatkozol. Es innentol kezdve a kulso hivonak nem kell tudni azt, hogy az adott hangfile milyen hosszu. Eppen ettol lesz elegans megoldas. A hivo elol eldugod a szamara irrelevans informaciot, a hangfile hosszat. Senkit nem erdekel, miert kelljen a hivonak ezzel is foglalkoznia. Teljesen felesleges RAM-ban tarolni a hangfile-ok hosszat.

Miert nyakatekert a fenti megoldas? Mert egy logikai ertekkel hivatkozol a hangfile-ra? Nincs ebben semmi kulonos, kevesebb parametert kell atadni, kevesebb a hibazasi lehetoseg, atlathatobb a kod. Megcsinalhatod ugy is, hogy a lejatszo file-ban a sorszam szerint egy switch-case szerkezet az adott hangfile cimet es hosszat hasznalja fel, de a switch-case-nel szebb az a tablazatos megoldas, amit en irtam. Es rovidebb kodot is eredmenyez.
(#) Attila86 hozzászólása Aug 26, 2015 /
 
Itt most mi baja van a fordítónak?
Idézet:
„build/default/production/main.o(.text+0x4): In function `.LSM1':
: undefined reference to `_DelayMs'
build/default/production/main.o(.text+0x6): In function `.LSM1':
: undefined reference to `_DelayMs'
make[2]: *** [dist/default/production/RFM12_teszt_1.production.hex] Error 255
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2”

A _DelayMs függvény nem tetszene neki valamiért? Na de nem is használom ezt a függvényt a projektben sehol!
(#) cross51 válasza Attila86 hozzászólására (») Aug 26, 2015 /
 
_DelayMs egyenlő a DelayMs függvénnyel, ha esetleg ezt használod a projekteben valahol akkor vagy nincs DelayMs függvény vagy nincs előre deklarálva(fv. prototípus), ha egyáltalán nem használod akkor nem tudom mi lehet a baj.
(#) Attila86 válasza cross51 hozzászólására (») Aug 26, 2015 /
 
Közben megtaláltam, egyetlen helyen használom a main.c-ben. De a féjl tetején be van include-olva a header hozzá:
  1. #include <xc.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <pps.h>
  5. #include <delay.h>
  6. #include <spi.h>
(#) killbill válasza cross51 hozzászólására (») Aug 27, 2015 /
 
A main.c-ben, a .LSM1 fuggveny hivatkozik a _DelayMs globalis cimkere (valoszinuleg fuggveny). A hibat a linker irja ki, nem a C fordito. Esetleg kisbetu/nagybetu elteres nincs valahol a nevben? A C-ben nem mindegy.
(#) ktamas66 válasza Attila86 hozzászólására (») Aug 27, 2015 /
 
Ha jól emlékszem a #define _XTAL_FREQ xxxxxx sorból számolja ki a késleltetést, nem tudom neked meg van-e adva valahol. (Legalábbis XC8-nál.)
(#) Gyimate hozzászólása Aug 27, 2015 /
 
Sziasztok!
Ha valakit érdekel, akkor írtam egy Timerek számolásában segítő kis programot, melyet megtalálhattok Itt
Leírást és az előzményt pedig Itt találjátok meg.
A hozzászólás módosítva: Aug 27, 2015
(#) cross51 hozzászólása Aug 29, 2015 /
 
Sziasztok!

Belső flash memória írással foglalkozom/próbálkozok (C-ben) maga a flash írás olvasás törlés működik, de eszembe jutott, hogy lehetne-e olyat csinálni, hogy létrehozok egy adott méretű konstans tömböt és ennek az elemeit módosítom a flash író függvénnyel. Így nem lenne szükség a flash visszaolvasására és + RAM-ra amiben eltárolom a kiolvasott adatot , mert nekem csak egy string ként kellene karakterek tárolására.

Próbálkoztam ezzel de az adott kód helyett NOP-ok kerülnek a memóriába.

Erre van lehetőség, hogy a konstans tömb elemeit programfutás közben a flash író függvénnyel átírjam?
(#) Attila86 válasza Gyimate hozzászólására (») Aug 29, 2015 /
 
Én ezt szoktam használni:
Bővebben: Link
(#) potyo válasza cross51 hozzászólására (») Aug 29, 2015 /
 
Nagyjából világos a kérdésed, de szerintem többre mennénk, ha mutatnál egy kódrészletet, hogy mire is gondolsz pontosan, ne mi találgassunk.
(#) cross51 válasza potyo hozzászólására (») Aug 29, 2015 /
 
Az igazat megvallva rájöttem a hibára a programmemória üres részre hibátlanul tudtam kódot írni.
De ahol már volt adat oda nem tudtam beírni azt az adatot amit szerettem volna, módosult, de nem arra amire kellet volna. Aztán eszembe jutott, hogy ahol meglévő adat van ott törölni kell az előző adatot és így már "átírható" probléma nélkül.
A hozzászólás módosítva: Aug 29, 2015
(#) nemgyuri hozzászólása Aug 30, 2015 /
 
Sziasztok! Érdekes jelenséggel találkoztam... Infra jeladót kötöttem az egyik (PIC PORTB0) bemenetre. Fordulatszámot mérek megszakításból, gond nélkül. 2500-as fordulat fölé nem ment az esztergám.
Amikor pozíciót akartam mérni, kikapcsolt megszakítás mellett, sima btfss PORTB0 - goto xx - btfsc PORTB0 - goto xx -el csak kb. 300-as fordulatig működött. A hibát megtaláltam, hiányzott egy ~1k-os ellenállás ami lehúzza a bemenetet. Ezt csak azért írtam, le mert a PIC ezek szerint nem ugyanúgy kezeli a bemenetét, ha sima digitális input vagy megszakításból kezelt input. Persze, ha valaki tudja az okot ne kíméljen minket. (szeretünk okosodni)
(#) cross51 válasza nemgyuri hozzászólására (») Aug 30, 2015 /
 
Hello!

Hát most az, hogy ugyanúgy vagy nem ugyanúgy kezeli erre nem tudok válaszolni(szerintem ugyanúgy).A hiba azért történt
Idézet:
„A hibát megtaláltam, hiányzott egy ~1k-os ellenállás ami lehúzza a bemenetet.”
ha a PIC egyik lába bemenetként van használva, ha megszakítás, h,a polling, belső vagy külső fel/le húzás kell vagy különben "lebeg" a láb és így akár azzal is kiválthatsz megszakítást, hogy oda érinted az ujjad.
(#) nemgyuri válasza cross51 hozzászólására (») Aug 30, 2015 /
 
Én is azt hittem, hogy mindegy, de nem volt mindegy, ha polling volt akkor bizonytalan volt a lehúzó ellenállás hiány a miatt - eddig rendben. de megszakításból teljesen stabíl volt a működés! A kijelzett fordulatszámot mindig jól mutatta, ellenőriztem másik fordulatszámmérővel is.
(#) zenetom válasza nemgyuri hozzászólására (») Aug 30, 2015 /
 
Szia!
Elég nehéz így bármit is kideríteni (PIC típus hiányában). Elsőnek azt mondanám, hogy a megszakításnál van egy schmitt-trigger, míg "sima" port bemenetnél nincs. Ezzel szerintem válaszoltam is a kérdésre. De nézd meg a PIC adatlapjában az adott lábhoz tartozó blokksémát.
(#) nemgyuri válasza zenetom hozzászólására (») Aug 30, 2015 /
 
Teljesen igazad van: megszakításnál ST, normál bemenetként TTL. (ja PIC16F886-ról volt szó)
Igy már érthető, köszönöm az iránymutatást.
Következő: »»   1198 / 1319
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