DS1307 Gerçek Saat Uygulması Hakkında....

Başlatan davul42, 11 Nisan 2011, 15:15:40

davul42

Device 16F628
Declare LCD_DTPIN PORTB.4 ' Used for 4-line interface
Declare LCD_ENPIN PORTB.3
Declare LCD_RSPIN PORTB.2
Declare LCD_INTERFACE 4
Declare LCD_LINES 2
ALL_DIGITAL = TRUE

TRISA=0

Dim saat As Byte
Dim dakika As Byte
Dim saniye As Byte

Symbol Rtc_Data = PORTA.0
Symbol Rtc_Clock= PORTA.1

GİRİS:
saat = 15
dakika = 2
saniye =10
GoSub set
GoTo basla
GOTO GİRİS

set:
SHOut  Rtc_Data , Rtc_Clock ,lsbfirst, [$8e,0]
DelayMS 200
SHOut  Rtc_Data , Rtc_Clock ,lsbfirst, [$be,saat,dakika,saniye,0]
DelayMS 200
Return

basla:
GoSub gettime
Print At 1,1,DEC2 saat,":",DEC2 dakika,":",DEC2 saniye
GoTo basla


gettime:
SHOut  Rtc_Data , Rtc_Clock ,lsbfirst, [$bf]
SHIn   Rtc_Data , Rtc_Clock ,lsbpre, [saniye,dakika,saat]
Return


ARkadaşlar Rtc uygulmasında data ve clock okumada sanırım bir problem var..yaptığım örnekte ilk önce saniye,dakika ve saata bir değer vererek başlatıyorum daha sonra data ve clock darbelerini okuttuktan sonra yazdırıyorum ama ekranda değer hep sıfır gösteriyor clck ucunu takip ediyorum değişmiyor sürekli 0 görnüyor.acaba yanlışı nerde yapıyorum??

ibrsel

"SHout" ve "SHin" komutları ile değilde DS1307 ile "I2C" haberleşmesi ile haberleşmeyi denediniz mi?

Örnek Kod  ;

Alıntı Yap
DS_oku:
   I2Cin SDA, SCL,$D0,$00,[sn,dak,sa,day,gun,ay,yil]
Return
DS_yaz:         
   I2Cout SDA, SCL,$D0,$00,[sn,dak,sa,day,gun,ay,yil]   
Return 


davul42

#2
ACABA DS1307 PİNLERİNİ YANLISMI BAĞLADIM???
http://www.image-share.com/ijpg-598-9.html
Device 16F628
Declare LCD_DTPIN PORTB.4 ' Used for 4-line interface
Declare LCD_ENPIN PORTB.3
Declare LCD_RSPIN PORTB.2
Declare LCD_INTERFACE 4
Declare LCD_LINES 2
ALL_DIGITAL = TRUE

Dim saat As Byte
Dim dakika As Byte
Dim saniye As Byte

Symbol Rtc_Data = PORTA.1
Symbol Rtc_Clock= PORTA.0

giris:
GoSub settime
GoTo basla


basla:
GoSub gettime
Print At 1,1,DEC2 saat,":",DEC2 dakika,":",DEC2 saniye
GoTo basla

settime:
I2COUT  Rtc_Data , Rtc_Clock ,$D0,$00, [saniye,dakika,saat]
Return

gettime:
I2CIN   Rtc_Data , Rtc_Clock  ,$D0,$00, [saniye,dakika,saat]
Return

I2C KOMUTLARINI KULLANDIM FAKAT PROTEUSTAKİ DS1307 SAYICISINIDA SAATTE TARİHTE SIFIRLANIYOR VE KAFASINA GÖRE SAYIYOR,DURUYOR...

BİR ŞEYDAHA SORUCAMDA ",$D0,$00," ONALTILIK BU SAYILARI YAZMAMIZIN AMACI NEDİR???

ete

Bana kalırsa DS1307 nin data shetini aç biraz okumaya çalış.
BU RTC I2C mantığı ile haberleşir. Data ve CLK pinlerine 10K lık pullup direnci de bağlamalısın.

