Fórum témák
» Több friss téma |
Proteus 8 Professional.
Kipróbálom ezt megszakításos fogadást.. bbalazs_: használom az adatlapot, de ezt a részt nem olvastam. Megszakítást USART-nál még nem használtam, ezért kérdeztem.
Mi az az RC megszakítás?
Azt, hol tudom beállítani? Ezeket állítottam be:
Engedélyeztetés majd programból, ha szükséges. Közben megvan. "PIR1: PERIPHERAL INTERRUPT REQUEST (FLAG) REGISTER 1" A hozzászólás módosítva: Jan 31, 2016
Ha egy bajtot fogad akkor egy interruptor general.
Igen, köszönöm, már megvan és szépen tölti az adatot.
16Kb-os adatot 10mp-alatt fogad, ez már azért sokkal jobb arány mint a 21mp
A PIR1 regiszter TXIF és az RCIF bitje nem írható programból: (R-0).
Itt nézz utána:
PIC24H Family Reference Manual : Section 17. UART 17.3 UART BAUD RATE GENERATOR - képlet az átviteli sebesség számításához További segítség: PIC24F Family Reference Manual : Section 21. UART 21.3 UART BAUD RATE GENERATOR (BRG) - képlet az átviteli sebesség számításához 21.3.2 Baud Rate Tables - sebességtáblázatok
Bocsi! Nem eléggé figyeltem.
Tehát itt: PIC24H Family Reference Manual : Section 7. Oscillator 7.1 INTRODUCTION - Oszcillátor blokkvázlat PLL módban az FRC jele az FRCDIV osztón keresztül megy, de annak az osztása alapesetben /1. 7.7 PHASE-LOCKED LOOP - PLL blokkvázlat A PLL-nek 3 osztója van: előosztó, utóosztó és a visszacsatolt jel osztója (azaz szorzó). A 7-8 ábrán leolvashatók a kritériumok, hogy melyik blokk mekkora frekvenciát tud fogadni. Tehát az osztókat úgy kell beállítani, hogy ezeknek megfeleljenek! Ez fontos! Nálad mik a beállítások?
Elolvastam 100* a bejegyzésed, de nekem ez nem kerek.
Idézet: „Vétel: Folyamatos vétel, RC megszakítást beállítani, vételi hibát lekezelni, a vett adatot egy vételi bufferbe írni. Adás: A TX megszakíáts az adási bufferből veszi ki a soron következő adatot és beírja a TXREG -be. Ha nincs adat a TX megszakítást tiltja. A fő program a vételi buffert figyeli, ha ven benne adat kiveszi és feldolgozza, a választ az adási bufferbe írja és engedélyezi a TX megszakítást.” Addig eljutottam, hogy beállítom a megszakítást.:
Egyelőre TX-et nem, mert nem értem, hogyan okozhatna megszakítást, ha már a vevő része folyamatosan dolgozik és alacsony szintűt nem tudom beállítani, ha a magas szintű már be van. Vagy legalább is én nem tudom az, hogy kellene.. Aztán, a főprogram egy while ciklusban folyamatosan megy a vétel:
Eközben a megszakítás a következő munkát végzi:
Szóval eddig jutottam. Részben működik is, de nem úgy szerintem ahogy kellene... Előre is köszi a segítséget. A hozzászólás módosítva: Jan 31, 2016
Én szeretek többször felhasználható kódokat írni, valamikor megírtam a bufferelt soros vétel/adás függvényeimet, azóta csak használom őket. Beleírtam egy kis használati útmutatót, meg csatoltam egy teszt alkalmazást is hozzá.
Én PIC32-nél dolgoztam UART Rx Tx interrupttal. PIC32MX795F512L-nél be lehet állítani, hogy Tx esetén mikor keletkezzen megszakítás, ha elküldött egy karaktert, ha a puffer kiürült, stb.
Én úgy csináltam meg, hogy a kiküldendő adatot beraktam egy tömbbe, majd a 0. elemét kiküldtem a szokásos módon, ezután már minden ment magától megszakításból.
Egyelőre kicsit el vagyok veszve, mert benjami amit küldött az nagyon összetett és profi kód, olyannyira, hogy még felhasználni sem tudom
Kicsit vicces, de sajnos ez van, be kell ismerjem. Most már én is megszakítással fogadom az adatot, de mint feljebb is leírtam, nem az igazi. Valami nem stimmel és ennél a projektnél fontos a gyorsaság és a pontosság. Jelen pillanatban amit írtam az instabilan működik. Idézet: „Egyelőre TX-et nem, mert nem értem, hogyan okozhatna megszakítást, ha már a vevő része folyamatosan dolgozik ...” A megszakítás célja, hogy az adott perifériát lehetőleg kevés CPU teljesítmény ráfordításával lehessen kezelni. A soros vevő az adat vételének befejezésekor kér (RCIF) megszakítást, az adó akkor kér (TXIF) megszakítást, ha az előzőleg beírt adatot elküldte, az újabb adat beírható. Beállítás: Baud rate, működési mód (CREN=1, órajel osztás, 9 -bit engedélyezése, stb), bufferek inicializálása, SPEN = 1, RCIE =1, TXIE = 0, Egyszerű vagy priooritásos megszakítás felprogramozása, a végén GIE (GIEH vagy GIEL) engedélyezése. RCIF megszakítás: RCSTA olvasása egyszer és elmentése (ha kell), FERR és OERR tesztelése: - Ha nincs hiba: az RCREG kiolvasása (ez törli az RCIF megszakítást) és a vételi biufferbe írása, egyel több adat van. - Ha hiba van: SREN = 0, RCREG kiolvasása (ez törli az RCIF megszakítást), az adat eldobása, RCEN = 1, TXIF: - Ha nincs elküldendő adat az adási bufferben: TXIE = 0 - Ha van: az adat kivétele a bufferből, egyel kevesebb adat, az adat beírása a TXREG -be. Főprogram eljárásai: - Vételi buffer állapot lekérdezés: Ha van adat a vételi bufferben a visszatérési érték 1, egyébként 0. - Vételi buffer olvasása - akkor hívható, ha van a bufferben adat: Az adat kiolvasása, egyel kevesebb adat - Adási buffer írása: Az adat beírása az adási bufferbe, ha ven még hely benne, egyel több adat van, TXIE engedélyezése. Az "egyel több adat" és az "egyel kevesebb adat" jelzések végrehajtását a főprogramban un. primitív művelettel (megszakítás nem tudja félbeszakítani) kell megvalósítani: decf, incf.
Jelen pillanatban csak adatot kell fogadni PIC-el, küldeni bármilyen adatot, küldhetek, a lények, hogy visszajelezzen a PC-nek, hogy jelen van és készen áll a következő adat fogadására.
Tehát a PC csak visszaigazolást vár PIC-től, amint megkapja azonnal küldi a soron következő adatot. A mostani leírásod alapján így írtam át:
USART ini:
A leírásod alapján az RCIF megszakítás:
És a főprogram:
A változók globális változók, így ezekkel nem lehet gond. Minden esetben csak 1 bájt adat érkezik. (ha jobban tetszik cserélődik) Nem akarok bufferelni mert: 1. túl sok adatot akarok fogadni (Maximum 8Mbit-et) 2. a beérkezett adatot egyből írnám is be a memóriába 3. egyelőre a bufferelés bonyolítaná a megértést Jelenleg a program hol, lefut teljesen, hol leakad az 1. byte-nál, de van olyan is amikor változó számú adatot el tud küldeni majd megáll. Muszáj lenne figyelnem, hogy érkezik e adat, mert ügye ez a biztos, és itt tévesztés nem lehet, mert akkor bajba lennék Ha nem teszem feltételbe, hogy vizsgálja érkezik e adat akkor minden esetben lefut, bár nem túl sokszor, de észre vettem, hogy téveszt az elküldött és számolt byte-okban. Idézet: Ezért jó, amit HP41C kolléga írt: megszakításba berakja egy tömbbe és ha van időd ( azaz ráér a periféria!) már nyomod is ki, miközben a vett adat hardveresen megint bekerül a pufferbe ! „Muszáj lenne figyelnem, hogy érkezik e adat, mert ügye ez a biztos, és itt tévesztés nem lehet, mert akkor bajba lennék”
Igen, de az a baj, hogy a vett adatot, nem vizsgálhatom mert az lehet nulla is.
Csak a vett adatok darabszámát kell vizsgálni.
Próbáltam úgy is, de leáll az adatküldés. (Persze mindig változó, hogy mikor)
Interrupt-ban meg a DataSize növelve van, minden megszakításnál. Vagy előfordulhat már itt, hogy a PC oldalon van valami gond? Bár azt kötve hiszem, mert az addig küldi az adatot ameddig csak tart a fájl hossza. Olyan mint, ha az időzítések nem lennének harmóniába. Bár gondolom ezt csak a PIC oldalán tudom hangolni, mert az számít, hogy PIC mikor végez és addig PC várjon csak nyugodtan. Képen látszik, hol akad el a művelet. 0x0c-t még vette, de 0x0D-t már nem. A hozzászólás módosítva: Feb 1, 2016
A PIC-ben az adat fogadása hardveres, az "nem hibázhat", ha jól programoztad fel ! Ha nem tudod, hogy hol a hiba, akkor tárold le a vett adatokat egy pufferben ( pl. a HP41C kolléga által említett megoldás is jó !), a programot állítsd meg a puffer méreténél kevesebb byte átvitele után és ellenőrizd le, hogy mi a bibi !
szerk: most néztem a képet... a szimulátornál nem lehet gond, tuti, hogy jól szimulálja a windows-on belüli átviteleket ?! A hozzászólás módosítva: Feb 1, 2016
Az a kód biztosan jó és működik, bár én nem nézegettem sokáig, megnéztem hátha tanulhatok valamit és én sem tudtam eligazodni rajta, tanulmányozni most nincs időm.
Nekem azért volt szükség a megszakításra, mert ha egy nagyon gyors PIC-en hosszabb adatokat küldesz és pakolászod be a bufferbe, akkor egy idő után jól betelik.
Ha nem fut végig a program akkor nem tudom letárolni sem.
A kép amit csatoltam az pont ezt hivatott mutatni. A PC-s program egy emelkedő teszt sorozatot küld ami 0-tól 50-ig tart decimálisan. A képen látható, hogy az adat küldés eljut 13-ig vagy is a 0x0c-ig. A PC kiküldi a következőt 14-eset vagy is a 0x0d-t, de azt már a PIC nem dolgozza fel. Tehát akkor ha egy tömböt töltenék fel lenne benne 13 adat az 50-ből. Persze újabb futtatásnál, lehet csak 1szer vagy 2 szer vagy 8szor futna le. Minden indításnál random, van úgy hogy mind az 50 adat beérkezik. Szóval nem tudom mi lehet a gond. Droot: biztosan jó, de sajna 18F442-vel nem kompatibilis. Pár paraméter után már lefutott a kód, de hibázik ezért inkább maradok egy fapados változatnál, hátha rájövök miben hibázok. A hozzászólás módosítva: Feb 1, 2016
Nem fut végig ezt honnan veszed? Lehet, hogy valamiért "csak" nem dolgozza fel !? Nem írtad, hogy lefagy ?!
A soros porton érkező jelnek HARDVERESEN be kell kerülnie az RX regiszterbe, ez szimulációnál is látható ( azt nem tudom, hogy PROTEUS alatt ezt meg tudod-e nézni, MPLAB alatt igen!)!
A kellemetlenségeket elkerülendő teszteléshez a 0x20 .. 0x7E közötti karaktereket használd. Ugyanis a 0x0D a "Carrage Return" vezérlőkarakter, a 0x0A a "New Line", amit a soros port monitor értelmezhet.
Ha MpLab8 alatt fordítanál, tesztelnél, lehetőséged lenne az UART vételt egy Register Injection stimulussal vezérelni a szimulációhoz. Töréspontokkal megállíthatod a vételi megszakításkezelő, a bufferkezelő, stb rutinokat. Nem kell más, mint létrehozni egy az RCREG regiszterbe injectáló file stimulust és egy adatállományt. Rengeteget segített nekem is....
Ezt onnét tudom, hogy a PC-s program "lefagy".
A fagyás oka pedig az, hogy 0x0D kiküldetése után nem jön a PIC-től visszaigazolás. A visszaigazolás hiányában PC-s program vár addig ameddig nem jön jel, szóval végtelen ideig vagy is ez már felfogható fagyásnak. PIC vagy is a főprogram veszettül pörög és várja az adatot, de mivel PC is vár, így mind ketten csak egymásra várnak, vagy egy sült galambra ami az éteren keresztül repül a szájukba MPLAB alatt nem tudok tesztelni, nem tudom, hogy kell és éles hardver még nem áll rendelkezésemre. (Talán a héten vagy köv héten elkészül a nyák)
Átállítottam a tartományt 0x20-tól Decimális 0x32-ig tartományra.
Sajnos továbbra is megáll az adatfolyam. Sajnos egyelőre MPLAB-ban nem tudok tesztelni.
Ráfutás történik: Az elsőnek vett adatot nem olvassa ki a programod mielőtt a következő vétele befejeződik. Ha FRERR vagy OERR hiba keletkezik, a karaktert eldobja a kiszolgáló rutin és nem küld helyette más adatot. Nem fogod megúszni a két buffer kezelését. Nem kell nagynak lennie. Elegendő a maximális távirat méret és még egy kicsi. Az adatok közvetlen küldére helyett egy ellenőrzött adatátvitelt kellene használni. Az ellenőrzésnek ki kellene mutatnia az ilyen elvesztős hibákat. Ha hiba van, akkor az egész táviratot meg kell ismételni.
Nézd meg az Intel hex formátumot. ":" -tal kezdődik minden rekord - könnyű keresni, nem fordul elő másutt. A rekord végén egy egyszerű ellenőrző összeg. Próbáld meg azt leprogramozni, hogy egy 16 byte adato tartalmazó hex rekordot átküldesz, leellenőrzöd és visszaküldöd. Így a PC -n látni fogod, hogy jól működik. A hozzászólás módosítva: Feb 1, 2016
Az SPBRG = 20 nem jó. Az már több mint 119000 Baud.
21 kell, de az is 1,3% eltérés a 115200-hoz képest (113636). Ilyen hosszú adatfolyamnál atompontosan kell összehangolni a két sebességet, vagy szakaszosan adni, hogy szinkronizálhassanak, különben elcsúszik minden. Idézet: USART-ot használ, az meg a START-STOP elvet, ami még a távíróknál is működött, mert minden byte átvitele után "szinkronizál" a START bittel ! Az 1,3%-os eltéréssel "simán" mennie kell, akármilyen hosszú adatfolyammal is / ha egy byte vétele tuti, akkor a többinek is jónak kell lennie az elv miatt! / „Ilyen hosszú adatfolyamnál atompontosan kell összehangolni a két sebességet, vagy szakaszosan adni, hogy szinkronizálhassanak, különben elcsúszik minden.”
Az USART nem élvezérelt kommunikáció, hanem mintavételes. Vagyis nem "szinkronizál", hanem adott időpontban vizsgál. Emiatt, ha nem pontos a Baud érték a két végén, simán Start bitnek érzékel egy 0-át az előző bájtból és vége a szinkronnak.
|
Bejelentkezés
Hirdetés |