Fórum témák
» Több friss téma |
Fórum » PIC - Miértek, hogyanok haladóknak
Szia!
Először mindenképp assembly-vel kezdj PIC-et programozni! Most már négy hónap elteltével nagyon örülök neki hogy amikor én is hasonló kérdést tettem fel mint most te, akkor Watt meggyőzött hogy assembly-vel kezdjek. Visszatekintve tényleg nagyon hálás vagyok neki ezért. A C-vel egyenlőre még csak szemezgetek de már így is látom hogy rengeteg haszna volt az assembly tanulásnak. A C-vel tényleg sokkal egyszerűbb a programfejlesztés de ha nem érted a PIC működését akkor nem sokra mész vele. Először assembly aztán ha abban már megy minden akkor jöhet a C. Idézet: „. Van hátránya a C nyelvnek?” Van. Van hatranya az Assembly nyelvnek? Van. Melyik a jobb nyelv? Az egyik -- de az is lehet a masik... Bocs, de tenyleg nem lehet megmondani, Assemblyvel tomorebb es gyorsabb kodot lehet irni (ha ertesz hozza), C-vel meg gyorsabb a fejlesztes es talan kevesbe hibazhat benne az ember. Idézet: „(Assembly-hez nem nagyon értek. Azért szeretnék a C-vel programozni, mert azzal nagyobb progikat kevesebb sorban lehet megírni.)” Ez rendben van, es nincs is semmi gond vele. Azonban az Assembly-t azert kell megtanulni mikros kornyezetben, mert nagyon sok pelda asm-ben van meg. Adatlapban is asm-ben fogjak leirni mi hogy mukodik. Tehat ha nem is abban fejlesztesz, azert illik tudni, hacsak nem szeretnel masoktol, harmad kezbol kapott informaciokbol megoldani a dolgaidat.
Sokszor leírt álláspontom az, hogy a PIC egy áramkör, ezért úgy kell vele bánni. Meg kell ismerni minden lehetőségét az összes "kapcsolóját", "vezetékét". Ezt a C elfedi, soha nem érted meg rajta keresztül a valós működést, ami űrt képez benned, amit nagyon nehéz lesz később betömni.
Az asm alapból 35 utasítás, amiből 20-at használunk legtöbbször(18F-eknél kényelmi kiegészítő parancsok is vannak, de nélkülük lehet programozni, csak nem érdemes). Egyszerű, de a program összetett. Lépésenként mondod el mit tegyen a PIC, ezért nehéznek tűnik, de ha ráérzel az ízére nem fog gondot okozni. Sok esetben az életben is hasznád veszed a "gépi kódú" gondolkodásnak.
Sziasztok!
Kérlek ne röhögjetek, mert Nektek valszeg primití lesz a kérdés, de valaki elmagyarázná nekem, hogy az alábbi kódrészletből hogyan lesz 1s-es megszakítás? Tudom ez alapvető digitális technika ismereteinek hiányára utal, de légyszi segítsetek! movlw B'00000001' ;tmr1 interrupt engedélyezés movwf PIE1 ; bcf STATUS,RP0 ;bank0 kiválasztás ;------------------------------------------------------------------------------- movlw B'00101111' ;külső órajel, négyes előosztó(a 8sec-es IT-hez), timer indítás movwf T1CON bSf INTCON,GIE ;GLOBÁLIS INTERRUPT ENGEDÉLYEZÉS bsf INTCON,PEIE ;periféria interrupt engedélyezés movlw H'E0' ;1s múlva kikapcsolja a timer rutin movwf TMR1H clrf TMR1L Az én értelmezésem: A HW-ben 20Mhz-es kristály ketyeg, így 1 gépi ciklus 1/20000000*4=200nS alatt fut le. A TIMER-be betöltünk 57344-et, ami minden 4. (4-es előosztás miatt) ciklussal növekszik. Így 6.5528 mS alatt éri el a túlcsordulást.
Majdnem jó az értelmezés, annyi az eltérés, hogy nem a főoszcillátorról fut a timer, hanem a T1OSC lábakra kötött 32768Hz-es kvarcról.
Egyébként így nem lesz belőle minden körülmények között pontosan 1s-os megszakítás, mert ha a megszakítás bebillenése és a kiszolgálása között a 32768Hz-es oszcillátornak bejön egy újabb periódusa, akkor az utána érvénytelenítve lesz a megszakítási rutin folyamán.
Köszönöm a választ!
T1CON regiszter 1. bitje választja ki, a 3. bit engedélyezi a külső oszcillátort... Rájöhettem volna, de köszöm mégegyszer! Mivel ez a program, amiből kiemeltem, egy LED-et gyújt ki 1s-re, itt nem kellett a halálpontos időzítés.
Bocsánat, ha már itt tartunk, leírnád, hogy hogyan oldható meg a pontos 1s ? Igaz még csak most tanulgatom a PIC-programozás rejtelmeit, de később jól jöhet.
Köszönöm előre is!
Én a múltkor úgy oldottam meg, hogy kiszámoltam, hogy egy 20Mhz-es kristálynál mennyi órajel után telik el pontosan 1 ms és ez alapján már akármilyen időzítést tudsz csinálni.
20Mhz = 20.000 Khz = 20.000.000 Hz Ebből következik, hogy 1 másodperc alatt pontosan 20.000.000 órajel van. Azt nem mondom, hogy 100%-osan pontos de szerintem elég közel van hozzá.
Szia!
Több megoldás is lehet: - TMR1, külső 32768 Hz kvarccal. A TMR1H regiszter legfelső bitjét a megszakítási rutinban 1 -re kell állítani a kiszolgálás során. Az íráshoz el kell olvasni a Timer1 errata-t. - TMR2 belső órajellel. A megszakítás a belső órajel leosztott frekvenciával. Egy további szoftver számlálóval előállítani az 1 másodpercet. Itt nem kell a timer regisztereit írni, de nem megy sleep-ben. - TMR2 PWM üzemmódban órajelet előállítani a TMR1-nek (külső összekötés). Ebben az esetben nem kell külső kvarc. Sajnos ez sem megy sleep üzemben.
Nem ez a gond, hogy ki kell számolni, mert az fix lenne. Az a gond, hogy ha a megszakítás kiszolgálásánál fix értékkel csinálsz valamit, akkor az bizonyos esetekben jó, bizonyos esetekben meg nem. Pl. cape-t esetében vegyük azt, hogy bejött a timer1 megszakítása, de már egy másik megszakítás folyamatban volt, aminek a kiszolgálása hosszabb ideig tart, mint amennyi a 32768Hz-es oszcillátor egy periódusa (most az más kérdés, hogy egy megszakítás ne legyen hosszú idejű, de előfordulhat). Ez idő alatt az oszcillátor a TMR1 regiszterpáros előtt álló előosztón már billent annyit, ahány periódus eltelt. Ha viszont a megszakítási rutinban lefuttatunk egy utasítást, ami módosítja a TMR1L tartalmát (ugye a clrf is ezt csinálja), azzal az előosztót is töröljük, vagyis az előzőleg eltelt periódust gyakorlatilag eldobtuk és ismét nulláról indult az előosztó is. Persze ez nem gond mindaddig, amíg nem telik el egy periódusnyi idő a megszakítás bebillenése és a TMR1L módosítása között, mert akkor eleve nullán van még az előosztó. A megoldás erre az lenne, hogy nem használunk előosztót a timer1-nél, így nincs ilyen "rejtett" nullázásból fakadó probléma. A másik, hogy ha nincs előosztó, akkor viszont a TMR1L fog nullától már különbözni a törlés pillanatában, vagyis ezzel meg itt dobtuk el a periódust. A megoldás vagy az, hogy nem macerálunk semmit a TMR1 regisztereknél, vagy úgy csináljuk, hogy ne rontsuk el a számlálást. Előbbi nem kivitelezhető, mert akkor a 32768Hz-es oszcillátorról csak minden második másodpercben csordulna túl a timer1. Ezért azt kell csinálni, hogy csak a TMR1H regiszter legfelső bitjét billentjük 1-be a megszakítási rutinban, és előzőleg a timer1 konfigurálásánál engedélyezzük a TMR1H és TMR1L független írását-olvasását. 16F és kisebb kontrollereknél ez eleve így van, 18F-nél erre való az RD16 bit a T1CON regiszterben, amit jelen esetben nullára kell állítani. Így a megszakításjelző bit bebillenése mindig pontosan 1 másodpercenként fog bekövetkezni, függetlenül attól, hogy a kontroller mikor fogja lereagálni a megszakítást. Ez érvényes egészen addig, amíg nem tart egy másik megszakítási rutin futása 1/128 másodpercnél, vagyis kb. 7ms-nál tovább. Ha még ettől is tovább tart, akkor viszont már előfordulhat, hogy a TMR1H módosításakor a módosítás közben billen egyet, mi viszont a régi értékét írjuk bele vissza a legfelső bit 1-be billentése mellett. Ezért ebben az esetben arra is figyelni kell, hogy a TMR1L nem csordul-e majd túl közben. Ha ezt is megoldottuk, akkor ezen kívül már csak abból lehet gond, hogy a TMR1H legfelső bitje már eleve 1-ben van, amikor billentenénk 1-be. Na akinél ez előfordul, az meg inkább hagyja az egészet olyanra, aki ért is hozzá.
Érdemes megnézni pl. 18F4550 adatlapjában az example 12-1-et, illetve ezt a doksit is érdemes olvasgatni. Mellesleg a kilóhertz és a megahertz rövidítései nem személynevek, nem annak a helyesírási szabályai vonatkoznak rá. Tehát nem Mhz, hanem MHz és nem Khz hanem kHz, mert a hertz jele a Hz és a kiló jele a k, a mega jele pedig az M. Ezeket akárhogy állítjuk össze, mindig ugyanúgy kell írni az egyes tagokat. Mellesleg általános iskolás tananyag, talán illene tudni. Ugyanígy a kilóbájt sem Kb, hanem kB, megabájt nem Mb, hanem MB, gigabájt sem Gb hanem GB (mondjuk ezeknél vannak még más dolgok is a tizes-kettes számrendszerből adódóan, de ebbe most ne menjünk bele).
Hali!
Még mindíg akadt kis gondom az eeprommal kapcsolatban, de most nem az írással van baj. Azt szeretném kérdeni, hogy az olvasási sebessége mennyi lehet az eepromnak? PIC16F88-at használok. Sajnos nem találok az adatlapján erre információt. Mert arra találtam utalást neten, hogy az írás az 3-4ms is lehet, de az olvasásról nem tudok semmit. Esetleg ha tudnátok valami oldalt, ahol le van írva az is jó lenne. A távirányítónak 10ms alatt megy le egy jelsorozat, és ha lassú az eeprom olvasás, nem tudom összehasonlítani a mért adatot a lementettel... Írásnál már megoldottam, hogy először beolvassa a kódot, és utána menti le, de lehet hogy akkor olvasásnál is előbb ki kell olvasnom a gyors flash programmemóriába?
Olvasásnál nincs semmi korlát. Amint bebillentetted az RD bitet, a következő utasításnál már olvashatod is ki az EEDATA regisztert (lletve előtte azért a megfelelő bankot válaszd ki, ha nem ugyanott van, ahol az EECON1). Flash programmemóriánál lehet némi késés, ott két NOP utasítás szokott kelleni, de kontrollertől függ, nincs most kéznél adatlap, hogy konkrétan megnézzem.
Nekem is szimpatikusabb a C, ezért szeretnék megtanulni vele PIC-et programozni.
PICKit2-vel debuggolok. A Run gombra kattintok hogy elinduljon a PIC, majd a Halt gombbal megállítom véletlenszerűen. A PIC viszont mindig a goto START1-es soron áll meg! Miért? A programocskámnak van egy kis hibája mert néha hülyeségeket csinál. Ennek kiderítéséhez viszont a hibajelenség bekövetkeztekor le kellene állítanom a PIC-et hogy lássam hol áll meg hogy valemennyire behatároljam a hiba helyét.
Optimalizálások ki vannak kapcsolva? Project->Build options->Project->MPLAB C18->Categories->Optimization és a Debug vagy a Disable legyen kiválasztva.
Nálam nincs ilyesmi ahogy nézem:
Azt hittem, C kódot próbálsz debuggolni. Akkor viszont nem tudom, mi lehet. Ha teszel egy megszakítási pontot valahová, majd futtatod, akkor annál megáll?
Most hogy kérded, nem!
Betettem két megszakítási pontot de egyiknél sem áll meg! Szerk.: Levettem a külső tápot az áramkörről és most már megáll a megszakítási pontokon és ha megállítom akkor már nem a reset vektoron áll meg. Hogy van ez?! Remélem külső táp nélkül is jelentkezni fog a hibajelenség...
Nemtudom, nekem is néha az icd2 furcsa dolgokat csinál. Én csak annyit csináltam, hogy a debugger alatt leszedtem a kiválasztást az icd2-ről, majd vissza, és akkor normális lett.
Most olvasom a válaszaitokat. Köszönöm mindegyikőtöknek a segítségét! Akkor assembylvel kezdek, és ha az megy utána fogok bele a C-be. Észrevettem hogy ez egy összetartó, segítőkész közösség, jó itt lenni! További kérdésekkel fordulok majd hozzátok!
A fenébe... debuggoláskor nem akar előjönni a hibajelenség. A debuggolás miben más annál amikor rendesen fut a PIC?
Most te mit is csinálsz tulajdonképpen? Mert amiből indultunk, ott is azt írtad, hogy debuggolsz.
A PIC-em programja néha egyenlőre teljesen érthetetlen okból belekerül egy cégtelen ciklusba. Van hogy a bekapcsolás után azonnal, van hogy 20 másodperc múlva de van hogy csak 8-10 perc múlva.
Szeretném kideríteni hogy hol van ez a kártékony végtelen ciklus. Ezért debuggolom a PIC-et a PK2-vel. De ha debuggolom akkor a hibajelenség nem jelentkezik sajnos. Már kb fél órája fut a PIC debug módban de nem akar 'lefagyni'. Ezért gondoltam hogy lehet valami különbség a PIC működésében ha debug-ban fut. Annál is inkább mert ezt a mondatot találtam a neten: Idézet: „Programfejlesztések során nagy segítséget jelent egy úgy nevezett ICD (In Circuit Debugger). Segítségével valós (majdnem valós inkább, mert a debug program kicsit eltér a valóditól) működés közben tesztelhetjük programjainkat.”
Hogy miben tér el az éles futás és a debug, azt nem tudom én sem. Próbálj rákeresni a neten.
Nem lehet, hogy összefügg a probléma olyasmivel, hogy az RB6, RB7 lábak lebegnek normál futásnál, te pedig megszakítást tettél a PORTB változására, viszont nem kezeled le azt az esetet, ha RB6 vagy RB7-en jött változás?
Ez nagyon jó tipp de sajnos ez nem lehet probléma. A PGC és PGD lábakra egy multiplexált hétszegmenses LED kijelző két szegmense van kötve.
Hali
Lehet olyan problema, hogy a PK2 nem valos idoben debugol. En probaltam, es pl az IT-ket nem lehet rendesen figyelni, mert van kommunikacio a PIC es a MPLAB kozott es nem jon at minden adat. Probald meg a programodat a SIM-ben debugolni. Talan ott rajossz a turpissagra. Udv Vili
Hol van a programodban olyan ciklus, ami végtelenné válhat? Keresd meg az ilyen helyeket, és nézd meg, hogy mi történhet, ami miatt beragad. Aztán lehet, hogy ez valami hardveres probléma, a használt chip errata lapját sem árt elővenni és megnézni, hátha van valami gond a chippel. Pl. magas szintű megszakításnál ha MOVFF utasítás közben jött megszakítás, és RETFIE FAST-al lépsz ki a megszakítási rutinból, akkor az a WREG tartalmát elrontja a 18F4550 és kisebb társai A3-as revíziójánál.
Idézet: „Hol van a programodban olyan ciklus, ami végtelenné válhat?” Hát ezaz... elméletileg sehol. De olyan magas bonyolultságú a program hogy ezt lehetetlen átnézni... A gyakorlatban hangsúlyozom hogy percekig tökéletesen működik, ennyi idő alatt több százszor végigfut minden ciklus. Aztán több száz vagy több ezer lefutás után, 8-10 perc elteltével jelentkezik a hibajelenség. Idézet: „Aztán lehet, hogy ez valami hardveres probléma, a használt chip errata lapját sem árt elővenni és megnézni, hátha van valami gond a chippel. Pl. magas szintű megszakításnál ha MOVFF utasítás közben jött megszakítás, és RETFIE FAST-al lépsz ki a megszakítási rutinból, akkor az a WREG tartalmát elrontja a 18F4550 és kisebb társai A3-as revíziójánál.” Na ez egy érdekes dolog, megpróbálok utánanézni ezeknek. Összefüggést ugyanis nem sikerült találnom hogy mitől függően jön elő a hiba. |
Bejelentkezés
Hirdetés |