Data sheet okumanı tavsiye etmemdeki amaç RTC nin zaman ve tarih kayıt formatını görmen içindir.
Zira 8 bitlik hafızaları 4 bit + 4 Bit şeklinde kullanıyor. Örnek vermek gerekir ise;
Saniye=37 ise bu değer DS1307 den şu şekilde okunuyor. %0011 0111   soldaki bitler 37 rakamının onlar basamağını, sağdaki 4 bit ise birler basamağını temsil etmektedir.
Bunu desimal karşılığı  55 rakamı olup hex karşılığı ise otomatikman 37 olmaktadır.
Diğer bilgilerde buna benzer şekilde kayıt altında tutulur.
Elinde iki alternatif bulunmaktadır. Ya DS1307 den okuduğunu hex formatında LCD de göstereceksin yada formatı normal desimal sisteme çevireceksin. %00110111 sayısını desimal sisteme çevirmek için;
- SAYI=%(11110000 & Saniye)  komutunu verip sondaki 4 bitlik bilgiyi alırsın. Sonra bunu 4 bit sağa kaydırırsın. Yani SAYI=SAYI>>4
Böylece sayı değerin 3 olacaktır. Bunu 10 ile çarparak 3 olan sayıyı 30 yaparsın. Sonra,
SN=%00001111 & SANIYE komutu ile bu seferde en sağdaki 4 biti alırsın . Sonra SN=SN+SAYI diyerek 30 ile 7 rakamını toplamışolursun ve sonucu 37 olarak bulursun.

Ama unutma değeri 37 olan Saniye rakamını yeniden RTC ye bu şekilde yazamazsın. Bunu RTC nin formatına çevirmen gerekiyor.
Yani ;
ONLAR=SN rakamının onlar hanesi
BIRLER=SN rakamının bir ler hanesi.
ONLAR=ONLAR<<4
SAYI=ONLAR+BIRLER
şeklinde sayı yazılacak formata çevrilmiş olacaktır.

Ete

Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

davul42

#4

I2Cout Rtc_Data,Rtc_Clock,$D0,$00,[0]'                    'ds1307 nin giriş değerleri
DelayMS 100
I2Cout Rtc_Data,Rtc_Clock,$D0,$07,[$90]'
DelayMS 100

anamenu:
Print At 1,1 , DEC2 SAS,":",DEC2 DS,":",DEC2 SS
GoSub ds1307_oku
GoSub ds1307_yaz
GoTo anamenu

ds1307_yaz:
I2Cout Rtc_Data  ,  Rtc_Clock , $D0 , $00 , [ saniye, dakika, saat, gunadi, gun, ay, yil ]
saniye=So+Sb


DelayMS 200

Return


ds1307_oku:
I2Cin  Rtc_Data  ,  Rtc_Clock , $D0 , $00,  [ saniye, dakika, saat, gunadi, gun, ay, yil ]

So= %11110000 & saniye
So= So>>4                'SO:Saniyenin Onlar basamağı
So= So*10               

Sb= %00001111 & saniye   'SB:SANİYENİN BİRLER BASAMĞI
Sb= Sb<<4

SS= So+Sb                'SS:SANİYE SAYISI


         
Do= %11110000 & dakika
Do= Do>>4                'DO:Dakikanın Onlar basamağı
Do= do*10               

DAB= %00001111 & dakika  'DAB:DAKİKANIN BİRLER BASAMAĞI
DAB= DAB<<4

DS= Do+DAB               'DS:DAKİKA Sayısı


Sao= %11110000 & saat
Sao= Sao>>4              'SAO:saat Onlar basamağı
Sao= Sao*10               

Sab= %00001111 & saat    'SAB:SAATİN BİRLER BASAMAĞI
Sab= Sab<<4

SAS= sao+sab             'SAS:SAAT Sayısı
Return

HOCAM DATASHEETİNİ OKUMUŞTUM TABİ ANLADIĞIM KADARINI...

RTC NİN OKUMA KISMI TAMAM.AMA YAZMA KISMINDAKİ  DEDİĞİNİZ GİBİ BİRLER VE ONLAR BASAMAKLARININ FORMÜLLERİNİ ÇIKARTTIM AMA HER 1 SANİYEDE "SS=SS+16" DİYE GİDİYOR??

