Fórum témák

» Több friss téma
Fórum » DS1307 inicializálása
 
Témaindító: fookos, idő: Jan 29, 2008
Témakörök:
Lapozás: OK   1 / 7
(#) fookos hozzászólása Jan 29, 2008 /
 
Sziasztok!

PIC órát építek, és DS1307-et használok hozzá. Minden szépen működik, de a teljesség kedvéért nem hagy nyugodni, hogy hogyan kezeljem le az első bekapcsolásnál a DS1307 inicializálását. Az adatlapjában a következők állnak:

1.) "Note that the initial power-on state of all registers is not defined. Therefore, it is important to enable the oscillator (CH bit = 0) during initial configuration."

2.) "Illogical time and date entries result in undefined operation. Bit 7 of Register 0 is the clock halt (CH) bit. When this bit is set to 1, the oscillator is disabled. When cleared to 0, the oscillator is enabled.

Vagyis, lehet, hogy szemét fog a csipben állni bekapcsoláskor, és ha csak a CH bitet állítom 0-ba, akkor is mindent nullára kell állítanom inicializálnom.

De az is lehet, hogy a CH bit már nulla az első bekapcsoláskor (hisz ez is belefér a nem definiált fogalmába). Ilyenkor viszont, ha nincs szerencsém akár 29:87-t is állhat az óráknál (hiszen nem definiált) ami viszont hibás működéshez vezethet.

Szóval nekem úgy tünik, hogy a CH bit vizsgálata sem elégséges ahhoz, hogy tudjam, hogy első bekapcsolás történik, vagy már be lett az óra állítva, és minden OK.

Sokat keresgéltem a neten, és sok progit átrágtam, de erre a kérdésemre nem kaptam választ.

Szóvala kérdéss röviden: mi a helyes módja a DS1307 üzembevételének, és hogyan tudom, hogy már allítottam be helyes időt (vagyis korrekt a tartalma) illetve, hogy még nem lett beállítva semmi, és lehet hogy a chip tartalma hibás és csak szemét.

