ds1302-pil sorunu

Başlatan halinzlimurat, 15 Aralık 2007, 20:37:42

halinzlimurat

DS1302- DS18B20 - 4 ADET BÜYÜK 7SEG DİSPLAYVE PIC 16F877 İLE DUVAR SAAT YAPTIM. FAKAT PROBLEMİM ŞU DEVREYİ KAPATINCA, SAATİ SAKLAMIYOR. YANİ DS1302 YE PİL TAKTIM PİLİ ŞARJ ETMESİ İÇİN DS1302 Yİ UYGUN ŞEKİLDE KURDUM FAKAT. DEVREDEN ELEKTRİK KESİP TEKRAR VERİNCE SAAT SAKLANMIYOR , SIFIRLANIYOR. ACABA DS1302 ŞEMAMDA MI Bİ ARIZA VAR. ELİNDE DS1302 NİN PİL İLE KULLANILMASINA DAİR ŞEMA VE PROGRAM OLAN VARSA YOLLAYABİLİR Mİ?
@<-.HKM.->@

otm

merhaba
ben aşağıdaki şekilde kullanmıştım.herhangi bir sıkıntı yaşamadım

halinzlimurat

ben de ayynen o şekilde kullanıyorum. saat normal çalışıyor. fekat elektrik gidip gelince saat kaldığı yerden değil sıfırdan başlıyor..
neden acep çözemedim yau :(
programım da şöyle...


.......
...

' Ds1302 Giriş uçları
RST     var     PORTc.4
IO      var     PORTd.3
SCLK    var     PORTd.2

Low RST                         ' RTC yi resetle
Low SCLK

rtcyil var     byte
rtcay  var     byte
rtcgun var    byte
rtcdate var     byte
rtcsaat   var     byte
rtcdakika  var     byte
rtcsaniye  var     byte
rtccontrol var  byte
....
...

basla:

a_kadir:

gosub zamanioku
goto basla
zamaniayarla:
   RST = 1         ' RTC Yazma modunda
       Shiftout IO, SCLK, LSBFIRST,[$8e, 0]  ' burst modu
   RST = 0         ' RTC yi resetle
   RST = 1         ' TRC Yazma modunda       ' 8 RTC register değerini RTC ye yaz
       Shiftout IO, SCLK, LSBFIRST, [$be, rtcsaniye, rtcdakika, rtcsaat, rtcgun, rtcay, rtcdate, rtcyil, 0]
   RST = 0         ' RTC yi resetle
Return

zamanioku:
 
 
   RST = 1         ' RTC yazma modunda
       Shiftout IO, SCLK, LSBFIRST, [$bf]      ' burst modu    
       Shiftin IO, SCLK, LSBPRE, [rtcsaniye, rtcdakika, rtcsaat, rtcgun, rtcay, rtcdate, rtcyil, rtccontrol]
   RST = 0         ' RTC yi resetle                      ' 8 RTC register değerini oku, değişkenlere yaz
    x=rtcsaniye : gosub hesap2:saniye=x
    x=rtcdakika : gosub hesap2:dakika=x
    x=rtcsaat : gosub hesap2:saat=x
    x=rtcgun : gosub hesap2:gun=x
    x=rtcay : gosub hesap2:ay=x
    x=rtcyil : gosub hesap2:yil=x
       
   
Return
@<-.HKM.->@

aslan_korhan

Pilin bitik olmasın...
Dünyada 10 çeşit insan vardır. Binary bilen ve bilmeyenler.

halinzlimurat

:) yok be abicim okadar da değil...
ölçtüm 3.7 V. hatta ilk taktığımda 2 v. idi fekat ds1302 de şarj etmiş 3.7 V. şu anda. hatta ve dahi pil terine güç kaynağı kullandım pilden mi diye aynı değişen bişi yok neden dir acep yau... ve hatta maxim-ic den aldığı beleş :) ds1302 lerden bile değiştirdim 3-5 tane aynı...
resim de eklemek isterdim ama olmuyor şimdi ama emin olun devre doğru...
programda mı bi eksik var acep???
@<-.HKM.->@

buiba