BU UYGULUMAYI FORUMDA BULDUM(https://www.picproje.org/index.php/topic,26050.msg175912.html#msg175912) ORDA BAŞKA BİR FORMÜL UYGULAMIŞ  VE DS1307 DE NE GÖRÜNÜYORSA AYNISINI LCDYE GEÇİRİYOR AMA BELLİ BİR ZAMANDAN SONRA DS1307 DE LCDEDE EKRAN KARIŞIYOR VE İLERLEMİYOR..ÇALIŞSADA FARKETMEZ BENİM SORUNUM ÖĞRENMEM AÇISINDAN ASLINDA I2C HABERLEŞME MANTIĞIDIR OKADAR ÇOK DEĞİŞİK UYGULMALAR NETTE YAPILMIŞKİ YAPTIĞIM PROJE ÇOK YAMALI OLDU VE ANLAMASI ZOR OLUYOR..I2C NİN YAZMA VE OKUMA MANTIĞINI RTC İLE  ANLATIRSANIZ EMİNİM BU İŞİ ÇÖZECEĞİM...

davul42

Sanırım bu konuda  çoğu kişi benim gibi takılmış :)

emrah

arkadaşlar şu satırdaki olayı açıklayabilirmisiniz? seri iletişimde proton komutlarını  tam bilmiyorum.

set:
SHOut  Rtc_Data , Rtc_Clock ,lsbfirst, [$8e,0]
DelayMS 200
SHOut  Rtc_Data , Rtc_Clock ,lsbfirst, [$be,saat,dakika,saniye,0]
DelayMS 200
Return



ilk gönderilen nedir ?     [$8e,0]

bunun özelligi nedir?      lsbfirst

Rtc_Data

Rtc_Clock

bu pinler nedir ? rx tx mi ?

OG

#7
SHOUT komutu ile,

-Clock pini çıkış ve L olur, (Neden L olur altta sukunet durumu konusu)
-Data pini çıkış yapılır,

