Fórum témák

» Több friss téma
Fórum » PIC - Miértek, hogyanok haladóknak
Lapozás: OK   1266 / 1318
(#) Attila86 válasza Attila86 hozzászólására (») Aug 14, 2017 /
 
Illetve van a másik rosszul lejátszott hangfájl, próbáltam megnézni hasonlóképp debuggerben ezt is. Viszont ennek a tömbnek a címe 0x10000! Ez bele sem fér a mutatóba mert az 16 bites! Hogyan lehet az, hogy csak 16 bites egy char* mutató?! Az nagyon kicsi!
(#) pajti2 válasza tomi52 hozzászólására (») Aug 14, 2017 /
 
Az az "NV" másabb "NV", mint mondjuk a flash memóriák esetében. Az az "NV" csak annyit jelent, hogy van mellé tápfesz megoldva olyan alacsony energiaszinten, mint egy kvarcórához a gombelem, és eltart egy ideig, mire le fog tudni merülni. Dióhéjban: marketing hype. Egy akármilyen pic10/12 vagy valami újabb low power cuccot veszel, amihez raksz egy tuti pontos kvarcot, akkuról meghajtod, a mezei timerén számolod az ütemjeleket, ugyan úgy van egy nem felejtő rtc-d.
(#) pajti2 válasza cross51 hozzászólására (») Aug 14, 2017 /
 
Hát egy kicsit sikerült egybedarálni az ömlesztett vegyes felvágottat, de azt hiszem, értem a kérdés lényegét.

A lényegre válaszolva, adási irányban is használhatsz megszakítást, ha igényled, de akár elhagyható is. A megszakítás lényege, hogy időben olyankor van adat kezelési kényszered, amíg talán másvalamit csinál a főciklusod, ami mégsem ülhet ölbe tett kézzel egész nap arra várva, mikor fog vagy nem fog adat érkezni. Szóval fut a főciklus, és majd foglalkozik az adattal, amikor jön. Ha a beérkező adat olyan helyre kerül, ahol tuti nem fut rá a következő adat addig, míg a főciklus kényelmesen végig fut, akkor megszakításra semmi szükség nincsen. A főciklus elérkezik oda is, pollozással ránéz az adattárolóra, és kiveszi az adatot. Adási irányban az annyit jelent, hogy betölti. Megszakítás használatával egy kicsit gyorsabb lehet a kommunikáció egyes esetekben. Pic32-esekben például van vagy 4 byte-os uart buffer, és azt akár ha 115200-al hajtod is, a 32 bit eltart 270 uSec ideig, míg kimegy, annyi idő pedig temérdek sok egy főciklusnak végig futni, ami normálisan van megírva, és tuti nem kap blokkot sehol sem. A probléma akkor kezdődik, amikor valamelyik komponens low quality. Szóval adásnál is meg lehet tenni, hogy jelezze csak interrupt, mikor kell rá figyelni.

Az adatbufferek felépítése gondolom nem fog gondot okozni, a trükk csak a megszakítási flagek kezelése. A megszakítási engedélyt a főciklus kapcsolja be, amikor pld első alkalommal azt látja, hogy hiba flag van jelezve valami statikus változóban. Például a device reset alapinit kapcsolhatja azt be első alkalommal, később pedig az utolsó uart transmit interrupt. Amikor a főciklus azt látja, hogy az adat küldő gépezet le van halva, és adatokat rak éppen a kimeneti bufferbe, első alkalommal "bebikázza" az adat küldést: kikapcsolja a hiba flaget, visszakapcsolja az interruptot, és utána az első byte-ot saját kezűleg tölti át a kimeneti regiszterbe. Később az interruptok majd beszipkázzák a többit. Az utolsó byte után olyan interrupt fog érkezni, ami nem fog adatot találni a kimeneti bufferben, olyankor az interrupt rutin tiltja le a saját további élezését, és kapcsolja fel a hiba flaget a főciklusnak jelezni, hogy ha lesznek még kimeneti adatok, újra be kell majd indítani a küldési gépezetet.

Van olyan lehetőség is pld uu64 kommunikációnál, hogy az uart saját magát tömi 0x00 byte-okkal, amikről a túloldal tudja, hogy nem értékes byte-ok, és csak dobálja el őket. De az nem valami elegáns megoldás energetikailag. Az persze az egyik előnye, hogy olyan módon sosem kell interrupt engedélyezést kapcsolgatni, csak egyszer felkapcsolni, és had fusson, mint ahogy az is előnye, hogy külön kontrol és adat csatorna szervezhető úgy az uart kommunikációra. Ha éppen olyasmit bütykölsz, azt a megoldást is választhatod.

Nagyjából érthető a flow control?
(#) Attila86 válasza Attila86 hozzászólására (») Aug 14, 2017 /
 
Megvan!
A két mutató elé beírtam azt hogy __psv__, így:
  1. __psv__ u8  *most;
  2. __psv__ u8  *vege;

Illetve a függvény bemeneti paraméterénél is átírtam:
  1. void Hanglejatszas_start(HangLejatszas_type *Hang, __psv__ u8 *fajl, u16 meret)

Így minden probléma megoldódott: A 0x331E íródik bele nem pedig a 0xB31E, továbbá lejátssza a 0x10000-res címen kezdődő tömbböt is.
(#) cross51 válasza pajti2 hozzászólására (») Aug 14, 2017 /
 
Világos. Most az elmélkedést végül felhasználtam épp az egyik projektben van UART használva. Mivel percek telnek el küldés és küldés között így nem kell nagyon flow control-al foglalkoznom, hogy mikor adhat át a fő ciklus adatot vagy mikor nem.

Azért írtam át interrupt-ra mert ez még egy egyszerű felhasználás, mikor kicsit összetettebb lesz és folyamatosan sok adat megy ki akkor jöhet a flow control / flag-ek de ahhoz már lesz egy alap, hogy induljak el.
A hozzászólás módosítva: Aug 14, 2017
(#) Hp41C hozzászólása Aug 14, 2017 / 1
 
(#) tomi52 válasza killbill hozzászólására (») Aug 14, 2017 /
 
Idézet:
„Ertelek. Ha te megelegszel azzal, hogy mukodik, de nem tudod, hogy mitol, akkor nem erolkodom tovabb.”
Nem elégedtem meg, újra elővettem a témát. Úgy tűnik, talán sikerült kibogoznom a problémát, a ciklusokban már nincs szükség az időzített várakozásokra.
Ami még mindig kell, az az írás és olvasás közti várakozás. Erre nem jöttem rá, hogyan lehetne kiküszöbölni, vagyis hogyan kérdezhetem meg az EEPROM-tól, hogy készen áll-e újabb műveletre?
(#) Attila86 hozzászólása Aug 19, 2017 /
 
Soha nem volt még szükségem sleep vagy idle módokra, idáig. Most azonban el kellene küldenem a PIC-et idle módba hogy kevesebbet fogyasszon. A programom nagyvonalakban a következőképpen néz ki:

A főprogram egy while(1) végtelen ciklusban flagbiteket (nem perifériák hardveres megszakítási flagbitjeit!) ellenőriz hogy 1-be álltak-e. Ha igen, akkor törli az adott flagbitet és végrehajtja a szükséges dolgokat, majd visszatér a flagbitek végtelen vizsgálatához.

A flagbitek a megszakításokban vannak 1-be állítva. Van kb 6-8db megszakítási forrás (timerek és UART-ok). Ha beérkezik egy megszakítás akkor azt kiszolgálja, matekol egy kicsit majd az említett (a főprogramban figyelt) flagbitek valamelyikét 1-be állítja. Vagy nem. Nem mindig állítja egybe, ez különböző dolgoktól függ és ez itt most lényegtelen. A fontos csupán annyi, hogy a megszakítások a főprogramnak ezeknek a flagbiteknek a segítségével jeleznek.

Ez így tök szuperül működik, csak most szeretném hogy amikor nincs dolga a PIC-nek, akkor menjen el idle módba. Például vegyük az egyik timert, amely 1ms-onként okoz megszakítást. Ennek a megszakításnak a kiszolgálásában van egy static változó melyet inkrementálgatok és ha eléri az 1000-ret akkor nullázom és az egyik flagbitet 1-be állítom. Ebben az esetben a megszakításból return-el térne vissza a PIC, hogy a főprogramban végig tudja nézni a flagbiteket. Ha azonban nem érte el a számláló az ezret, akkor nincs értelme tovább működnie ezért itt, a megszakítás kiszolgálásának végén szintén idle-be küldeném.

Ez így működhet?
Rajzoltam is:
(#) tomi52 hozzászólása Aug 19, 2017 /
 
Teljesen alap kérdésem van, de lényegében a C++-t "menet közben" tanulom. Az Arduinoban a library forrásoknak a "h" részét kellett #include-al beillesztenem a főprogram elejébe, az hozta magával a hozzá való cpp-t. Most az MPLAB-X / XC32-ben csak akkor fordul hibátlanul, tudja feloldani a hivatkozásokat, ha a cpp-t hozom be #include-al. Az include-ált forrásokban osztályok vannak.

Azt hiszem, ez így nem korrekt, valamikor az ősidőkben, amikor valamennyit foglalkoztam C-vel (nem ++-al), akkor is csak a "h"-t kellet behoznom. Mit csinálhatok rosszul? Egyáltalán, kell-e több információ a kérdésem megválaszolásához?
(#) pajti2 válasza tomi52 hozzászólására (») Aug 20, 2017 /
 
Kicsit el van micsodálva az a szerkezet, ha .h állományokban vannak a classok. A .h állományokban #def-ek, változók, és függvény fejlécek helye van. Az osztályok forrásának .cpp állományban van a helye. A fordítási hibát a mákostészta-projectekben jellemzően az okozza, ha tisztázatlan a szerkezet, és többször húzná be ugyan azt az állományt.

Ha mást nem, legalább a preprocesszornak rakd bele a header-ekbe, hogy csak egyszer húzhassa be a fordító
#ifndef this_file
#define this_file
...a teljes akármilyen file...
#endif
és akkor include-olhatod szanaszét bárhová, akár header, akár forrás. De jobb lenne inkább "rendet rakni". A "this_file" helyére természetesen mindig az aktuális file nevét rakd be.
(#) tomi52 válasza pajti2 hozzászólására (») Aug 20, 2017 /
 
Az a helyzet, hogy úgy van felépítve, ahogy Te is írod. A " .h állományokban #def-ek, változók, és függvény fejlécek ", .cpp állományban az osztály függvényei. Ez is megvan:
#ifndef this_file
#define this_file
...a teljes akármilyen file...
#endif
Képtelen vagyok megtalálni, mi lehet rosszul. Ugyan ilyen felépítéssel az Arduino-ban működött, ahogy a "nagykönyvben meg van írva". Érzésem szerint valami apróságot bökhetek el, de azt nagyon.

A másik "nem értem" dolgot inkább képben mellékelem. Ennek ellenére a fordítás nem jelez hibát, a program fut.

xc32.png
    
(#) pajti2 válasza Attila86 hozzászólására (») Aug 20, 2017 /
 
Lehet mindenfélét bütykölni, ha te csinálod a cuccot, a teljes alkotói szabadság jár ki neked. Élvezd! Ezernyi dolog mind működni tud.

Van pár olyan dolog is, ami annak alapján van kinevezve "best practice"-nek, hogy ha 1-2 évvel később visszatérsz ugyan ahhoz a projecthez, utólag ne szégyenkezz a saját trehányságaid miatt, hanem egy ollózható minőségű tiszta kódot találj. De azok mentén építeni mindig minden projectedet tiszta nyűg és "eridjen a fenébe" halom sok tennivaló. Csak akkor térj rá azokra a technikákra, ha van hozzá hangulatod. Mégis csak hobby-ról van szó.
(#) pipi válasza Attila86 hozzászólására (») Aug 20, 2017 /
 
A főprogram végtelen ciklusába tedd a sleep-et
(#) pajti2 válasza tomi52 hozzászólására (») Aug 20, 2017 /
 
Ha nem talál meg egy változót, hogyan tud lefordulni??
(#) tomi52 válasza pajti2 hozzászólására (») Aug 20, 2017 /
 
Idézet:
„Ha nem talál meg egy változót, hogyan tud lefordulni??”
Hát ez az! Erre lennék kíváncsi én is. És azt el is felejtettem leírni, ha beteszek csak úgy kamuból egy nem is használt második paramétert is, akkor meg nincs hibajelzés.
(#) Attila86 válasza pajti2 hozzászólására (») Aug 20, 2017 /
 
Jó oké, én arra vagyok kíváncsi hogy van-e valamilyen logikai hiba az elképzelésemben. Kettőt talán találtam:

1.: A főprogram valamelyik flagbitet 1-ben találja, ezért törli, majd végrehajtja azokat amiket kell neki. Az ábráimon a "..."-al jelölt kockára gondolok. Míg ebben a kockában fut, aközben beérkezik egy megszakítás. A megszakítás lekezelődik, majd a végén elküldi a PIC-et aludni. Pedig nem szabadna, hiszen így a főprogramban a "..."-al jelölt rész végrehajtása félbeszakad!

2.: Kb ugyan ez történik, csak megszakításokkal: Beérkezik egy megszakítás, mely lekezelése közben beérkezik egy másik megszakítás is. Az első még nem fejeződött be, de tegyük fel hogy ő return-el fejeződne be. Viszont a másodikként beérkezett megszakításnak Idle()-vel lesz vége, azaz az első megszakítás ugyan úgy mint az első példában, félbeszakad.
(#) _BiG_ válasza Attila86 hozzászólására (») Aug 20, 2017 /
 
Az lehetne opció, hogy egy feltételt beleteszel a ciklus végére, hogy ha valamennyi flag 0, csak akkor menjen idle állapotba? Egész addig, amíg ez nem teljesül, fusson csak a főciklus továbbra is és kezelje le őket.
Tehát a megszakításban nem küldöd a PIC-et pihenni (miért is tenné, hiszen a leírásod alapján a megszakítás csak flag-et állít), csak a főprogramban, de csak akkor, ha mindennel végzett.
(#) Attila86 válasza _BiG_ hozzászólására (») Aug 20, 2017 /
 
Közben megoldottam úgy, hogy a főprogramban való altatás (idle) előtt 1-be állítok egy változót, ébredés után meg nullázom. A megszakítások végén pedig ha a megszakítás arra a döntésre jut hogy altatni kell, akkor még ide betettem egy feltételvizsgálatot hogy a főprogramban az a változó igaz-e vagy hamis. Tehát a megszakítások csak akkor altatják a PIC-et, ha a megszakítás előtt, a főprogramban egyébként is aludt.
Így néz ki tehát a main:
  1. while(1)  
  2. {
  3.     if(A)
  4.     {
  5.         A=0;
  6.         //...
  7.     }
  8.     if(B)
  9.     {
  10.         B=0;
  11.         //...
  12.     }
  13.     if(C)
  14.     {
  15.         C=0;
  16.         //...
  17.     }
  18.     FoprogramAlszik=1;
  19.     Idle();
  20.     FoprogramAlszik=0;
  21. }


Egy megszakítás pedig így:
  1. void _T1Interrupt(void)
  2. {
  3.     IFS0bits.T1IF=0;
  4.     //...
  5.     if(???) //Ha kell a főprogram számára jeleznünk, akkor:
  6.     {
  7.         A=1;    //Flagbit bebillentése
  8.         return; //A főprogram ébresztése!
  9.     }
  10.     else    //Ha nem kell jeleznünk a főprogramnak, akkor:
  11.     {
  12.         if(FoprogramAlszik) Idle(); //Ha a főprogram alszik akkor visszaaltatjuk a PIC-et
  13.         else return;    //Ha nem alszik a főprogram, akkor nem altatunk.
  14.     }
  15. }

Na így most nagyon szuperül működik az egész. Megkértem a timer8-at és a timer9-et hogy 32 bites számlálóként számolják az ébren töltött idejét a PIC-nek és ebből százalékot számítok. Átlagosan kb 7,3%-ot van csak ébren (pontosabban nem idle módban) a PIC. A teljes elektronika energiafelhasználását ezzel 14%-al sikerült csökkentenem.
A hozzászólás módosítva: Aug 20, 2017
(#) _BiG_ válasza Attila86 hozzászólására (») Aug 20, 2017 /
 
Azaz a megszakításban altatod el? Hm, fura. Ha több megszakításod van, akkor annyiszor vizsgálsz feltételt és annyiszor adod ki a "nyugoggyámále" parancsot.
Az én elgondolásom rövidebbnek tűnik és egyszerűbbnek, a megszakítások is rövidebbek. Nem beszélve a logikai kapcsolódásról: csak a főprogram tétlensége okoz alvást és ez a kódból egyértelműen látszik.
(#) Attila86 válasza _BiG_ hozzászólására (») Aug 20, 2017 /
 
Igazad van! Valóban úgy egyszerűbb és átláthatóbb az egész. Viszont ha a megszakítások nem billentenek be flagbitet, akkor felesleges a főprogramban levizsgálni őket, azaz a vizsgálatukkal töltött ébrenléte a PIC-nek ez esetben felesleges. Ki is próbáltam: kb 0,1%-kal nőtt az ébren töltött idő ha a megszakításokban semmilyen módon nem altatok.

Van például egy 62,5us-onkénti timer megszakításom is (16kHz-es hanglejátszáshoz), bár ennek kiszolgálása nagyon rövid ideig tart, viszont mivel borzasztóan sűrű ezért totál felesleges feltételvizsgálatokra kényszeríti az általad vázolt esetben a főprogramot.
(#) _BiG_ válasza Attila86 hozzászólására (») Aug 20, 2017 /
 
Idézet:
„Van például egy 62,5us-onkénti timer megszakításom is (16kHz-es hanglejátszáshoz), bár ennek kiszolgálása nagyon rövid ideig tart, viszont mivel borzasztóan sűrű ezért totál felesleges feltételvizsgálatokra kényszeríti az általad vázolt esetben a főprogramot.”

Az is lehet, te látod, mit csinálsz
Vagy kétfelé szedni a dolgot, a sűrű megszakítás altasson, a többi nem, csak a főprogram. Hm?
(#) Attila86 válasza _BiG_ hozzászólására (») Aug 20, 2017 /
 
Marad így, az a 0,1% is számít.
(#) AZoli válasza Attila86 hozzászólására (») Aug 20, 2017 / 1
 
Lehet hogy használod, de leírom. A PMD1-7 regiszterek bitjeinek 1-be állításával le tudod kapcsolni a nem használt perifériákat, ez is jelentős fogyasztás csökkentés. DMA, CAN, stb.
(#) cross51 hozzászólása Aug 20, 2017 /
 
Sziasztok!

Hp41C nemrég megosztott egy linket velünk az ICD4-ről. Én bele olvastam a User Guide-ba és azt láttam hogy egy 300MHz PIC32C van benne csodálkoztam rajta mert még sose láttam ilyen család kódot. Ma letöltöttem az MPLABX 4.0-át és ott láttam, hogy ez egy ARM alapú PIC32 tud esetleg erről valaki valamit?
(#) Attila86 válasza cross51 hozzászólására (») Aug 20, 2017 /
 
Én nem tudom, de ha tényleg gyors és nem olyan bugos mint a PICkit3 akkor veszek egyet az tuti!
(#) rolandgw válasza cross51 hozzászólására (») Aug 20, 2017 /
 
Egyenlőre csak találgatás megy a fórumokon, valószínűleg átnevezett Atmel SAM-ok.Az ARM GCC már integrálva van az MPLAB 4-be.Szerintem összevonják az IDE-t, mint ahogy az NXP és a Freescale is tette nemrég.
(#) cross51 válasza Attila86 hozzászólására (») Aug 21, 2017 /
 
Attila86:
Itt is HS USB egy Spartan 6 FPGA és a 300MHz-es PIC32 ami az ICD3-mal szemben biztos gyorsabb (ha jól láttam 40 mips-es az a dspic ami az ICD3-ban van).
Valamint az ICD3 gyorsabb kevesebb probléma van vele mondhatnám úgy is, hogy csak néha fossa össze magát, de akor USB ki-be és megy tovább szépen.
Esetleg ha érdekel valakit régen találtam egy pdf-et amiben megvan az ICD3 scheamtic-ja
Bővebben: Link.
rolandgw:
Lehetséges, hogy ki viszi a piacról az Atmel nevet a Microchip? Csak, hogy találgassunk mi is egy kicsit
(#) rolandgw válasza cross51 hozzászólására (») Aug 21, 2017 /
 
Szerintem igen. Ekkora SAM választék mellett elég fura lenne egy cégen belüli rivalizálás ARM ügyben. Majd kiderül
(#) tomi52 hozzászólása Aug 21, 2017 /
 
Gondoltam, egy másik gépen kipróbálom az MPLAB-X és XC32 legújabb verzióit. Mivel MX-es PIC-em van, telepítettem a "PIC32_Legacy_Peripheral_Libraries"-t is. Ez az XC1.40-es verziónak megfelelő könyvtárakat teszi fel. Csak azt nem tudom, hogyan kellene beállítani, hogy ezt meg is találja? A fordítás ott elbukik, hogy nem találja a "plib.h"-t. Próbáltam az 1.40-es könyvtárat ugyan úgy beállítani, ahogyan a saját "include" könyvtárammal működik, de nem vált be. Nem jól csináltam, vagy valami egész más dolgot kell művelni, nem tudom.
(A gépen 32 bites kubuntu 14.04 LTS van.)
(#) pajti2 válasza Attila86 hozzászólására (») Aug 21, 2017 / 1
 
Megszakításból altatni a pic-et elég meredek dolog, de ha stabilan működik, ám használd. Kicsit denormalizáltnak tűnik úgy a flow control, de a legjobb teljesítményt mindig az olyan megoldásokkal lehet elérni. A hátrányuk csak annyi, hogy hosszú idő múlva ha előszeded azt a projectet, majd vakarni fogod a buksit alaposan, hogy mi a rákot műveltél anno. Ha azt a projectet el akarod tenni magadnak későbbre, nagyon alaposan dokumentáld le!
Következő: »»   1266 / 1318
Bejelentkezés

Belépés

Hirdetés
Lapoda.hu     XDT.hu     HEStore.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