programda rtc yi resetle diye bir komut var,dolayisiyla siz her enerji verdiginizde islemciniz,satti sifirliyor olmasin?

halinzlimurat

inanmıcaksın ama onu da kaldırıp denedim yine yanı. ben de düşündüm onu. aynı aynı aynı... :(
@<-.HKM.->@

arslan74

Merhaba,

Size DS1302 için kendi kullandığım C kodunu veriyorum.

#define  SECOND		0x81
#define  MINUTE		0x83
#define  HOUR		0X85
#define  DATE		0X87
#define  MONTH		0X89
#define  DAY		0X8B
#define  YEAR		0X8D
#define  CONTROL	0X8F
#define  CHARGER	0X91



#define TRIS_IO TRISE1


static	bit	SCLK  	@ (unsigned)&PORTE*8+0;	// use this bit to 
static	bit	IO		@ (unsigned)&PORTE*8+1;	// use this bit to 
static	bit	RST  	@ (unsigned)&PORTE*8+2;	// use this bit to 



void init_DS1302( void ){
	
	unsigned char sec_val;
	
	RST = 0;
	DelayUs(2);
	SCLK = 0;
	DelayUs(2);
	
	write_DS1302( CONTROL, 0 );
	
	write_DS1302( CHARGER, 0b10100110 );
	
	sec_val = read_DS1302(SECOND);
	
	if ( sec_val & 0b10000000 )	// Eğer saat kristali kapalı ise ac.
			write_DS1302( SECOND, 0b00000000 );
} //


Bu mantığa göre yeniden yaz.


Selamlar

halinzlimurat

if ( sec_val & 0b10000000 )   // Eğer saat kristali kapalı ise ac.
        write_DS1302( SECOND, 0b00000000 );


şu satırın türkçesini yollarsan bişiler yapabilirim....
@<-.HKM.->@

arslan74

Alıntı yapılan: "halinzlimurat"if ( sec_val & 0b10000000 )   // Eğer saat kristali kapalı ise ac.
        write_DS1302( SECOND, 0b00000000 );


şu satırın türkçesini yollarsan bişiler yapabilirim....

Merhaba,

Eğer saat kirstali kapali ise saat hiç çalışmaz. Yanı okumada sürekli aynı sayıyı verir.

Bence sen aşağıdaki kodlara yoğunlaş. sorun orada olablir. eğer sarj kısmı kapalı ise o zaman devrenin pille bağlantısı yok olabilir.


 write_DS1302( CONTROL, 0 ); 
    
  write_DS1302( CHARGER, 0b10100110 ); 

  


Selamlar

ete

DS1302 de saniye nin 7. saat osilatörünün durma yada çalışmasını belirler. Şayet bu bit 1 ise saat osilatörü durur dolayısıyla saat durur. Bu bitin ilk çalıştırmada hangi konumda olacağı kesin değildir. Gerekirse programın başına bu biti sııfr yapacak bir komut koyulmalıdır.
Ancak  arkadaşımızın problemi bu değil bence.
Biraz sesli düşünelim. Arkadaş saati çalıştırıyor (belkide bir ayar yapıyor) sonra karta giden gerilimi kesiyor. Ancak DS1302 nin 8 nolu bacağında pil yada ayrı bir devreden gelen 3 V var diyor. Bu durumda saat 8 nolu pininden aldığı gerilimle çalışmasına devam etmesi ve zamanı sayması gerekir.
Ancak arkadaş saatin zamanı unuttuğunu belirtmiş. Bu durumda sorunlar neler olabilir bir inceleyelim;
1. Arkadaş programı vermiş ama programda başlangıçta saat ayarı yapıldığını ve bununda DS1302 ya kayıt edildiğini gösteren bir satır göremedim. Bu durumda saat'e mevcut zaman değerleri yazılmaz ise saat doğru zamanı göstermeyecektir. Bunu programda göremiyoruz. Anlaşılan programın tamamını vermemiş. Ama verdiği de hiç bir işimize yaramıyor. Bir mantık kovalamacası yapılacaksa programın tamamı üzerinden yapmamız gerekir idi. Zamanı yazmıyor ise doğru zamanı görmüyor olacak . Ancak belkide sisteme gerilim verip saniye değerlerini biraz çalıştırıyor sonra gerilmi kesip aynı yerden başladımı diye bakıyorda olabilir. Bu konuya açıklık getirmesini bekliyoruz.

2. Diyelimki  saatini başlangıçta ayarladı. Bu ayar esnasında zaten saniye 7. biti sıfırlanacak ve saat osilatörü çalışmaya başlayacaktır.
Bu durumda gerilim kesilince saatin zamanı unutması ancak  ancak pilin yanlış bağlanması yada pilin boş olması ile mümkündür.
Lityum pillerin yalnızca voltajlarının ölçülmesi onun dolu olduğunu göstermiyor. Önemli olan gerekli akımı sağlayıp sağlamadıkları kontrol edilmelidir. Bunun için bir led pil ile yakılmalı. Şayet yanıyor ise pil sağlam demektir. Ben çok lityum pil gördüm. Voltaj 2,9V dolayında ama pil bitik vaziyette idi. Genelde hesap makineleri ve data banklarda biten piller zaman faktörü nedeni ile bitiyorlar ve voltajları bir iki mili volt düşmesine rağmen amperleri sıfırlanıyor. Buna dikkat edelim.
Bu sorunun karşılığını arkadaşımız ayrı bir güç kaynağı bağladığını belirterek aşmış oluyor aslında. Peki hem güç kaynağı bağlı hem zamanın unutulması nasıl olabilir.? Bu fiziksel olarak mümkün değil. Bunun karşılığını bulmak için programın tamamına bakmak ayrıca yaptığı kartı da bir incelemek gerekir. Yoksa bu anlatılanlar mantığa uygun gelmiyor. Yada kestirmeden DS1302 bozuk demek gerekir ki onuda bir başkası ile değiştirdiğini söylüyor. Demekki ya programda bir hata var saatin doğru yazılmaması gibi yada kartta bir başka fiziksel bağlantı hatası var.
Bazı şemalarda DS1302 nin pil bacağı ile voltaj besleme bacağı birleştirilerek çiziliyor (sistemde pil kullanılmayacak ise). Bu yanlış. Besleme ayrı bacaklardan yapılması gerekir. DS1302 hangi bacaktaki voltaj daha yüksek ise oradan besleme yapmaktadır. Bu nedenle pil voltajı 3V seviyesinde olmalı. Normal besleme ise 5V seviyesinde olmalıdır.

Zaman bilgisi DS1302 ye belirli bir format düzeninde yazılması gerekiyor. BUna ait satır programda göremedim. Ancak Gosub Hesap2 şeklinde bir satırda bu işlemi yatığını düşünüyorum. Ancak satır detayı olmadığı için bu konuda da bir yorum yapamıyorum. Acdaba doğrumu yapılıyor bu hesap.

Sonucu burada öğrenebilirsek merakımız giderilmiş olacaktır. Hatırlatırım.
Bazı arkadaşlar hem soru sorup hemde bir müddet sonra " sağolun arkadaşlar sorunu hallettim" deyip konuyu kapatıyorlar. Halbuki pek çok insan meraklanıyor ve üstelik aynı sorun bir başkasının başınada gelebilir. O nedenle sorunun hallediliş şekli burada mutlaka belirtilmelidir. Bu kadar yazışmamızın amacı zaten paylaşmak. Devreleri , programları paylaştığımız gibi sorunları da paylaşmalıyız ki başkaları aynı sorunları yaşamasınlar.
Sorunsuz günler temenni ediyorum.
Ete
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

F493

şöyle birşey söylesem daha önce yaşamıştım.

programın başında ds1302'ye bir başlangıç degeri verilir ör//10 12 2007 00 00 00 bunu verdiniz diyelim.

sonra bunu 1 kere çalıştırıp sonra koddan bunu silin yoksa program enerjilendiginde hep bunu rtc'ye tekrar yazacagı için
işlemci her açılıp kapandıgında aynı yerden başlayacaktır

halinzlimurat

arkadaşlar teşekkkür ederim ilginiz ve alakanız için, özellikle ete' ye.
programın tamamını veriyorum... ds1302 ye bağlantım otm ' nin verdiği bağlantı gibidir. hiçbir fark yoktur. pilin eksi ucu devrenin gnd sine bağlıdır.
işten anlayan bir arkadaşıma sebebini sordum o bana saati ayarladığımda saniye bilgisini girmediğimi ondan dolayı olduğunu söyledi ama ayar yaptıktan sonra çalışıyo meret.. yani özetle devrede bi problem olduğunu sanmıyorum. pilin eski olma ihtimali de yok zira dediğim gibi ayrı bir güç kaynağı kullandım o da aynı. yani iki güç kaynağınında eksilerini birleştirdim de yaptım merak etmeyin... neyse kodlar aşağıda... tekrar teşekkür ediyorum. baskı devreyi de yollardım ama nasıl yapılıypr bilmiyorum....

söz konusu program...

include "modedefs.bas"
                   adcon1=7
seg1 var byte
seg2 var byte
seg3 var byte
seg4 var byte

saniye var byte
dakika var byte
saat var byte
ay var byte
gun var byte
yil var byte

x var byte
y var byte
z var byte
sayac var byte
sayac=0
 
 
alsaat  var byte
aldakika var byte

asaatd var byte[10]
adakikad var byte[10]
                   
trisb=0 : trise=%111  : trisc=%11111011  : trisd= %11111111
portd=0 : trisa=255

' Ds1302 Giriş uçları
RST     var     PORTc.4
IO      var     PORTd.3
SCLK    var     PORTd.2

Low RST                         ' RTC yi resetle
Low SCLK

'Ds18b20 Ayarları
Busy        VAR BIT         ' Busy Status-Bit
HAM         VAR	WORD        ' Sensör HAM okuma değeri
ISI         VAR WORD        ' Hesaplanmış ISI değeri
Float       VAR WORD        ' Holds remainder for + temp C display
XY           VAR WORD       
ISARET_BITI   VAR HAM.Bit11   '   +/- sıcaklık İşaret biti,  1 = olursa eksi sıcaklık
EKSI_ISI   CON 1           ' Sıfır altında isaret biti=1  oluyor kontrol için
ISARET     VAR BYTE        '  ISI değeri için  +/-  işaret
TEMP        VAR BYTE       ' Div32 bit hesap için geçici değişken
SYMBOL COMM_PIN=PORTC.0    ' One-wire Data-Pin "DQ" PortB.4 da
                      

' Tarih  ve saat  değişkenkeri
sayar var byte
dayar var byte
rtcyil var     byte
rtcay  var     byte
rtcgun var    byte
rtcdate var     byte
rtcsaat   var     byte
rtcdakika  var     byte
rtcsaniye  var     byte
rtccontrol var  byte

sa1 var byte
sa2 var byte
k var byte
'ayar  değişkenleri


'------------------------------
SYMBOL CLK=PORTb.7
SYMBOL DTA=PORTb.6
SYMBOL AKTAR=PORTb.5




'----------------------------------


'-----------------------------------



' **************************************** ds1302 pil şarj
RST = 1 ' Ready for transfer 
Shiftout IO, SCLK, LSBFIRST, [$8E, $0] ' Enable write, control = 0 
RST = 0 ' Reset RTC 
RST = 1 ' Ready for transfer 
Shiftout IO, SCLK, LSBFIRST, [$90,$A5] 'Write trickle = %10100101 
RST = 0 
' **************************************** ds1302 pil şarj
             pause 100

murat:

 gosub zamanioku
 
if (saat=alsaat) and (dakika=aldakika) and (saniye<11) then
portc.2=1
else
portc.2=0
endif





  if portc.5=1 then
  pause 250
  goto ayar
  endif



if (dakika//2=1) and (saniye>=0) and (saniye=<10) then'ISIYI GÖSTER
portb.0=0
portb.1=0
gosub sensoroku
gosub segment
endif


if (dakika//2=0) and (saniye>=0) and (saniye=<5) then'GUN/AY GÖSTER
portb.0=0
portb.1=1
seg1=gun/10
seg2=gun//10
seg3=ay/10
seg4=ay//10
gosub segment
endif


if (dakika//2=0) and (saniye>=6) and (saniye=<10) then' YIL GÖSTER
portb.0=0
portb.1=0
seg1=2
seg2=0
seg3=yil/10
seg4=yil//10
gosub segment
endif


if saniye>10 then  'SAAT GÖSTER

if saniye//2 = 0 then
portb.0=0
portb.1=0
else
portb.0=1
portb.1=1
endif

seg1=saat/10
seg2=saat//10
seg3=dakika/10
seg4=dakika//10
gosub segment
endif

Goto murat   



zamaniayarla:
    RST = 1         ' RTC Yazma modunda
        Shiftout IO, SCLK, LSBFIRST,[$8e, 0]  ' burst modu
    RST = 0         ' RTC yi resetle
    RST = 1         ' TRC Yazma modunda       ' 8 RTC register değerini RTC ye yaz
        Shiftout IO, SCLK, LSBFIRST, [$be, rtcsaniye, rtcdakika, rtcsaat, rtcgun, rtcay, rtcdate, rtcyil, 0]
    RST = 0         ' RTC yi resetle
Return

zamanioku:
   
   
    RST = 1         ' RTC yazma modunda
        Shiftout IO, SCLK, LSBFIRST, [$bf]      ' burst modu    
        Shiftin IO, SCLK, LSBPRE, [rtcsaniye, rtcdakika, rtcsaat, rtcgun, rtcay, rtcdate, rtcyil, rtccontrol]
    RST = 0         ' RTC yi resetle                      ' 8 RTC register değerini oku, değişkenlere yaz
     x=rtcsaniye : gosub hesap2:saniye=x
     x=rtcdakika : gosub hesap2:dakika=x
     x=rtcsaat : gosub hesap2:saat=x
     x=rtcgun : gosub hesap2:gun=x
     x=rtcay : gosub hesap2:ay=x
     x=rtcyil : gosub hesap2:yil=x
        
    
Return

'*********************   decimalden hex e çevir
hesap1:
if x>9 then
y=x//10
z=(x-y)/10
x=(16*z)+y
endif
return
'********************* hex' den decimale çevir
hesap2:
if x>9 then
y=x//16
z=(x-y)/16
x=(z*10)+y
endif
return


'SHIFTOUT DTA,CLK,1,[aa]
 '           0  1  2 3   4  5    6  7  8  9   C  o   -  boş
'lookup aa,[63,6,91,79,102,109,124,7,127,111,57,99,128,0],aa

segment:

lookup seg4,[63,6,91,79,102,109,124,7,127,111,57,99,128,0],seg4
SHIFTOUT DTA,CLK,1,[seg4]

lookup seg3,[63,6,91,79,102,109,124,7,127,111,57,99,128,0],seg3
SHIFTOUT DTA,CLK,1,[seg3]

lookup seg2,[63,6,91,79,102,109,124,7,127,111,57,99,128,0],seg2
SHIFTOUT DTA,CLK,1,[seg2]

lookup seg1,[63,6,91,79,102,109,124,7,127,111,57,99,128,0],seg1
SHIFTOUT DTA,CLK,1,[seg1]

HIGH AKTAR: PAUSEus 1: LOW AKTAR

return

SENSOROKU: 
            OWOUT   Comm_Pin, 1, [$CC, $44]' ISI değerini oku
Bekle:
           OWIN    Comm_Pin, 4, [Busy]    ' Busy değerini oku
           IF      Busy = 0 THEN Bekle    ' hala meşgulmü? , evet ise goto Bekle..!
           OWOUT   Comm_Pin, 1, [$CC, $BE]' scratchpad memory oku
           OWIN    Comm_Pin, 2, [HAM.Lowbyte, HAM.Highbyte]' İki byte oku ve okumayı bitir.
           
               
 Hesapla:                 ' Ham değerden Santigrat derece hesabı
    ISARET  = "+"
    IF ISARET_BITI = EKSI_ISI THEN
       ISARET   = "-"  
       temp=($ffff-ham+1)*625
       ISI  = DIV32 10
       GOTO GEC   
    endif
    TEMP = 625 * HAM        ' 
    ISI = DIV32 10          ' Div32 hassas derece hesabı için 32 bit bölme yapıyoruz.
GEC:
    FLOAT = (ISI //1000)/100
    ISI=ISI/1000 
    
  
  if isaret_biti="-" then
  seg1=12
  seg2=isi/10
  seg3=isi//10
  seg4=11
  else
  seg1=isi/10
  seg2=isi//10
  seg3=11
  seg4=10  
  endif
return


ayar:
a1:' saat/dakika ayarı

portb.0=1 : portb.1=1
if portc.6=1 then
pause 250
saat=saat+1
if saat>23 then saat=0
endif


if portc.7=1 then
pause 250
dakika=dakika+1
if dakika>59 then dakika=0
endif

seg1=saat/10
seg2=saat//10
seg3=dakika/10
seg4=dakika//10
gosub segment


if portc.5=1 then
pause 250
x=saat : gosub hesap1 : rtcsaat=x
x=dakika : gosub hesap1 : rtcdakika=x
gosub zamaniayarla

  goto a2
  endif


goto a1

a2:  ' gun/ay ayarı

 portb.0=0 : portb.1=1

if portc.6=1 then
pause 250
gun=gun+1
if gun>31 then gun=0
endif


if portc.7=1 then
pause 250
ay=ay+1
if ay>12 then ay=0
endif

seg1=gun/10
seg2=gun//10
seg3=ay/10
seg4=ay//10
gosub segment


if portc.5=1 then
pause 250
x=ay : gosub hesap1 : rtcay=x
x=gun : gosub hesap1 : rtcgun=x
gosub zamaniayarla
  goto a3
  endif
goto a2

a3:    ' yil ayarı
    portb.0=0 : portb.1=0

if portc.6=1 then
pause 250
yil=yil+1
if yil>99 then yil=0
endif


if portc.7=1 then
pause 250
yil=yil-1
if yil=255 then yil=0
endif



seg1=2
seg2=0
seg3=yil/10
seg4=yil//10
gosub segment


if portc.5=1 then
pause 250
x=yil : gosub hesap1 : rtcyil=x
gosub zamaniayarla
sayac=1    
for k=1 to 10
read 9+k,asaatd[k-1]:pause 10
read 19+k,adakikad[k-1]: pause 10
next k
  
  goto alarmayar
  endif

goto a3
alarmayar:
         portb.0=1:portb.1=1 
alsaat=asaatd[sayac-1]
aldakika=adakikad[sayac-1]

seg1=sayac/10:seg2=sayac//10:seg3=13:seg4=13
gosub segment
pause 5000

al1:

if portc.6=1 then
pause 250
alsaat=alsaat+1
if alsaat>23 then alsaat=0
endif


if portc.7=1 then
pause 250
aldakika=aldakika+1
if aldakika>59 then aldakika=0
endif

seg1=alsaat/10
seg2=alsaat//10
seg3=aldakika/10
seg4=aldakika//10
gosub segment


if portc.5=1 then
pause 250
write 9+sayac,alsaat :pause 10
write 19+sayac,aldakika :pause 10
sayac=sayac+1
if sayac>10 then goto murat 
goto alarmayar
endif
      
    goto al1

goto alarmayar
goto ayar



end
@<-.HKM.->@

halinzlimurat

Yine her zaman ki gibi kendi sorunumu kendim hallettim :)
Sorun şu saati ayarlarken yani rtcsaniye ve rtcdate değerlerine değer vermememmiş. rtcdate değişkenini rtcgun değerine eşitleyip ve rtcsaniye değerine sıfır değeri verince sorun halloldu...

Herkese İyi Çalışmalar...
@<-.HKM.->@

recebcolak

verdigin programda displeyleri tarama yöntemi ilemi yaptın kardeş.devre şemasını ekleye bilirmisin birde ds1302 nin herhangi bir baçagına 10 klık direnç baglanaçakmı bazı devrelrde oluyorda.
ben herkesi sevdim bilmiyorum sevildimmi?