Fórum témák
» Több friss téma |
Ezzel csak az a baj, hogy megtörténhet az is (debug esetén tapasztaltam is), hogy éppen bent van a mérésben, amikor beugrik egy karakter a soros porton. Akkor már hiába tiltanám a mérés_flag-et, nem ér semmit, ugyanis már benne vagyok.
Nem szeretek eltérni az ajánlásoktól, mert nem véletlenül írják oda.
Ha nem tiltok megszakítást, javulhat a MODBUS, de romlik a mérés.
Ha bitenként engedélyezed-tiltod a megszakítást, akkor legalább 100kbps sebességet ki kell tudnia szolgálni úgy is a hardvernek gond nélkül. Egy bit ideje minimum 60us, gyakorlatban legyen inkább 80us, akkor is 1/8us=125000bps sebességgel kellene érkeznie az adatnak a soros porton, hogy egy 1wire bit átvitelének ideje alatt beérkezzen egy bájt a modbuson. És akkor még ott van a két bájtos hardveres puffer is, tehát nem tudom elképzelni, hogy ezesetben a bejövő puffer túlcsordulna.
Te tudod...
Mellesleg más út, de potyo-nak igaza van... A hozzászólás módosítva: Jún 5, 2014
A one_wire_reset-tel van a gond, az hosszú.
Egy 40MHz -es PIC18 az RCREG-ből egy karakter kivételét el tudja intézni kb. 30-35 utasításcból. Ez kb. 0.35 us. Egy körforgó bufferbe teszi a vett adatokat és elkönyveli, hány van a bufferben, a többi a főprogram dolga. Az adás hasonlóan: A főprogram feltölti a kimenő buffert a távirattal, a megszakításui rutin küldi el a soron következőt. Ez is megoldható kb. ugyanannyi dővel, mint a vétel. Egy adás és egy vétel ideje így belefér a 1-wire toleranciáiba.
Egy 512us időzítést egy timerrel kellene megvalósítani. A hozzászólás módosítva: Jún 5, 2014
Idézet: „Egy adás és egy vétel ideje így belefér a 1-wire toleranciáiba.” Ezt mondogatom egy ideje...
Én PIC16f886-on írom, 20 mhz-el.
Igen, valóban timerrel kellene, csak már annyit használom a timert, hogy nem tudom, hogyan tegyem még itt is. Használom a timer1-et a mérések, kiiratások időzítésére. A timer0-t a modbus utolsó karakter utáni 3,5 karakternyi szünetre. A timer2-őt PWM-re, szóval hogy gyűrjem bele még a ds-t is?
Egy timert több dologra is lehet használni. A Timer0-ba még beférne egy másik időzítő flag beállítása, vagy maga a végrehajtás is, ha pár sor...
Idézet: „A timer2-őt PWM-re, szóval hogy gyűrjem bele még a ds-t is?” Pl. valahogy így:
De ez meg felesleges, mert a reset tarthat tovább, mint az adatlapban megadott minimális érték. A lényeg csak az, hogy ne legyen rövidebb. Tehát belövöd, hogy a legrosszabb esetben se tartson adott időnél rövidebb ideig, aztán ha közben jön megszakítás, akkor kicsit tovább tartja a resetet, az nem probléma.
Akkor ezek szerint a Timer0-t is kiválthatnám?
Lehet, hogy az én struktúrám a rossz. A write_bit és a read_bit is kaptak egy argumentumot, mivel 3 különböző lábon is vannak ds-ek.
A onewire_write_bit
A read_bit:
Vagyis bitenként tiltom a megszakítást. A resettel bénázok. Nem sikerült a fenti kódod. A hozzászólás módosítva: Jún 6, 2014
Sziasztok!
Nem tudom, hogy mennyire off a kérdésem, de Ti milyen fejlesztőkörnyezetet használtok PIC-hez, C nyelven? Én MPLab-ot használok, de a szerkesztője valami borzalmas... Üdv.: László
Szerintem mi is MPLAB-ot használunk. Nem annyira borzalmas...
Én is MPLAB-ot használok. Valóban nem a legkifinomultabb a szerkesztője, de volt már dolgom rosszabbal is.
Szia!
MPLAB. Egyszerű, átlátható. Nem tudálékoskodik minden legépelt karakter után, mint az IDE-k egy része.
Ennyi a reset. Ide (sem) nem kell megszakítás tiltás...
A hozzászólás módosítva: Jún 7, 2014
Idézet: Configure/Settings menüben beállíthatod, hogy külső szerkesztőt használjon. „Én MPLab-ot használok, de a szerkesztője valami borzalmas...”
Kipróbálom, köszönöm.
Viszont koncepciókidolgozásban szeretnék segítséget kérni. Melyik a jobb megoldás: A főprogram megszakításokban beállított flageket hajt végre, a megszakítás timer1. Mikor bizonyos idők lejárnak, megcsináljuk a dolgunkat, pl: kiiratás frissités, mérés... Ha jön egy karakter a soros porton, egy körforgó pufferba pakoljuk a byteokat (a megszakításban a legelsőt leellenőrizzük, a többit már nem, majd a főprogramban), persze FERR, OERR ellenőrzés után. Ha bármelyik bekövetkezik, üritjük a bejövő puffert és kezdjük elölről. Itt lenne az első kérdés: a: Mikor beérkezik 8 byte, akkor flaget 1-be állítjuk jelezvén a főprogramnak, hogy bejött egy keret. Vagy: b: Minden karakter között timert futtatunk, amit egy újabb karakter beérkezése esetén resetelünk. Amikor a timer túlcsordul, akkor már valószínüleg több byte nem jön, flag=1; Itt lenne a második kérdés: A: A főprogram megvizsgálja az eredeti bejövő puffer tartalmát, ha minden ok, akkor feltölt egy kimenő puffert, amit majd megszakítással elküldünk. Ha elment az összes karakter, akkor ismét lehet fogadni, addig nem. Vagy: B: Átmásoljuk egy másik pufferba a bejövő puffer tartalmát, majd ismét engedélyezzük a soros port olvasás megszakítást, mert a puffer már újra írható, mivel az adatait már lemásoltam egy másikba, nem kell attól félni, hogy jön egy újabb keret és felülírja az eredeti üzenetet. Ez az egyik verzió. A másik olyan lenne, hogy egy olyan függvényt írnék, ami rá-ránéz a puffer tartalmára és a különböző állapotoknak megfelelően egy állapotgép változót növelgetne, hogy éppen hogy áll a puffer tartalma. Kérnék szépen segítséget, mivel bizonytalan vagyok a program szervezésben. A hozzászólás módosítva: Jún 7, 2014
Szerintem az 1. megoldás: ütemezett végrehajtás a Timer megszakításban beálló jelzők szerint. Itt több esemény eltérő időzítése is megoldható, ez az általános.
A MODBUS miatt minden beérkező karakter után 3,5 karakternyi időt kell ellenőrizni és ha lejár, az az üzenet végét jelenti. Tehát ez a megoldás a javasolt. Timer kezdeti érték feltöltéssel, indítással, megszakításban történő lekezeléssel javasolt. Erre elmehet egy timer(nálam a Timer1 szokott lenni)... Az RS485 egyidőben csak egyik irányba kommunikál. Érvényes vétel után adásra váltunk(választ kell küldeni), tehát a vétel megszakítással szerintem nem kell foglalkozni, de ha nagyon akarod, ki lehet kapcsolni a lekezelés végéig az USART vételt (RCSTA1bits.CREN). A teljes csomagot kell fogadni, majd lehet ellenőrizni a CRC-t és utána a címet. A választ is érdemes megszakításban elküldeni, nemrég beszéltünk erről a PIC miértek haladóknak topicban Hp41C-vel. Idézet: „Mikor beérkezik 8 byte” Szerintem nem 8 bájt jön mindig, de egyedi megoldásoknál lehetséges, csak az nem lesz szabványos lekezelés. Viszont a 3,5karakteridő viszgálata és a CRC megoldja a csomag végének detektálását és jóságának ellenőrzését.
Akkor nincs értelme lemásolni a bejövő puffert egy usart-tól független pufferba?
Ha a timer1-et használom időzítésekre, ugyanazt hogy tudom használni modbus karakterek közötti idő vizsgálatára? Idézet: „Szerintem nem 8 bájt jön mindig” Bocsánat, azt elfelejtettem mondani, hogy csak a 3. funkciókódot valósítottam meg, ott 8 bájt jön be:
Egyébként melyik lenne jobb megoldás? A Bejovo_puffer.adat-ot használni, vagy a struktúrát? A hozzászólás módosítva: Jún 7, 2014
Vételkor nem szoktam áttölteni a puffert beszédes nevű változókba, benne ellenőrzöm, belőle töltöm át, illetve benne készítem elő az adatokat küldésre. Küldéskor csak a megfelelő puffer pointerét kell átadnom a TX előkészítő rutinnak (ha több pufferből is küldeni kell, pl. belső óra. Ilyenkor a kevesebb adatot mozgatom át az épp aktuális puffer elejére, hogy a MODBUS protokollnak megfelelő legyen az első néhány bájt).
Úgy is tudod melyikben mi van, még akkor is, ha több funkciót is kiszolgálsz. Emlékeztetőt szoktam írni megjegyzésben, az nem zabálja a memóriát és nem lassít! A hozzászólás módosítva: Jún 7, 2014
Idézet: „Ha a timer1-et használom időzítésekre, ugyanazt hogy tudom használni modbus karakterek közötti idő vizsgálatára?” Sajnos külön timert igényel, ha könnyen és pontosan akarod lekezelni a dolgot. Inkább másik Timerrel old meg az általános időzítéseket. Melyiket mire használod most és milyen megszakítás ütemmel? Most olvasom vissza, hogy a TImer0-t használod a 3,5 karakteridőre. Ha működik, akkor az is jó... A hozzászólás módosítva: Jún 7, 2014
Hát van némi problémám a lekezeléssel. Ha szigorúan betartom a min. 3,5 karakternyi időt, vagy max 5-öt, akkor nem jó, 10 karakternyi időnél már beugrik.
Szóval a timer2-őt pWM-re, timer1 általános időzítések, timer0 a modbus-ra. Valahogy így:
Ahol Modbus_timeout-tal lehet állítani a timer0 idejét. MB_start_flag jelzi, hogy mehet a timer0 és vétel közötti szünetről van szó. Reset_Modbus - ekkor ürítjük a puffer tartalmat, mert egy hibás karakter vétel történt. És ha a timer0 lejár, akkor soros_flag=1 jelzvéna főprogramnak, hogy mehet a modbus kiértékelés. Idézet: „Ha működik, akkor az is jó...” Esetleg jobb lenne valami más? A hozzászólás módosítva: Jún 7, 2014
Ezt nem értem. Nem megszakításban kezeled le a soros portot?
Ez a kód hol helyezkedik el?
Megszakításban nagyon fura nekem a while, na de lépjünk ezen túl...
A korábban leírtak szerint kellene átírnod a kódot. Minden bejövő karaktert letárolsz a pufferbe, majd kilépsz a megszakításból. Ezt addig, amíg a timeout nem jelzi, hogy vége a csomagnak, ekkor beállítasz egy jelzőt, hogy kész a csomag és a fő ciklusban lekezeled. A timeoutot mindegy milyen módon állítod elő, csak pontos legyen. A Timer1 azért jobb, mert elindítható, leállítható és fel lehet tölteni kezdő értékkel, így csak akkor szakít meg és csak egyszer, amikor lejárt az idő(viszont fel kell áldozni erre). Ehhez persze a megfelelő osztásokat kell beállítani a bemenetén. Ha a timer0-al dolgozol, vagy több dologra is használni akarsz egy timert, ott több megszakítás lesz a 3,5karakter alatt, ez kissé erőforrás igényesebb, de nem vészes. Az eredmény lehet ugyanaz...
Nekem is az volt, de régebben veled is fórumoztam erről:
Régebbi fórum UART-ról Itt kaptam a sugallatot, azóta ezt használom. Hogy érted, hogy Idézet: „ott több megszakítás lesz a 3,5karakter alatt” Most pillanatnyilag 4 MHz-en megyek, 16-os osztó timer0-val ami 0.00409600 sec. Az 9600-on majdem 4 bájt átvitelének ideje. Ez pont jónak tűnik. Még annyi lenne a kérdésem, hogy jelezzem a megszakításban, hogy 1. bájtról van szó? Szóval ahogy írtátok is, nem csinálok a megszakításba vizsgálatot, de az első bájtot ha megvizsgálom, ami ugye a cím, akkor egyből kiderül, hogy nekem jött-e az üzenet, vagy nem. Kell ezzel foglalkozni, vagy majd a főprogram úgy is kidobja? A hozzászólás módosítva: Jún 7, 2014
Lehet vizsgálni a címet végül is, ezzel nincs semmi baj, de a további bájtokat ettől még fogadni kell, csak nem kell feldolgozni...
Igen, így csak egy megszakítás lesz a Timer0 esetében is, ami jó. Első bájtot úgy lehet jelezni, hogy beállítasz egy jelzőt, ha bejön egy karakter. Ezt a jelzőt az időtúllépésben törlöd. Tehát, ha a jelző törölve van és jön egy bájt, akkor az az első. A hozzászólás módosítva: Jún 7, 2014
|
Bejelentkezés
Hirdetés |