data_gonderiyor:
-Sonra data pinine gönderilecek datanın ilgili biti verilir ( bu bit nedir az sonra)
-Clock pini 1 adet puls üretir (L idi , pals üretmesi demek L'den H'a ve sonra tekrar L'ye geçmesi demektir)

Gidecek datanın 1 biti gitti, diğer bitlerini de sıra ile "data_gonderiyor" altındaki şekli ile tamamlar.

------------------
Şimdi LSBFIRST meselesine bakalım

Giden data örneğin 8 bitlik bir sayı olsun ve datanın değeri 5 olsun,

Datanın sıra ile gidecek bitlerini görmek için ikili sistemde bakalım,
Decimal 5 demek = 00000101  demektir

Bit sıralaması
76543210
00000101

7. bit en güçlü bit (en değerlikli bit) dir, bunun adı MSB dir (Most Significant Bit)
Bu bit 0 ise toplama katacağı değer 0, 1 olursa toplama katacağı değer 128 dir, yani en güçlü, bizim sayı sistemimizdeki birler hanesi, onlar hanesi, yüzler hanesi dediğimiz gibi burada da 2 üzeri 7 hanesi.

0. bit en zayıf bit (en değerliksiz bit) dir, bunun adı LSB dir (Least Significant Bit)
Bu bit 0 ise toplama katacağı değer 0, 1 olursa toplama katacağı değer 1 dir, yani en zayıf,  da 2 üzeri 0 hanesi.

Peki göndermeye hangi taraftan başlayacağız? LSB tarafından mı, MSB tarafındanmı?

5 sayısı MSB tarafından gönderilirse sıra ile gidecek bitler, 0 0 0 0 0 1 0 1  dir,
5 sayısı LSB tarafından gönderilirse sıra ile gidecek bitler, 1 0 1 0 0 0 0 0  dir

Alıcı taraf hangi taraftan kabul edecek ise o taraftan başlamak gerekir. Bu sebeple önemli. Alıcı bitleri ters yerleştirirse alakasız bir değer ortaya çıkar.

İşte LSBFIRST demek, LSB tarafından başla demektir. Aksi halde MSBFIRST olmalı idi.

----
Kafanı şu an karıştırmasın ama bir de
LSBFIRST_H
MSBFIRST_H

komutu var, bu da Clock sinyalinin sukunet halinde iken H olduğu durumlar için, yani clock pini H da bekler, pals üretmek için LOW a iner tekrar H olur.
------------------------------

Toplamanın +16 hata yapması meselesi ise, sayılar hexadecimal olduğundan kaynaklanıyor, bunu dönüşümünü de ETE Hocanın dökümanlarında bulabilirsin.

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

Diğer mesele, Yukarıdaki linkte verdiğin kod problemsiz çalışıyor, hatan başka bir yerde dir.

-----------------
Alıntı YapRtc_Data

Rtc_Clock
bu pinler nedir ? rx tx mi ?

SHIN veya SHOUT komutuna göre giriş (rx) veya çıkış (tx) durumuna döner.
FORUMU İLGİLENDİREN KONULARA ÖM İLE CEVAP VERİLMEZ.

ete

Davul42,

Hemen belirteyim, I2C mantığını derken protokol mantığını soruyorsan onu öğrenmene hiç gerek yok. Bu konuda çok sayfalı bir açıklama var. Sen komutun kullnaılmasını öğren o sana yetecektir. Bu konuda bilmen gereken. I2C ile çalışan bütün elemanların bir chaz kodu vardır. Her elemanın ve özellikle I2C epromların birde Adres değerleri vardır. Komutta bu değerleri kullanmak zorundasın. Elamana yazarken I2CWrite ve elemandan okurken I2CRead komutları kullanılmaktadır.

PBP da kullandığım kodları aşağıda veriyorum. Önce okuma var adından okunan değerlerin çevrilme mantığını göreceksin.

ZAMANOKU:
        I2CRead SDA,SCL,$D0,$00,[SECOND,MINUTE,HOUR,HAFGUN,DAY,MONTH,YEAR]',TEMP]                  
        SN =((SECOND>>4) & $0F)*10+(SECOND & $0F)
        IF SN=ESKISN THEN RETURN
        DAK=((MINUTE>>4) & $0F)*10+(MINUTE & $0F)
        SAAT=((HOUR>>4) & $03)*10+(HOUR & $0F) 
        GUN=((DAY>>4) & $03)*10+(DAY & $0F)
        AY= ((MONTH>>4) & $01)*10+(MONTH & $0F)
        YIL= ((YEAR>>4) & $0F)*10+(YEAR & $0F)  
        RETURN


Şimdi de yazma mantığına bir bakalım.
ZAMANYAZ: 
        HOUR=(SAAT DIG 1)<<4+SAAT DIG 0
        MINUTE=(DAK DIG 1)<<4+DAK DIG 0
        SECOND =(SN DIG 1)<<4+SN DIG 0
        DAY=(GUN DIG 1)<<4+gun DIG 0
        MONTH = (AY DIG 1)<<4 + AY DIG 0
        YEAR =(YIL DIG 1)<<4+YIL DIG 0       
        I2CWrite SDA,SCL,$D0,$00,[SECOND,MINUTE,HOUR,HAFGUN,DAY,MONTH,YEAR,0]
        RETURN


Ete
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

emrah

OG hocam bilgiler için teşekkür ederim. peki bu komutlar ne için kullanılmış.? yani seri bilgi göndermekle clock  pals vererek ne yapılmış?

ben rf den bilgi gönderecegim fakat gönderecegim bilgiye nasıl şifre eklemeliyim ve seknron data göndermeliyim?
HSEROUT [veri]  komutu ile veri içindeki bilgi seri olarak gitmektedir. bunun hangi pinden cıkacagını nasıl ayarlamalıyım?
pic basıcte bunu yapıyorum ama protonda daha farklı sanırım. bunlarıda acıklayabilirseniz çok iyi olacak....

davul42

Şimdi ete hocam ;

I2Cin Sda,Scl,$D0,$00,[saniye,saat,dakika,gunadi,guntarihi,aytarihi,yıl,0]
$D0,$00                                                                  RTC nin kontrol registeri okumada D0(%11010000
                                                                               yazmada  D1(%11010001) midir?
[saniye,dakika,saat,gunadi,guntarihi,aytarihi,yıl,0]  RTC lerde burada bilgi okuma sıralaması hep sabitmi?
                                                                                burdaki "0" veya temp değişkenin
                                                                                amacı nedir?

birde okuma sırasında RTC den okuyup Lcd ye aktarıyoruz.Bın den Bcd ye çeviriyoruz...bu tamam...
ama yazma işleminin mantığını anlayamadım yani çevirdiğimiz Bcd leri Bın e çevirip tekrar RTC ye göndermemiz???benim aklıma gelen saatin ayarını yaparken Rtc gönderdiğimiz biilgiler için bu işlemi yapıyoruz????

devrim35

#11
Device = 16F876

ALL_DIGITAL = True

LCD_DTPIN = PORTD.4
LCD_RSPIN = PORTD.2
LCD_ENPIN = PORTD.3
LCD_INTERFACE = 4
LCD_LINES = 2
LCD_TYPE = 0

SDA_PIN = PORTC.4 'DS1307 SDA pin
SCL_PIN = PORTC.3 'DS1307 SCL pin

Dim Temp1   As Byte
Dim Temp2   As Byte
Dim TempVal As Byte
Dim Saniye  As Byte
Dim Dakika  As Byte
Dim Saat    As Byte
Dim GunAdi  As Byte
Dim Gun     As Byte
Dim Ay      As Byte
Dim Yil     As Byte
Dim Ctrl    As Byte
Dim Secs_last As Byte


DelayMS 50
Cls

Main:

BStart
BusIn 11010001 , 0 , [Saniye, Dakika, Saat , GunAdi, Gun , Ay, Yil, Ctrl]'oku
BStop


TempVal=Saniye
GoSub BCD_TO_BIN
Saniye=TempVal

TempVal=Dakika
GoSub BCD_TO_BIN
Dakika=TempVal

TempVal=Saat
GoSub BCD_TO_BIN
Saat=TempVal

TempVal=GunAdi
GoSub BCD_TO_BIN
GunAdi=TempVal

TempVal=Gun
GoSub BCD_TO_BIN
Gun=TempVal

TempVal=Ay
GoSub BCD_TO_BIN
Ay=TempVal

TempVal=Yil
GoSub BCD_TO_BIN
Yil=TempVal

Print At 1,1,DEC2 Saat,  ":", DEC2 Dakika, ":", DEC2 Saniye
Print At 2,1,DEC2 Gun ,  "/", DEC2 Ay,     "/", DEC2 Yil
GoSub gunler
GoTo Main

gunler:
If GunAdi=1 Then Print At 1,11,"PAZAR"
If GunAdi=2 Then Print At 1,11,"PTESI"
If GunAdi=3 Then Print At 1,11,"SALI "
If GunAdi=4 Then Print At 1,11,"CRSMB"
If GunAdi=5 Then Print At 1,11,"PRSMB"
If GunAdi=6 Then Print At 1,11,"CUMA "
If GunAdi=7 Then Print At 1,11,"CTESI" 
Return

BCD_TO_BIN:                                   
     Temp1 = $0F & TempVal                   
     Temp1 = Dig Temp1, 0                     
     Temp2 = TempVal >> 4                     
     Temp2 = Dig Temp2, 0                     
     TempVal = Temp2 * 10 + Temp1             
     Return

Bende böyle bir RTC devresini 16f84a ya programladım.Fakat ben 16f876 yı aracı olarak kullanmak istiyorum yani RTC den clk ve data 16F876 ya girecek oradan 16F877 ye ve 16f877 üzerinden den LCD den görünücektir..Bunun için çok yol var sanırım ..ama ben yine SCL ve SDA yani I2c haberleşmesini kullanmak istiyorum onun için zannedersem bu komutları;

BusOut  kontrol     , adres , [Değişken1,Değişken2.....]    '16f876 dan çıkış

BusIn  kontrol     , adres , [Değişken1,Değişken2.....]       '16f877 ye giriş   

kullanmam gerekiyor..kontrol ve adresler konusunda yardımcı olurmusunuz????