Segítségeteket előre is köszönöm!
(#) levy_k hozzászólása Jan 29, 2008 /
 
Én egy aksit raktam a DS-re, így nem kell ellenőrizgetni állandóan, hogy első beállítás vagy sem.Tegyél egy reset gombot is az órára, ami minden regisztert alapállapotba tesz (pl. 00 óra 00 perc stb.).
Üdv.
(#) fookos válasza levy_k hozzászólására (») Jan 29, 2008 /
 
Természetesen van aksi a DS-en.

A reset gombot jó ötletnek, de azért tulzásnak tartom. Plusz HW ás plusz SW egyben.

Egyébként azon gondolkodtam, hogy beírok az SD RAM-jába a 0x3C-től kezdődöen (x3F-4) egy 4 szavas szót (pl: "AZ1+"), és initkor kiaolvasom és ellenörzöm, hogy benne van-e. Ha nincs, akkor tuti, hogy még nem használtam a csipet és teljes initet hajtok végre.

Ez a módszer viszont felveti azt a kérdést, hogy a csip RAM-ja elveszti-e a tartalmát, ha az aksit kiveszem a foglalatból.
(#) levy_k hozzászólása Jan 29, 2008 /
 
Nem úgy van feltüntetve mint "NV" RAM szal, sztem felejt, de próba cseresznye.Nekem október óta megy egy DS egy kis akkun, külső táp nélkül.A DS-ben van egy kis töltő is, ami a külső táp megjelenésekor tölti az aksit.Nagyon el van találva.
(#) gyengus válasza fookos hozzászólására (») Jan 29, 2008 /
 
Én is pices órán dolgozok DS1307-el .
Én gombelemet raktam rá.
Abból indultam ki, hogy 1. bekapcsoláskor úgyis beállítom az időt, ez esetben a CH bit 0 lesz, a későbbiekben úgyis ott az elem.
Mellékelem a forrást, hátha érdekel vkit, C18-hoz van.
Még csak maóta megy, volt pic reset, áramtalanítás, jónak tűnik.
(#) fookos válasza gyengus hozzászólására (») Jan 29, 2008 /
 
Bár én asm-ben dolgozom linuxról (gpasm, gplink, gputils, picprog) az init_rtc()-ben kinullázod a teljes másodpercet. Vagyis, ha ezt minden PIC resetnél/bootnál felhívod, akkor eléggé hamar sokat fog késni az órád (pl, ha xx:yy:59-kor 00-t írsz a másodpercek helyébe).

Pont ez a dilemma, ami foglalkoztat. Hogy teljes reset-et csak egyszer kell a DS1307-nek adni, méghozzá legelső alkalommal. Utána már erre nincs szükség. De pontosan honnan tudjam, hogy melyik a legelső alkalom?

Ha a CH-bit 1-ben van, akkor ruti, hogy első bekapcsolás történt. Ilyenkor nyugodtan lehet mindent resetelni.

De ha a CH-bit 0-ban van, akkor fut az óra, és bármilyen értéke lehet. Erre volt a sztringírós javaslatom. Annak az esélye, hogy egy sztring vagy számsor pontosan ugyan úgy megtalálható legyen az óra RAM-jában az eléggé alacsony. Vagyis ha CH=0 és van string, akkor fut az óra. Ha CH=0 de nincs string, akkor teljes resetet kell végrehajtani.

De ez még mindignem 100%-os megoldás, és lehet, hogy x millió bekapcsolásból 1-szer téved az algoritmus.

Tehát a kérdés továbbra is fennáll, hogy hogyan lehet 100%-osan kitalálni, hogy a chip még nem volt inicializálva.

(#) levy_k hozzászólása Jan 29, 2008 /
 
Az aksit (backup-osra gondolok) rákötöd az analóg bemenetre vagy egy interruptos lábra, és figyeled a feszt vagy az interruptot.Amikor megjelenik egy felfutó impulzus (az aksit beteszed az órába) vagy a fesz szintet ellenőrzöd.(ez arra is jó lehet, hogy jelezze az alacsony aksi szintet)
(#) gyengus válasza fookos hozzászólására (») Jan 29, 2008 /
 
Az init_rc()-ben csak a control regisztert (07H) nullázom.
A CH bitet csak időbeállításkor.
Lehet, hogy nem gondoltam minden eshetőségre, de szerintem ennyi elég. Eddig működni látszik.
Ha hülyeséget ír ki, akkor meg úgyis beállítom.
(#) fookos válasza gyengus hozzászólására (») Jan 29, 2008 /
 
Kisérletezgettem egy kicsit.

1.) Aksi nélkül el sem indul a cucc. I2C hibát kapok.

2.) Ha kiszedem az aksit, akkor úgy tünik, hogy a CH bit 1-be fordul. Szóval elégha erre vizsgálunk. Itt a kód:



ds1307_init
movlw b\'00010001\' ; 4 096 Hz a kimenetre kapcsolva (teszt célokra)
movwf v_dsf1307_byte
movlw RTC_CONTROL ; 0x07 a Control byte
call ds1307_w_byte ; írjuk ki

movlw RTC_SECONDS ; vizsgáljuk meg a CH bitet, és ha 1-ben van
call ds1307_r_byte ; akkor töröljük, és inicializáljuk az órát
addlw b\'10000000\' ; ha 0-ban van, akkor készen vagyunk
btfss STATUS, Z ; az óra jár
return

ds1307_clear
call I2C_Start ; akkor nullázzuk ki az órát

movlw RTC_DEVICE_W
call I2C_Write

movlw RTC_SECONDS
call I2C_Write

movlw 0x00
call I2C_Write ; seconds (00-59)
call I2C_Write ; minutes (00-59)
call I2C_Write ; hours, 24 hour-mode (00-24)
movlw 0x01
call I2C_Write ; day (1-7)
call I2C_Write ; date (1-31)
call I2C_Write ; month (1-12)
movlw 0x00
call I2C_Write ; year (00-99)

call I2C_Stop

return
(#) MPi-c válasza fookos hozzászólására (») Jan 29, 2008 /
 
Hát én is ezt az RTC-t építettem be az órámba.
Én nem vizsgálgatom az óra állapotát, (CH bit vagy bármi más) hanem a PIC eepromjába, adott címre egy értéket írok. Első induláskor ezen a címen nulla van, az első beállítás után pedig nem nulla. Ha a program a nullát detektálja betölti a kezdő időt és dátumot az RTC-be, ami nálam 2008. 01. 01. 00.00.00 (persze bármi lehet) és természetesen a dátumnak megfelelő hét napja. Nálam is van gombelem.

Idézet:
„Aksi nélkül el sem indul a cucc. I2C hibát kapok.”

Ez érdekes, nálam ilyen nem jelentkezik és furcsa is lenne, hisz nem kötelező az RTC mellé gombelemet tenni, anélkül is menni-e kell. És hát megy is, így úgy tűnik, hogy a tápfeszt rákapcsolva a CH bit is nullába fordul, vagy egyből nulla, tehát azt nem nagyon tudod vizsgálni.
(#) fookos válasza MPi-c hozzászólására (») Jan 29, 2008 /
 
Ha az aksis lábat (pin 3) földre kötöm, akkor megy is. Ha aksi van rajta akkor is megy. De ha csak lóg a levegőben akkor I2C hiba lép fel.

Egyébként mi történik az óráddal, ha aksit cserélsz? Hisz a PIC eepromjában ot csücsül a szépen megjegyzett bájtod, miközben a DS1307 szépen kinullázódott és az adatlapja szerint nem definiált értékekkel indul újra.
(#) MPi-c válasza fookos hozzászólására (») Jan 29, 2008 /
 
Nem gondolom, hogy sűrűn kellene aksit cserélni, hisz csak áramszünetre van.(Alaplapokon is jó pár évig kitart). Természetesen törölni kell az eeprom adott címét, vagy programzással vagy egy beállítási (menü) ponttal pl: "Elemcsere"
(#) MPi-c válasza fookos hozzászólására (») Jan 29, 2008 /
 
Idézet:
„miközben a DS1307 szépen kinullázódott és az adatlapja szerint nem definiált értékekkel indul újra.”

Ha lemerül az aksi azt csak akkor látom meg, ha egy áramszünet miatt újra indul az óra.Már igen régóta próbálgatom ezt az IC-t, de mindig nulláról indult - beírás nélkül is - tehát nem "nem definiált értékről", egyszerűen csak nulláról, illetve a DAY regiszterbe 1 kerül.
Egyébként, ha elemet kell cserélni, valószínű, hogy az órát is állítani kell, tehát az is mindegy, hogy volt-e már korábban beállítva.
(#) fookos válasza MPi-c hozzászólására (») Jan 29, 2008 /
 
Ha definiált értékekkel indul (és úgy tünik, hogy avval) és nem szemét van a regiszterekben, akkor minden OK és halleluja (egyébként ma én is ezt tapasztalatam).

Ezt viszont az adatlapjában így kellet volna leírniuk a kedves chipgyártóknak...

Mindenkinek nagyon szépen köszönöm a segítséget!
(#) levy_k hozzászólása Jan 29, 2008 /
 
Egyébként én ezt az áramszünet dolgot úgy oldottam meg egy komolyabb cuccban, hogy internetről NTP-vel lekéri a pontos időt minden indítás után és adott időközökben is (pl. 24-óránként).
(#) MPi-c válasza fookos hozzászólására (») Jan 30, 2008 /
 
Egyébként én az eepromos dologgal csak az első beállítást akartam megoldani, mármint, hogy egyből a megfelelő menü jelenjen meg. Azután rájöttem, hogy teljesen felesleges, csak egy gombnyomást spórolok és így is , úgy is a beállítással kell kezdeni. Az is feleslegesnek tűnik, hogy egy "ál kezdőérték" (nálam a 2008. 01. 01....) töltődjön be először.
Szóval, végül is sikerült megoldani egy látszólagos problémát.
(#) fookos válasza MPi-c hozzászólására (») Jan 30, 2008 /
 
Lenne egy újabb kérdésem. Nem pont az init kérdésköre, de még mindig ds1307.

Ha olvasok I2C-vel a chip-ből, nekem csak byte-onként sikerül. vagyis így (pszeudó kódot írok, hogy egyszerűbb legyen):

I2C_Start
I2C_Write( DS1307_Write )
I2C_Write( Adress )
I2C_Stop

I2C_Start
I2C_Write( DS1307_Read )
I2C_Read( one_byte)
I2C_Stop

vagyis kiírom a címet ahonnan olvasni szeretnék, aztán stop, utána meg 1 byteot olvasok.

De ha - a doksi szerint legális módon - több byte-ot szeretnék újracimzés nélkül olvasni, akkor az első olvasott byte rendben van (pl. seconds, ha 0x00-nál kezdek) de a többi már szemetet tartalmaz (pl. a 2. byte a minutes lenne). Ismét pszeudó kód:

I2C_Start
I2C_Write( DS1307_Write )
I2C_Write( Adress )
I2C_Stop

I2C_Start
I2C_Write( DS1307_Read )
I2C_Read( one_byte_1)
I2C_Read( one_byte_2)
I2C_Read( one_byte_3)
I2C_Read( one_byte_4)
I2C_Read( one_byte_5)
I2C_Stop

Egyszerűen nem értem, miért. A doksi szerint működnie kellene a dolognak.

Az I2C rutinjaim a hibásak, vagy ez tényleg nem megy? Esetleg találkoztatok már evvel a problémával?

Válaszaitokat előre is nagyon szépen köszönöm!
(#) fookos válasza fookos hozzászólására (») Jan 30, 2008 /
 
Ok, válaszolok magamnak...

Az ASM szintü I2C kezelés alapjait ebből a hőmérős projektből szedtem. Link a projektre

Ha a csatolt fájlt alaposabban megnézzük, kiderül, hogy az olvasások után ACK és az utolsó olvasás után pedig NACK küldendő. A fent említett linken található progiban ez viszont nincsen lekezelve.

Tehát kell írnom I2C_Read_ACK és I2C_Read_NACK rutinokat. Az olvasás meg valahogy így fog kinézni (pszeudó kód):

I2C_Start
I2C_Write( DS1307_Write )
I2C_Write( Adress )
I2C_Stop

I2C_Start
I2C_Write( DS1307_Read )
I2C_Read_ACK( one_byte_1)
I2C_Read_ACK( one_byte_2)
...
I2C_Read_ACK( one_byte_n)
I2C_Read_NACK( one_byte_n+1)
I2C_Stop

Na majd este.



i2c_read.jpg
    
(#) gyengus válasza fookos hozzászólására (») Jan 30, 2008 /
 
Address után stop és start helyett restart kell az ábra szerint (13. o. figure 6), az Ack-kat se felejtsd ki.
Igaz, én a C18 fveit használom, van olyan amelyikkel lehet több bájtot olvasni, azzal nincs gond.
(#) gyengus válasza gyengus hozzászólására (») Jan 30, 2008 /
 
Közben kiderült, h bugos az idő kiolvasását és beállítását végző fvem .
Az adatlapban tényleg csak az az 1 mondat van a 24 órás üzemmódról? (8. o. 3. bekezdésben)
Nagyon kevés és csak belezavart.
Szal tesztelgettem a szerintem kritikus óra és perc értékekre (9:59, 12:59, 19:59, 23:59).
Először úgy értelmeztem azt az 1 mondatot, hogy megkeverték az órák tárolását, b5 és b4 sorrendje fel van cserélve.
Aztán próbaképp kiszedtem az órák külön kezelését és simán BCD-nek értelmeztem. Így a kérdéses időpontokkor helyesen váltott, utolsónál a napot is növelte, vagyis tényleg az az éjfél.
Ha ez így van, akkor minek kellett az az 1 mondat? Mellesleg a táblázat kapcsolódó sora is félrevezető, szerintem.
(#) fookos válasza fookos hozzászólására (») Jan 30, 2008 / 4
 
Megkérdeztem a gyátrótól is. Neki tudnia kell... Itt a levelezés:

----------------------------------------------------

Dear Maxim,

the ds1307 description writes: "Note that the initial power-on state of all registers is not defined. Therefore, it is important to enable the oscillator (CH bit = 0) during initial configuration.".

Does this mean that the state of the oscillator (CH bit) is also undefined during the first bootup?

Generally: is there a well defined way to tell after a bootup whether this was a first bootup (undefined values) or a later bootup with defined values?

-------------------------------------------------------

Greetings,
As stated in the data sheet the data is undefined and there is no way of determining if the part has been power up before.

-------------------------------------------------------
(#) levy_k hozzászólása Jan 30, 2008 /
 
Jó taktikának tűnik, hogy a pontra menő témáknál saját magadnak adod a pontot.Lehet én is nyittok ilyen értelmetlen topicot, és magamnak osztom a pontokat.
(#) Moderátor hozzászólása levy_k hozzászólására (») Jan 30, 2008
 
Ettől függetlenül a valós megoldást mégiscsak saját maga ata meg (és ráadásul ebből más is tanulhat), valamint az én meglátásom szerint ez nem is olyan gagyi topik, hiszen egy valós probléma állt a háttérben. Azt azért megnézném, hogy szerinted melyek az "értelmes" topikok, ha ez egyáltalán nem az

Persze nem mindennapi dolog, hogy az emberek maguknak adják a pontot (mi sem szoktuk ezt jó néven venni, moderátorok), de amint ezt látni lehet (a hsz-eket végigolvasva), ez egy kivételes eset.
(#) levy_k hozzászólása Jan 30, 2008 /
 
Te tudod, te vagy a mod, nekem 1 szavam se lehet a tiéddel szemben. :nemtudom:
(#) MPi-c válasza (») Jan 30, 2008 /
 
Egyetértek veled, hogy nem volt értelmetlen a topik, de valljuk be az induló kérdés és a mai napon felvetődött további kérdés is látszólagos, vélt problémából indult ki.
Néhány RTC-vel volt csak dolgom: DS1307, DS1337, RTC72421,PCF8583, de egyik sem indult "szemét"-tel, mindegyik nulláról mérte az időt. Ha mégis valaki találkozott ennek az ellenkezőjével, akkor én vagyok a tudatlan.
A második kérdésnél, pedig kiderült, hogy az alkalmazott kommunikáció volt a helytelen, annak ellenére, hogy annak pontos mentét az adatlap tartalmazza.
Óriási pozitívumnak tartom viszont, hogy fookos (vagy főokos) a kérdések feltevése mellett kereste-kutatta a megoldást és arra (az előzőnél egy kis rávezetéssel) magától rájött. Tehát, amit tanulni lehet a topikból: 1. Nem kell egy kérdés után a sült galambra várni. Keresni, olvasni, kísérletezni, a megoldás így meglelhető. 2. Ha valami a sok kutatás és olvasás után sem tiszta, meg kell kérdezni.
Szerintem nagy a valószínűsége, hogy másban is felvetődnek azok a kérdések, amivel fookos a topikot indította.
levy k!
Én úgy gondolom, nem a pont, hanem a tudás gyűjtögetése számít.
Üdv!

(#) levy_k hozzászólása Jan 30, 2008 /
 
Akkor miért is van pontrendszer :kerdes:
(#) MPi-c válasza levy_k hozzászólására (») Jan 30, 2008 /
 
Hogy inspiráljon.
(#) fookos válasza gyengus hozzászólására (») Jan 31, 2008 /
 
Egy újabb kérdés foglalkoztat, amit így lehet összefoglalni: Időzítve, pollingal vagy interrupt-al érdemes (elegáns) a ds1307-ből az időt kiolvasni?

Időzítve: Egy teljesen jól működő PIC-es órához úgy illesztem a DS1307-et utólag, hogy csak mondjuk percenként 1-szer olvasom ki az időt a DS1307-ből.

Előnye: Könnyen leprogramozható egy meglévő óraprogiból kiindulva. Az óra a DS1307 hiánya esetén is jár a PIC kvarcának a pontosságával. A ds1307 beállítása is megoldott mert minden programozási műveletnél egyszerűen kiírom a teljes időt a DS-be.

Hátrány: Viszonylag nagy kód.

Polling: van egy jó kis végtelen ciklusom (ami pl. a 7-szegmenses LED kijelzőt is kezeli) és ebbe valahova belebarkácsolom a DS1307 I2C kiolvasását. Igy másodpercenként többször is olvassa.

Előnye: Kicsi a kód.
Hátránya: DS1307 nélkül nem éled és jár az óra. Szerintem nem elegáns.

Interrupt: A DS1307-et úgy programozom, hogy a 7-es lábán 1 HZ-s jelet adjon, és ezt rákötöm a PIC egyik bemenetére, ahol evvel interruptot generálok. Erre az interruptra olvasom ki másodpercenként az időt a DS1307-ből.

Előnye: Kicsi a kód. Szerintem nagyon elegáns.
Hátránya: Plusz 1 PIC lábat elhasznál

Az én órám (egyenlőre csak tesz-board-on) jelenleg időzítve jár, mert így gyorsan el tudtam indulni. De alapvetően az interruptos megoldás tetszik a legjobban. De kiváncsi lennék, hogy Ti mit gondoltok, melyik metódust választottátok mikor a programot megírtátok.
(#) gyengus válasza fookos hozzászólására (») Feb 1, 2008 /
 
Lehet, hogy nem elegáns, de én a pollingot használom.
A kijelző miatt úgyis kell 1 végtelen ciklus, nálam ez a mainben van, abban hívom meg a megfelelő lekérdezést és a kijelzőt kezelő fvt.

Az időzítéssel sztem az a gáz, h ha nem pontos, akkor látszólag pontatlan az óra. És nem az számít, h az RTC szt mennyi az idő, hanem, h mennyit mutat, mikor ránézünk. Nekem nem sikerült a pic időzítőjével pontosnak mondható órát összehoznom, ezért is váltottam DS1307-re.

Az interrupt még jó megoldás lehet, de bonyolultabb.
(#) MPi-c válasza fookos hozzászólására (») Feb 1, 2008 /
 
Az első, „időzítős” megoldás nem túl ésszerű. Ha már kezedben van egy eszköz, ami az idő, dátum kezelésére lett kitalálva, felesleges ugyanazt szoftveresen megvalósítani és az eszközre a szoftveres óra pontosítását bízni.

Én a harmadik megoldásodat tartom „nem elegánsnak”, de csak azért, mert a PIC képes meghatározott időnként lekérdezni az RTC-t, és ehhez nem kell az utobbi „megszakítás kérelmét” használni.
Én így oldottam meg: mivel más lényeges feladata a PIC-nek nincs, mint az idő lekérdezése és megjelenítése, ezért másodpercenként ötször timer megszakítással lefuttatom az RTC kiolvasását és az értékek kiírását.
Következő: »»   1 / 7
Bejelentkezés

Belépés

Hirdetés
Lapoda.hu     XDT.hu     HEStore.hu
Az oldalon sütiket használunk a helyes működéshez. Bővebb információt az adatvédelmi szabályzatban olvashatsz. Megértettem