Fórum témák
» Több friss téma |
De, számít. Mikrokontrollernél (is) az órajel frekvenciája az alfája és omegája mindennek.
Számoló: RC Circuit Calculator. Bővebben: RC Oscillator Circuit. Jobban járnál, ha ezt a kontrollert leváltanád egy modernebb típusra, aminek van belső órajele. A külső RC oszcillátor nagyon érzékeny, könnyen elmászik a frekvencia. Ha nagyon pontos időzítések kellenek, akkor valamilyen pontos külső órajel vagy kvarc kell.
Még azt nem értem, ha van ez a parancs __delay_ms, és a programozasnal megadjuk a frekvenciát, akkor abból miért nem számol pontos milliszekundumot. Persze, ha a frekvencia elmaszik, akkor az idő is elmaszik, ez rendben van. De, ha pontos a frekvencia (kvarc), akkor pl. már kisebb frekvencia is jó lehet.
Azért nem pontos, mert a kontroller ilyen utasítást nem (sem) ismer. Ezt az egy utasítást le kell fordítani a kontroller nyelvére, amit a fordító meg is tesz helyetted. Ez a fordítás vagy jól sikerül, vagy nem de általában az utóbbi. Ennyire időkritikus alkalmazásnál a programot már ASM-ben illik írni, ott nincs tévesztés. Cserébe masszívan több idő egy fejlesztés.
A Timer-es megoldásnál szabályos időközönként ad egy jelzést az időzítő. Innentől kezdve a pontosság az órajel pontosságától és attól függ, hogyan kezeled ezt a jelzést. Általánosságban elmondható, hogy az esetek nagy többségében ez a módszer meg is felel. Van, ahol a delay függvény hazsnálata is bőven jó és marad az időkritikus alkalmazás.
Szia!
Gyakorlatilag nem számít a frekvencia. Bármilyen frekvenciád van, a timer2-vel 0,01 -0,001 sec időnként ami pontos, megszakítást lehet generálni. Ekkor csak egy számlálót kell léptetned, ami ha eléri a 100-at vagy 1000-ret akkor telt el 1 másodperc. hogy milyen módon oldod meg a 3 sec illetve az 5 sec időzítést már rajtad áll. A pontos frekvencia itt nem is játszik szerepet, hiszen szekundumos időkről beszélünk.
Tegyél mellé valamilyen kvarcot és ha megvan a frekvencia akkor segítek a programozásban.
Az nem úgy van, hogy a Portot olvassuk és ha kimenet, akkor a Latch-et írjuk?
Nem egészen.
Írásnál mindegy hogy a POTRx vagy LATx regisztert használjuk, a beírt érték mindig a latch-be kerül. Olvasás-módosítás-írás típusú utasításoknál kell erre figyelni, ha valamelyik kimeneti láb logikai állapotát kívülről valami megváltoztathatja. Ekkor a PORTx használata esetén hibás érték íródhat vissza a LATx regiszterbe. Ezért ajánlott a LATx-regisztert használni kimeneti láb állapotának változtatására. (Már ha van ilyen regiszter az adott mikrovezérlőn.)
A segítséget megköszönném, mert a Timer kezelése gondot okoz. Próbáltam már, de nem sikerült. Váltottam egy olyan kontrollerre, amiben van belső órajel: PIC16F627A.
Ez volna a program __delay paranccsal. Ami a Proteus 8 szimulációval jól is működik, de csak 20 Mhz-nél. Ha sokkal alacsonyabb, akkor a másodpercek lassabban telnek. A valóságban pedig minden összevisszaság van. Ki van kommentelve a Timer-es próbálkozásom. A program (még PIC16F718-ra):
Működés: A nyomógombra egy relé meghúz, majd 1 sec múlva egy másik is behúz. 3 sec múlva a második elenged és ezután 1 sec múlva az első is elenged. Ha hosszan nyomjuk a gombot, akkor egy LED felvillan és onnantól számolja a másodperceket, ha ismét megnyomjuk a gombot, akkor leáll. Ezt az időt azért számolja, mert innentől kezdve a második relé már nem 3 sec-ig fog behúzva lenni, hanem eddig a megváltoztatott ideig. Köszönöm!!
Szia én más megközelítéssel gondoltam, nem próbáltam ki a programot, assemblyben programozok, de ezen el tudsz indulni.
annyit elrontottam, hogy amíg nyonva van a gomb addig növeli az időt és nem az újbóli megnyomásra, de ez lényegtelen ,hiszen "úgyis ott kell lennie"a páciensnek.
Kíváncsiságból belekukkantottam a dsPIC33/PIC24 FRM idevonatkozó részébe is (Serial Peripheral Interface (SPI) with Audio Codec Support), de tényleg nagyon alul-dokumentált az SPI működése. Azt látom, hogy a buffer 2x16-bites (SPIxBUFH, SPIxBUFL), viszont a FIFO csak 16-bites, és a mélysége az adathossztól függ (4, 8, vagy 16). Vagyis 32-bites adatnál 2 cella tartalmaz egy adatot, míg 8-bitesnél egy cella 2 adatot. Én arra tippelek hogy a shift regiszter is 16-bites és az adat két részletbe kerül bele. Vagyis 32-bites vagy 24-bites adat esetén először a felső szól kell beírni, mert az átvitel big-endian (Motorola) módon történik.
Sajnos tesztelés nélkül én is csak találgatni tudok. (Úgy látom hogy ez a doksinak a legelső (A) verziója. Talán majd a következő verziókban pótolják a hiányosságokat.) A hozzászólás módosítva: Máj 16, 2021
Köszönöm szépen. Mivel C-ben sem vagyok profi, hát még ebben... De atragom magam és megpróbálom átültetni C-be. Visszatért a lelkesedésem.
Szia! Ez c nyelven van.És hiba nélkül lefordul XC fordítóval.
Gyanús is volt, hogy ez C, de Te assemblyt írtál (amit egyáltalán nem ismerek). Félreértettem. Akkor viszont meg kell(ene) értenem . Küzdök vele! Még egyszer köszönöm!
Ez azért érdekes, amit írsz, mert a Port-ot közvetlenül nem is lehet írni, kizárólag a Latch-en keresztül. Legalábbis az adatlapon szereplő áramköri megvalósítás alapján. Ezért aztán bizonyos esetekben a Port írás hibás működéshez vezet, amit sikerült is kipróbálnom. Valamint a Chipcad-nél a szakember nyomatékosította, hogy írni kizárólag csak a Latch-ez szabad, Portot semmi esetre sem. De ezek szerint rosszul tudják
Lehet. Vagy csak rosszul értelmezted a szavait.
Eleve bizonyos PIC típusokban nincs is LATx regiszter, tehát ott csak a PORTx regisztert tudod írni/olvasni. Ahol van, ott a következő szabály él: Írásnál - akár a PORTx, akár a LATx a cél - mindig a LATx-be kerül az adat. Olvasáskor viszont külön olvasható a PORTx és a LATx is. A működés egyértelműen kiolvasható a portok leírásában szereplő vázlatrajzból. (Van külön RD LAT és RD PORT jel, de a WR közös.) A hozzászólás módosítva: Máj 17, 2021
Az esetlegesen hibás működés oka röviden:
Egy kimeneti láb állapotának megváltoztatásakor a rajta levő terheléstől függően (főleg ha ez a terhelés kapacitív jellegű) idő szükséges ahhoz, hogy a láb állapota ténylegesen megváltozzon. Ha ilyenkor az átváltási időn belül a PORT 8 bitjét beolvasod nem az utoljára kiírt, hanem még az azt megelőző állapotot olvasod vissza. Ezután a hibásan visszaolvasott értéken megváltoztatsz egy bitet, amit újra kiírsz a PORT-ra. Ekkor hibásan visszaolvasott láb véglegesen a hibás állapotában marad. Na mármost: mivel a bsf és a bcf utasítás is ezt a tevékenységsorozatot fogja végrehajtani, a PORT bitjeinek egymást követő állítgatása során képes lesz ugyanezt a hibát elkövetni. Ha létezik LAT regiszter, ezért javasolt azt írni, mert a LAT esetén nem jelentkezik a beleírt adat késleltetett megjelenése visszaolvasáskor.
Írásnál a PORTx címet vagy a LATx címet használva ugyanazt az adatkimeneti regisztert írjuk (tehát mindegy, hogy melyik címet használjuk).
Olvasásnál a LATx címet használva az adatkimeneti regiszter állapotát olvassuk vissza, a PORTx címet használva pedig a portkivezetések állapotát olvassuk - ez utóbbi értékét a rákapcsolt külső áramkör vagy áramköri elemek befolyásolják. Itt, a LATx és PORTx címzésnél nyilvánvalóan két különböző dologról van szó, de könnyen el tudjuk dönteni, hogy melyik adatra vagyunk kíváncsiak. A bonyodalom a read-modify-write típusú utasításoknál kezdődik, amelyeket csak úgy tudja végrehajtani a mikrovezérlő, hogy először beolvassa a regiszter tartalmát, azután elvégzi a kívánt módosításokat (pl. bit beállítás, vagy bit törlés), végül visszaírja az adatot a regiszterbe. Itt fontos, hogy a LATx regiszter címet használjuk, mert ha az adatkimeneti regiszter tartalmát és a PORTx bemenetek állapotát kombináljuk egy meggondolatlan PORTx címzés használatával, akkor kellemetlen meglepetések érhetnek. Bővebben lásd itt (a 3. és 5. ábra, illetve a a kapcsolódó szöveg).
Még egy lehetőség van, de az már mély víz...
Egy port lábat analóg módba állítunk, de a TRIS regiszterrel engedélyezzük a digitális meghajtóját. Ekkor a lábon a LAT regiszterbe utoljára beírt adatnak megfelelő szint áll be, az jut el - többek között - az A/D bemenetválasztójára, azt a szintet méri az A/D, ha a megfelelő csatornán kezdeményezünk átalakítást. Ha a PORT regisztert olvassuk vissza, az adott lábnál 0 értéket olvasunk. Ha a LAT regiszterből olvasunk, akkor is számos típuson 0 értéket kapunk mindig. Ebben az esetben a LAT regiszterrel végzett RWM művelet is hibás eredményt ad. A megoldás a LAT regiszterről egy kópiát tarunk a GPR memóriában, minden műveletet a kópián végzünk és az eredményt csak másoljuk (movwf, movff).
Sikerült alaposabban elolvastam a dsPIC33/PIC24 Family Reference Manual idevonatkozó Serial Peripheral Interface (SPI) with Audio Codec Support részét.
Nekem úgy tűnik hogy ebbe a mikrovezérlőbe több PIC32-höz fejlesztett perifériát építettek, erre utalnak a 32-bites regiszterek, amik a PIC24 számára két részben érhetők el. (pl.: SPIxBUFL és SPIxBUFH) A 21. oldalon azt írják, hogy ha az adathossz 16 bitnél nagyobb, akkor először mindig az SPIxBUFL regisztert írjuk (vagy olvassuk), majd csak azután az SPIxBUFH-t. A 15. oldalon leírtak szerint 24-bites adatnál az SPIxBUFH regiszter DATA<23:16> bitjei használatosak. (normál módban)
Akkor leírom röviden a történetet:
Írtam egy asm programot 18F1330-as procira, majd később néhány újabb funkcióval kellett bővíteni. A módosítás után nem működött, egyszerűen a kimenetek nem funkcionáltak. Mindvégig a PORT-ot írtam. Mivel nagy szükség volt a programra, ezért, mivel régi jó kapcsolatban vagyok a magyarországi disztribúcióval, a CHIPCAD-el, ezért tőlük kértem segítséget, azaz besétáltam hozzájuk a laptopommal, a Pickit3-asommal és a panellal, hogy segítsenek, mert az új kód sehogyan sem működik. Baromi rendes volt a srác, mivel sajnos régi laptopról van szó, elég lassan ment fel rá a legújabb Mplab, de végigvárta. Majd betöltötte a programomat és az áttanulmányozása után csak ennyit mondott nyomatékosan: Portot soha sem írunk, csak a Latch-et, amit ott helyben meg is tett, azaz kicserélte a kimeneteknél a két utasítást és csodák csodájára, azonnal megjavult (amúgy rácsodálkozott az ajánlottnál sokkal hosszabb szalagkábelre is, amit használok az on board programozáskor, de az nem okozott problémát). Tehát innen az ismeret és a tapasztalat, ami szerint egyáltalán nem mindegy, hogy Portot vagy Latchet írunk. Én személy szerint azóta is minden esetben kizárólag Latchet írok. (Azt hiszem, nem kell hozzátenni, hogy ahol van, mert az ugye triviális!)
Sokkal egyszerűbb örökre megtanulni hogy MINDIG a LATCH-ot írjuk, mint a kivételeket megtanulni mikor lehet a PORT-ot büntelenül és mikor KELL a LATCH-ot
Amúgy ez a read-modify-write is meg tud szivatni (engem már megtett) ha két egymás utáni utasítással van bitmódosítás a ugyanazon a porton, akkor az első bitmódosítás elveszik... Ez ugye az átlapolt utasításvégrehajtás miatt van, az első utasítás "teljes" végrehajtása előtt már olvassa a második bitművelet a portot, amin még az elsőt megelőző állapot van... szóval ilyenkor kell egy NOP a két (ugyanazon) porton történő bitművelet közé
Az írás és olvasás ugyanabban az utasításciklusban történik, valamint két egymást követő utasítás végrehajtása nincs átfedésben. Az előző utasítás végrehajtása, ill. a következő beolvasása és dekódolása történik egyszerre. Az egymást követő két bitmódosító utasítás - ami ugyanazt a PORT regisztert használja - a következőt okozza:
A hozzászólás módosítva: Máj 19, 2021
Pont ezt mondtam, ami a képen le van írva, két egymást követő bitpiszkálás esetén az első elveszik - 4 es pontban oda van írva... a második utasitás hamarabb olvassa port állapotát, mint ahogy az első utasítás beállítja, minek hívjuk, legyen overlap
section 4.3oldal Oké "szó szerint" nem a 2 utasítás végrehajtása van átfedésben... hanem a 2 utasítás az eléjétől a végéig nézve középen átfedésben van )) A hozzászólás módosítva: Máj 19, 2021
Lehet hogy jóra gondoltál, csak nem jót írtál. Ennek a dolognak nem az utasítás-végrehajtási sorrendhez van köze, hanem ahhoz hogy egy láb nagy kapacitív terhelése miatt a kimeneti feszültség viszonylag lassan fut fel (vagy le), ezért az olvasással addig várni kell, amíg a feszültség el nem éri a logikai szintnek megfelelő értéket.
Sziasztok!
Az alábbi programot írtam meg, szépen lefordult. PIC16F627A használok. A programot beégettem, és próbapanelon annyit csináltam, hogy adtam neki 4,71 V-t (3 db ceruzaelemről), bekötöttem a VSS-t. VSS és VDD közé tettem még kondit is. +-ra kötöttem egy ellenálláson át az MCLR-t. A nyomógombot a + és az RA0 közé kötöttem és ezt a bemenetet lehúztam a földre egy ellenállással. Csak ennyit kötöttem be és mértem a kimenetek feszültségét, de semmi. Az égetés előtt az égető ( UPP628) programjában bejelöltem az IntOsc I/O-t; a conf. Words-nél semmit sem pipáltam ki (azaz OFF minden): WDTE, PWRTE, BOREN, LVP, CPO, CP. Kivéve a MCLRE, ezt kipipáltam (ez ON). Van ötletetek, hogy miért nem csinál semmit? Talán a belső óra miatt még valamelyik lábára kellene +5V? Vagy valamit a fentiekből még ki kellene pipálni? Itt a program:
Előre is köszönöm a segítséged!
Nem rágtam át magam rajta...
Ami változót használsz irq-ban annak illik volatile-nek is lenni, de biztos nem ennyi nyűgje van... Tegyél még rá ledeket amit a program különböző helyein kapcsolgatsz, így látd merre kóvályog
Proteus szimuláció szerint jól működik. Mit jelent az irq és a volatile?
irq: interrupt rutinban...
Bővebben: Link Utasítja a fordítót, hogy azt a változót ne optimalizálja. AZ értelme hogy pl egymás utáni módosítása/felhasználása ugyanannak a változónak ha processzoron belül pl. regiszterben megtörténik, de közben van egy interrupt, ami megmódosítja a memóriában a változót, akkor az nem jut érvényre... |
Bejelentkezés
Hirdetés |