Fórum témák
» Több friss téma |
Fórum » PIC - Miértek, hogyanok haladóknak
Hello!
Még mindig 12F1572 PWM. RGB LED vezérlés. Színkombináció és fényerő USART-on jön. Fényerő változtatása sajnos csak lépcsős bevitellel lehetséges. Ezt szeretném folyamatossá tenni. Példa kedvéért egy 100-as max értékű kitöltési tényezőt 5 lépcsőben változtatok 0-100-ig vagy vissza. A LED-en pedig azt szeretném látni, hogy ez a 20-as lépcső folyamatosan megy végbe mintha potit tekernék. T2 megszakításral gondoltam valahogy úgy, hogy egy lépcső a bevitelen kb 300-500 ms és ezen idő 20-ad részeinként növelném-csökkenteném 1-el a kitöltési tényezőt, csak még nem tudom hogy valósítsam meg, hogy ez minden színkeverék esetében működjön, mert a PWM csatornákat tudom módosítani megszakításban, de az aktuális színbeállítást a főprogram változtatja. Nem tudom érthetően írtam-e le, de beszúrok egy részletet. Jön az adat és a fényerő usarton. Azán a főprogram beállítja a színt az adat alapján.
És ugyebár a megszakítás nem tudja a színkombináció aktuális étékét. Ezt szeretném valahogy megoldani. Van valakinek ötlete, hogy lehetne ezt egyszerűbben megcsinálni?
Esetleg az aktuális, meg a cél értéket külön tárolod. A PWM számlálóra a megszakítást is beállítod. amikor ez bekövetkezik, a két értéket közelíted egymáshoz. Ha utolérte vége, ha nem akkor értelemszerűen a következő lépés ismét ez lesz. Ha egy számlálóval kombinálod, tetszés szerinti fel-lefutási időket érhetsz el.A teljesen analóg azért szerintem nehezen kivitelezhető, mert a pwm időnél rövidebb lépésidőt nem választhatsz, aminek a 100 szorosa meg már szerintem az emberi reakcióidőt eléri. Max olyan lépcsőt választhatsz, ami már nem látszik. ( szerintem a 32- nél nagyobb felbontás már nem feltűnő)
Órámnál a fényerőt úgy állítom, a beírt meg az új mért fényerő érték számtani közepe az új beírt érték, Így gyorsan is beáll, meg nem is annyira lépcsős, és a reakció ideje is elfogadható.
Assembly nyelven nem sok példaprogramot fogsz találni hozzá. Ha ez nem zavar, akkor rajta! Én dugaszolós próbapanelon raktam össze az első PIC24HJ128GP502 próbaáramkört és a munkahelyi PICkit2-vel programoztam fel. Utána boootloaderrel használtam... PIC-kwik projekt, PIC cikkeim
Mondjuk szeretném a C-t is megtanulni de egyenlőre akkor maradok a 18-as szériánál és azon tanulom még az assemblyt. Amikor majd azt már kenem vágom akkor jöhet a C.
Köszi.
Periódus mérésére a ccp modul capture üzemmódja való!
üdv. Foxi
Sziasztok!
Szeretném, hogyha a dsPIC33EP512GP806-nak az RD0 lábára (INT0/RP64/RD0) az SPI1 periféria órajel-kimenete kapcsolódna. Az adatlapja azt írja a 215. oldalon hogy ha az SCK1-et akarjuk valahova kapcsolni akkor 0b000110-át kell írnunk abba az RPnR-be amelyikre kapcsolni szeretnénk, ez esetben az RP65R-be. Hogy ez melyik regiszterben található, arra a 261. oldalon kapjuk meg a választ, mégpedig hogy az RPOR0-ban leledzik. Az adatlap 97. oldalán lévő register map is ezt állítja. Azonban ha beírom a programba, hogy: RPOR0bits.RP65R=0b000110; Akkor az MPLABX azt mondja hogy "Unable to resolve identifier RP65R". Miért?
Adatlap szerint pedig ott van.
Ezen a gépen nincs MPLAB, de ha a RPOR0bits. után nyomsz egy Ctrl+Space -t, (vagy lehet hogy Shift+Space) akkor nem hozza fel hogy szerinte mik vannak a RPOR0 regiszterben? Vagy RPOR0bits kijelöl, jobbklikk, go to define -al eljutsz oda ahol meg tudod nézni.
Ez csak azt jelentheti, hogy nincs meg a megfelelő header file. Melyik fordító?
Sziasztok! PIC18F4550-hez kötöttem I2C-n DS1621-t meg DS1307-t. Egy problémám van, ha I2C-ben egymás után több bájtot olvasnék ki a slave-ekből, akkor az első bájt után a master nem tudja a slave-t nyugtázni, így nem jön több byte. Ha viszont csak 1 byte-ot olvasok, akkor minden rendben.
A drivert csatoltam, az I2C_Read_Byte2 függvénynél pl a 2. olvasás már nem működik. Előre is köszönöm, ha valaki rájön. A piccolo oldalt is néztem, microchip-et is, de nem értem
Pedig nálam simán megeszi az XC16 v1.10 a következő kódot:
A lényeg, hogy a project beállításoknál a "Common include dirs"-hez meg kell adni a családhoz tartozó könyvtárat (általában C:\Program Files\Microchip\xc16\v1.10\support\dsPIC33E\h) Itt lakozik a p33EP512GP806.h is, amiből ki lehet puskázni milyen regisztert minek is neveztek el.
Szia!
Én is csak az assemblyt ismerem. PIC24F, dsPIC30/dsPIC33 családok processzoraira is írtam már assemblyben programot. Kiindulásként a dsPIC30-as családhoz található inkább assembly anyag. A feladattól függ, hogy érdemes-e. A számítási kapacitása, sebessége sokkal nagyobb mint a PIC16F-es családnak. A PIC18-as családból még nem használtam, de szerintem azokhoz képest is lényegesen erősebb processzorok a 16 bitesek.
A nyugtázás nálam működik és így néz ki:
Nálad nem a nyugtázással van bal, hanem a negatív nyugtázás nem megy ki. Próbáld így az I2C_Read() függvényben, (az if nélkül):
Kis helyesírási baki a változód nevében: a nyugtázás angolul acknowledge
XC16 a fordító.
Közben rájöttem hogy lefordítja ettől még a kódot, érdekes. AZoli! Az RPOR0-ban a fordító szerint az RP20R és az RP35R van.
Szia!
Én dsPIC-eket programozok egy ideje (majdnem ugyan az mint a PIC24), bár én C-ben és nem assembly-ben. Régebben (meg néha most is) én is PIC18-akkal foglalkoztam. Alapvetően rengeteg különbség van a két család közt, néhány a teljesség igénye nélkül: - Nem 8 hanem 16 bites számokkal dolgozik. Bár C-ben ez kb mindegy mert ugyan úgy néz ki a kód, assemblyben viszont nagy segítség lehet. Illetve természetesen gyorsabb is a kód ebből adódóan. - A portlábak is 16 bitesek, legalábbis a PORTB-nek ki szokták vezetni mind a 16 bitjét. Ez azért nagyon jó, mert rendkívül nagy sebességgel vezérelhető így színes, grafikus TFT kijelző, mivel a színinformációt (16 bit) egyszerűen csak egy utasítással ki kell tolni a PORTB-re. A TFT-knél erre szükség is van mert különben látszik ahogy rajzol rá a PIC... - Egy utasításciklus nem négy, hanem két órajelciklus alatt megy végbe. Emiatt alapból gyorsabb a PIC. No meg ezek a 16 bites PIC-ek eleve is már nagyobb órajelről tudnak menni. - A PPS-nek hála (Peripherial Pin Select) majdnem minden periféria majdnem minden ki és bevezetése majdnem bármelyik lábra rákapcsolható. Kb oda köthetsz bármit ahová csak akarsz! Ez a nyáktervezést nagymértékben leegyszerűsíti. - Nem egy hanem általában három ICSP programozói lába van a 16 bites PIC-eknek. Ezek közül is oda kötöd az ICSP csatit amelyikre neked szimpatikus. - A 18F-eknél a PORTB-re lehetett bekapcsolni felhúzóellenállásokat. Ezeknél már bármelyik lábra lehet felhúzót és lehúzót is kapcsolni! - Általában a 18F-ekhez képest sokkal nagyobb program és adatmemória. Az 512kB programmemória teljesen normális. - A 18F-ekben (némelyikben) van EEPROM memória. A dsPIC-ekben (és a PIC24-ekben) sajnos nincsen, legalábbis én még nem találkoztam ilyennel. Itt a programmemóriát kell írni. De tök egyszerű, a Microchipnek van rá hivatalos függvénykönyvtára ami gyakorlatilag leszimulálja az EEPROM-ot. Valójában a PIC a saját programmemóriáját írja általa. - A PIC perifériái sokkal fejlettebbek! 16/32 bites számlálók amikből ráadásul rengeteg van, sokkal több lehetőség... - Az A/D is fejlettebb. Például nem egy hanem négy A/D konverter van benne, amikkel megoldható hogy akár négy jelből vegyen a PIC garantáltan egyszerre mintát. - Itt már nem CCP modulok vannak hanem ezek ketté vannak szedve: van Input Capture és Output Compare modul. Utóbbival pl PWM jelet a 18F-ek CCP moduljához képest összehasonlíthatatlanul több lehetőség szerint lehet előállítani... - Bizonyos típusokban van DMA (közvetlen memória-hozzáférés). Ezzel bizonyos perifériák (A/D, SPI, UART...) közvetlen tudnak az adatmemóriába írni vagy onnan olvasni, a program futásától függetlenül. Pl megoldható az, hogy az A/D fix időközönként vegyen mintát és azt pakolgassa bele a memóriába. És csak akkor szól ha már megvan mondjuk 1000db minta. - A 18F-ekben van az órajelhez egy négyszeres fáziszárt hurok (PLL) amit vagy bekapcsol az ember vagy nem. Nos ezeknél a 16 bites PIC-eknél már akkora a PLL amekkorára akarjuk! Akármilyen kvarccal beállítható szinte bármilyen órajel. A hozzászólás módosítva: Aug 8, 2015
Köszönöm az ismertetőt. Abban tudnátok segíteni, hogy milyen asm fordítót érdemes használni a 24-es szériához? Az ASM30- as fordítót próbáltam de mindig valamilyen hibát ír ki hogy a makefile rossz helyen van vagy micsoda, de nem találtam rá megoldást a neten. Majd ha visszamegyek a hotelbe csinálok a hibáról képet.
Az XC16-ot egyaránt használhatod C és Assembly programok írására, fordítására.
És az assembler részért használhatom úgy az XC16-os fordítónak, hogy az nincs aktiválva? Vagy a licensz lejártával az assembly rész sem fog rendesen optimalizálni?
Nem kell aktiválni, szabadon használható.
Assemblyben TE optimalizálsz, nem a fordító.
Én az ASM30-at használom MPLAB IDE-vel. Projektet kell készíteni, aminek tartalmaznia kell a forrás fájlt, a programot (.s), az .inc és .gld fájlokat. A forrás fájl kialakítására a régebbi dsPIC30-as processzorokhoz lehet példát találni. Az könnyen hozzáigazítható az újabb processzorokhoz.
Néha előfordul, hogy jelzi a sor elején az ismeretlen azonosítót, ez valami betegsége az X-nek szerintem, de lefordul. Nálam ha elmentem ujra megnyitom akkor már nem írja ki. Aztán éha megint rájön az elmebaj és megint jelzi. Ha tudod, hogy belinkeltél mindent és annak ott kell lennie akkor nem kell vele foglalkozni. Kicsit zavaró, de én már megszoktam.
Sziasztok!
PIC32MX-re írok egy programot és valami olyan hibát(?) találtam, amit nem tudok megfejteni. A kód a következő: A TimingFlags1 típusának deklarációja:
Flagek példányosítása Ezt Globálisnak tettem!
A ciklus, amiben a gondok vannak:
Timer1 megszakítás kezelése:
Tehát minden fél másodpercben be kellene állítódjon a TimingFlags1.ReceptUtemFlag. Ez nem mindig történik meg. Ha kiveszem a ciklusban jelzett négy sort, akkor igen. Ha a cReceptUtemFlag char típusú változót használom Flagnek, de a négy sort bennt hagyom, működik. Olyan, mint ha a fő ciklusban nagyon gyorsan módosított bitekre szabdalt TimingFlags1 változó megakadályozná a megszakításban a megfelelő TimingFlags1 bit beállását. A megszakítás megtörténik, detektáltam, az OraTesztCounter növekszik stb. csak a jelzőbit nem áll be mindig. Lehet, hogy a Sturtura kezelése nem egy programlépésben zajlik és nem tesz jót, ha a megszakítás beleszakít? Ha igen, lehet használni egyáltalán ezt a bitenkénti módot? A PIC18-aknál ilyet soha nem tapasztaltam... Nagy segítség lenne, ha valami ötlet felmerülne! Köszönöm!
Elso ranezesre szerintem deklarald volatile-nak azokat a valtozokat, amiket megszakitas allit, es attol fuggetlen programresz olvas. Ugyanis az optimalizacio miatt a TimingFlags1.ReceptUtemFlag valtozodat nem feltetlenul fogja minden ciklus lefutaskor felolvasni a memoriabol, hanem csak a while(1) ciklus elott egyszer, ezert nem veszi eszre, ha a megszakitas megvaltoztatja.
A hozzászólás módosítva: Aug 11, 2015
Kipróbáltam, nem módosul a lefordított kód. Lehet, hogy a C32 a globális változókat eleve volatile-nek veszi. Köszönöm a válaszod!
Közben kipróbáltam ezt:
Így jól működik. Tehát biztos, hogy a megszakítás félbeszakít valami belső műveletet, ami a bitek beállításához kell a bájtban, ami valószínű nem egy lépésben történik. Tudtok erről a témáról valami forrást ajánlani?
A
Bevallom nem tudom, hogy a megszakítás mikor léphet életbe, de szerintem bármelyik megkezdett gépi lépést követően. Ha beleszakít egy ilyen szekvenciába, majd a megszakításban ugyanezt lefuttatja, majd visszaadja a vezérlést a félbeszakított lépésre, akkor annak bármilyen következménye lehet. Nem túl boldog gondolat, de ha olyan változót kell módosítani fő szálakban, amit a megszakításban is módosítunk, és bitenként állítunk, akkor a parancs kiadása előtt le kell tiltani a hozzá tartozó megszakítás engedélyét. Jelen esetben elég lenne a Timer1-ét. Kicsit meglepő, ha ez így lenne és abszolut nem mulatságos! Természetesen várom a cáfolatokat, illetve a jó megoldást, ahogy kéne csinálnom! Köszönöm! A hozzászólás módosítva: Aug 11, 2015
Idézet: Most ertettem meg a problemadat. Figyelmetlenul olvastam el eloszor. A volatile mindenkeppen kell, mert ha most mukodik is, kesobb lehet, hogy nem fog. Semmi nem volatile, ami nem annak van deklaralva. A problemad ebben az esetben valoban abbol adodik, hogy ugyanazt a valtozot RMW valtoztatja a foprogramod is es a megszakitas is. Ebben az esetben le kell tiltani a megszakitast a muvelet idejere. Megjegyzem, ha nem kifejezetten indokolt a bitfield hasznalata, akkor ilyen helyeken kerulendo. Csak feleslegesen noveli a kodot, egyetlen byte RAM sporolasert.„Kipróbáltam, nem módosul a lefordított kód. Lehet, hogy a C32 a globális változókat eleve volatile-nek veszi. Köszönöm a válaszod! ” A regi (2010) gcc alapu pic32 fordito az jol mukodott, nem tekintett semmit magatol volatile-nak. A megszakitasok mint olyan a C nyelvnek nem resze. Vannak az ugynevezett sequence pontok, amikkel erdemes tisztaban lenni. Sosem lehetsz biztos benne, hogy egy a += 2; muvelet pontosan mit csinal belul. Ha 'a' 32 bites, akkor lehet, hogy 8 vagy 16 bites darabokban szedi fel a fordito, es ugy is teszi vissza, es ha kozben egy megszakitas hozzanyul a valtozohoz, akkor igy jartal. Itt semmire nincs garancia. Azoknal a valtozoknal, amit megszakitas is allit, nagyon esznel kell lenni, mert ahogy te is irod, a megszakitas egy RMW (read modify write) muvelet kozepen is bejohet, ha az RMW muvelet nem egyetlen assembly utasitas.
Köszönöm, így már világos!
Esetleg tudsz abban segíteni, hogyan tudok átadni egy subrutinnak paraméterként(pointerként) egy struturált változót? pl. ezt TimingFlags1.TouchGo Ilyet még nem csináltam, soha nem volt rá szükség (most azért kéne, mert nem akarom teleírni a kódot letiltásokkal, subrutinba tenném, paraméterezhetően). A netet túrom, de nem nagyon találok megoldást. Az RMW-s problémát értem, viszont itt szinte minden C utasítást több gépi lépésben hajt végre a PIC. Na most ugyanúgy fenn állhat, hogy félbe szakít egyet, beírja a magát, majd a visszaadáskor felülíródik az első szándék értékével. Nekem fura az asm után, hogy egy egész bájtot elpazaroljak egy bitért, de lehet nincs más mód! Lehetséges, hogy a magasabb szintű nyelvekben ezért nincs valós boolean? A hozzászólás módosítva: Aug 11, 2015
Lehet, hogy nem teljesen ertem a problemad, de talan erre gondolsz:
Tehat van egy strukturad, ennek a tipusa itt struct timer_t. Maga a valtozo az 'akarmi'; A struktura cimet, mint minden mas valtozoet az '&' operator adja. A struktura mezoikre a . operatorral tudsz normalisan hivatkozni, de ha a struktura cimet kapod meg, akkor -> operatort kell hasznalnod. Idézet: Ez igy is van, ezert a megszakitasoknal a leheto legkevesebb globalis valtozot kell hasznalni. Mast nem nagyon tehetsz.„Az RMW-s problémát értem, viszont itt szinte minden C utasítást több gépi lépésben hajt végre a PIC. Na most ugyanúgy fenn állhat, hogy félbe szakít egyet, beírja a magált, majd a visszaadáskor felülíródik az első szándék értékével.” Idézet: Assemblyben tudod garantalni, hogy egy tetszoleges memoria byte egy vagy tobb bitjenek a modositasa egyetlen utasitassal megoldhato?„Nekem fura az asm után, hogy egy egész bájtot elpazaroljak egy bitért, de lehet nincs más mód!” Egyebkent a C-ben is van _Bool tipus, de en meg eletemben nem hasznaltam. Akarmit toltesz bele, vagy 0 vagy 1 lesz, ha visszaolvasod. Annyi biten tarolja, ahogy a C forditonak tetszik. De ettol fuggetlenul az if, while , for es a ?: feltetele nem _Bool tipus, hanem barmilyik egesz, lebegopontos, _Bool vagy pointer tipus lehet, es csak az szamit, hogy az ertek 0 vagy nem.
Ennél egy lépéssel szeretnék többet. A struktura címét át tudtam adni, de szeretném paraméterként a bit nevét is átadni.
Assemblyben C18-nál egy lépés a bitművelet, a megszakítás nem tud beleszakítani. C32-nél úgy látom ez már messze nem így megy. |
Bejelentkezés
Hirdetés |