Sziasztok!
Szeretném megismerni a timerek működését, de egy kicsit kusza még.
Addig eljutottam, hogy be kell állítani, honnan kapja az órajelet a timer, mennyivel ossza, és a túlcsordul, akkor egy bitet magasba állít. Ha jól sejtem, akkor ez a program futásától függetlenül megtörténik.
Gondolom, a számláló értékét nullázni is tudom, illetve adott értékre be tudom állítani, hogy indítás után onnan számoljon.
A feladat, amit meg szeretnék oldani, hogy RA0 bemenet hatására RB0 kimenet magas lesz, és két feltételre menne újra 0-ra: vagy RA1 bemenet kapcsolja le (eddig nem is lenne gondom), vagy az RA0-ra induló timer0 kapcsolja ki. Emellett ugyanez a funkció RB1 kimenetre is, RA2-re indul, és RA3-ra vagy timer1-re állna meg.
Egy jól kommentelt ASM példaprogramot nagyon szépen megköszönnék.
Üdv: Jácint
Sziasztok!
Köszönöm mindenkinek a segítségét. Működik, amit szerettem volna. Tényleg csak egy kicsi lökés kellett, hogy tisztán átlássam.
Oszinak külön köszönet a csatolt dokumentumért, tulajdonképpen egy olyan példaprogramot kerestem.
Üdv: Jácint
0
Hello Jaca.
Ha majd ráérsz, írd meg nekem ehhez a programot...egészségedre! De citromszelet adagoló is lesz rajta...
Üdv.: Uniman
0
Ez jópofa :) De tartok tőle ha az a búzasör 5 fokkal melegebb lenne akkor nem nézne ki ilyen jól a bemutató.
0
Szia ty!
Épp most küzdök az analóg bemenet konfigurálásával, hogy a hőmérséklettől függően szabályozzam az elfordulási szöget. :)
Üdv: Jácint
0
Szia Jácint!
Kezdjük az elején, hogy ugyanarról beszéljünk.
- Feltételezem van datasheet-ed a processzorról, ez az alap.
- Nem ártana tudnunk, hogy ez egy 16F627 vagy esetleg egy 16F627A.
- A timer beállításához tudnunk kell, hogy milyen órajelről járatod a processzort és milyen időzítés az amit be szeretnél állítani. Esetleg az időzítés pontosságát is add meg ha kritikus paraméter.
- Találd ki, hogy szeretnél-e interrupt-ot használni a feladathoz - esetünkben ez nem feltétlenül szükséges.
- Válassz ki egy timert a feladatra (pl. Timer0 vagy Timer1) és olvasd át a működését. Próbáld önállóan meghatározni a beállítani kívánt paramétereket, regiszterek értékeit.
Csinálj egy egyszerű vázlatot arról, hogyan fog működni a programod.
Ezek után írd le, hogy hol akadtál el és miben tudunk segíteni.
Üdv, ty
0
Még egy kis info:
A timer jellemzően egy utasításidőnként (ez a processzor órajelének a negyede) számol egyet ha az előosztó/utóosztó 1:1 állásban van.
Tehát 4 MHz órajel esetén 1 MHz a timer alapja, azaz 1us. Ha ehhez beállítasz pl. egy 1:8 osztót, akkor már 8us-ként fog számolni egyet.
Esetünkben a timer0 felfele számol, és ha 0xFF-ről túlcsordul 0x00-ra, akkor van a timer esemény, ami a TMR0IF flag 1-be állása.
Tehát ha a 4MHz órajellel 10us-et szeretnél időzíteni (ez egy nagyon elméleti példa) akkor (0xFF-10+1) értékre kell állítanod a timert, azaz 246 azaz 0xF6 értékre.
Valósabb példa amikor az ember 1ms környékére próbálja belőni a timert és ehhez egy osztót is használ. Mert ugyebár a 8 bites timerrel esetünkben maximum 256us lenne beállítható
osztó használata nélkül.
De az van, hogy ez baromi sok betű és lehet h. olyasmit írok amivel régen tisztában vagy. Ha van rá igényed adok egy Skype elérést privátban és pár percben beszélgethetünk kicsit a témáról ha érdekel.
0
Szia!
Hát nekem biza 10 másodpercnyi időzítés kellene. Ehhez szerintem az órajelet le kell vinnem, ami nem gond, külső ellenállással le lehet menni. Az alkalmazás nem kíván se pontosságot, se gyors reagálást. Konkrétan egy paneltovábbító konvejor vezérlése lenne a végső cél, csak ezzel a timer funkcióval nem volt dolgom, és nem találtam asm-es példát kimerítően kommentelve. Amit kellene tudnia, hogy míg pörög az időzítés, addig más eseményekre is tudjon reagálni a cucc, ezért a "for next" típusú késleltetés nem jó. Ja, sima 627, nem az A-s tipus. 3 motor van, ami indítástól számítva 10 másodperc után meg kell álljon, ha nem történik semmi, és nem egyszerre vannak indítva.
Üdv: Jácint
0
Nem kell lemenjél az órajellel. Beállítasz egy timert vm. jól kezelhető értékre, maradjunk az 1ms-nél.
Utána számolod egy változóban, hogy hányszor jelzett a timered. Ha a változód elérte a 10.000-et az 10 másodperc.
Ha 3 időzítés kell, az 3 egymástól független változóval oldható meg. Akkor nullázod őket amikor akarod, ott vizsgálod őket ahol akarod.
ASM kóddal nem fogok tudni segíteni, mert nem használom.
A programot ilyenkor (meg máskor is) úgy szokták felépíteni, hogy egy végtelen ciklusban pörög a kód és ezen belül vizsgálod a timer változókat is.
Maga a timer emellett mehet megszakításból, de nem feltétlenül szükséges.
pl.:
_program_belépési_pont_
inicializálás();
while(1)
{
BemenetekKezelése();
KimenetekKezelése();
TimerEseményekVizsgálata();
}
Ezen túl lehet egy timer interruptod, ami 1ms-ként lefut és növeli (nálam inkább csökkenti) a timer változókat
-------------
De továbbra sem írtál semmi konkrétumot, hogy mivel vagy elakadva, miben kell a segítség.
Egy timer beállításához minimum az órajelet kell tudni és azt, hogy milyen időzítést szeretnél elérni.
A kérdésnek valahogy így kellene hangzania: "4MHz órajelnél szeretném a timer1-et 0.1 másodpercre beállítani, ehhez kérnék kommentezett ASM kódot"...
0
Szia ty!
Ott vagyok elakadva, hogy még soha sem használtam timert. Az összes bit bájt és I/O műveletet vágom, az asm-mel régóta foglalkozom, és az alapműveletekre rengeteg példa is van. De olyat nem találtam sehol, hogy adott bemenetre elindul egy timer, ami 60ms után bekapcsol egy kimenetet. asm-ben legalább is nem. Annyit már a nyitó szövegben leírtam, hogy RA0 bemenetre adott magas szintre bekapcsol RB0 és RA1-re vagy a timer0-ra kikapcsol. Ha most kiegészítem 4 MHz-el és 10 secundummal, attól még az alap nem fog változni. (Na jó, a 10 secben van már némi trükk.)
Igazából nekem az lenne a fontos, hogy egy példaprogramon lássam, hogy kell kezdő értéket adni a számlálónak, hogy kell elindítani, és hogy kell ellenőrizni, hogy lejárt (túlcsordult). Ha már látom az alapot, akkor azt tudni fogom az igényeim szerint formálgatni.
Üdv: Jácint
0
Ok. Bontsuk részfeladatokra:
1) Adott bemenetre elindul egy timer
- Bemenetet már kezeltél, tehát marad a timer elindítása.
- Úgy látom a timer0 egyszerű mint egy bot. Ki se lehet kapcsolni. Gyakorlatilag van kb. három lehetőség amit állíthatsz és kész.
A timer működése, hogy számol fölfele a TMR0 regiszter és amikor túlcsordul akkor az INTCON regiszter TMR0IF bitjét '1'-be állítja. Ha engedélyezve van a timer0 interrupt (nem tudom megszakításokat szoktál-e használni, erre külön kitérhetünk) akkor bekövetkezik az interrupt, ahol a programod megállapítja, hogy ez a bit '1'-ben van, törli és újra beállítja a TMR0 regiszter értékét annyira,
hogy (a korábbi példánál maradva) 1ms szükségeltessen az ismételt túlcsorduláshoz.
Emellett hozzáad egyet az eltelt milliszekundumok számához.
Az egész kódot nagyon egyszerűen el tudod kezdeni írni és tesztelni:
- Kell a processzorra két LED
- Törlöd a TMR0IF bitet
- Ellenőrzöd, hogy a TMR0IF valóban nulla-e, ha igen akkor bekapcsolod LED1-et.
- Vársz amíg TMR0IF bit '1' lesz, majd bekapcsolod LED2-t.
Azt fogod tapasztalni, hogy a kódod lefutása után két LED világít.
Tovább bonyolítva berakod az egészet egy végtelen ciklusba és a LED-et negálod minden timer bekövetkezésnél és szkóppal megnézed milyen gyakran következik be a timered.
Ha ez megy a többi is fog!
0
Sziasztok!
Olyat nem lehet csinálni, hogy az egyik bemenet közvetlenül indítsa timert. Figyelni kell a bemenetet majd ha megvan a feltétel inicializálni a timert. A csatolt PDF 10. oldalán ott a kód amit kerestél. A belső órajelet használva ez a konfiguráció 4Mhz-es kristállyal 250ns*4*8*65536=524,288ms-onként csordul túl, ha vársz 19 túlcsordulást 9,96s-os időzítést kapsz.
A példaprogram az időzítő túlcsordulás bitjét figyeli és vár a túlcsordulásra.
Üdv,
Oszi
0
Szia!
"Hát nekem biza 10 másodpercnyi időzítés kellene. Ehhez szerintem az órajelet le kell vinnem" Nem érdemes, mert akkor minden más feladatvégrehajtás is lassul ! Ha kimérsz vele pl. 10 ms-ot ( ez belefér pl. 64-es előosztóval is !), akkor abból 1000-et leszámolva pont 10s telt el !
Üdv: Steve
0