DS1307

Rasprava o PIC mikrokontrolerima, PIC projekti i drugo vezano za PIC-eve...

Moderators: pedja089, stojke369, [eDo], trax

Post Reply
User avatar
78L05
Pravo sam se raspisao :)
Pravo sam se raspisao :)
Posts: 1402
Joined: 28-05-2009, 13:22
Location: Hrvatska

DS1307

Post by 78L05 »

Uspio sam napraviti komunikaciju između PIC-a i DS1307 pomoću ove linije:

Code: Select all

DB0 VAR BYTE [8]
I2CREAD SDA,SCL,$D1,$00,[STR DB0\8]
Vrijeme zapisujem na ovaj način:

Code: Select all

lcdout $FE, $C0,"Vrijeme:",hex2 DB0[2],":",hex2 DB0[1] 
Pitanje je, kako primjerice podešavati pročitane sate, odnosno kako sate koristiti kao običan DEC broj u dekadskom sustavu.

Hvala unaprijed
Ne vjeruj u čuda - računaj na njih!
djanib
Posts: 16
Joined: 14-12-2011, 21:41

Re: DS1307

Post by djanib »

Nema mi nista gore nego kad neko ne napise koji PIC koristi, niti u cemu zeli primjer.
Hajde nema veze. Evo ovdje MikroPascal primjer sa procedurama i za read i za write DS1307.
Kontroler PIC: 16F877, 16F877A, 18F4520 ....

Port C: scl,sda -> DS1307
Port D: LCD 4X20
Port B: 8xLED Binar counting sec
ext osc: 8MHz

To je sva pamet....

MikroPascal code:

Code: Select all

program RTC;

var Tsec,GSec,Gmin,Ghr,Gday,Gdt,Gmn,Gye,add0 : byte;
    text : string[3];
    txday: string[10];

Procedure Init;
Begin
    TrisD:=0;                    // LCD 4x20 PortD output
    TrisB:=0;                    // LED row, show secoonds PortB output
    LCD_Init(PortD);
    Lcd_Cmd(LCD_CURSOR_OFF);
    Lcd_Cmd(LCD_Clear);
    Lcd_Out(1,1,'RTC DS1307-Time/Date');
    Lcd_Out(2,1,'Time:');
    Lcd_Out(3,1,'Date:');
    Lcd_Out(4,1,'Day:');
    add0:=0;
    I2C_init(100000);
End;

Procedure Show_time;
begin
     if GSec<10 then add0:=1;
     ByteToStr(Gsec,text);
     Lcd_Out(2,12,text);
     if add0=1 then lcd_chr(2,13,'0');
     add0:=0;

     if Gmin<10 then add0:=1;
     ByteToStr(Gmin,text);
     Lcd_Out(2,9,text);
     Lcd_chr(2,12,':');
     if add0=1 then lcd_chr(2,10,'0');
     add0:=0;

     if Ghr<10 then add0:=1;
     ByteToStr(Ghr,text);
     Lcd_Out(2,6,text);
     Lcd_chr(2,9,':');
     if add0=1 then lcd_chr(2,7,'0');
     add0:=0;
end;

Procedure Show_date;
begin
     if Gye<10 then add0:=1;
     ByteToStr(Gye,text);
     Lcd_Out(3,14,text);
     Lcd_Out(3,13,'20');
     Lcd_chr(3,17,'.');
     if add0=1 then lcd_chr(3,15,'0');
     add0:=0;

     if Gmn<10 then add0:=1;
     ByteToStr(Gmn,text);
     Lcd_Out(3,9,text);
     Lcd_chr(3,12,'.');
     if add0=1 then lcd_chr(3,10,'0');
     add0:=0;

     if Gdt<10 then add0:=1;
     ByteToStr(Gdt,text);
     Lcd_Out(3,6,text);
     Lcd_chr(3,9,'.');
     if add0=1 then lcd_chr(3,7,'0');
     add0:=0;
end;

Procedure Show_day;
begin
     If Gday=1 then txday:='Ponedeljak';
     If Gday=2 then txday:='Utorak    ';
     If Gday=3 then txday:='Srijeda   ';
     If Gday=4 then txday:='Cetvrtak  ';
     If Gday=5 then txday:='Petak     ';
     If Gday=6 then txday:='Subota    ';
     If Gday=7 then txday:='Nedelja   ';
     Lcd_Out(4,7,txday);
end;

Procedure Read_time;
begin
   I2C_Start;
   I2C_Wr($D0);              // Set I2c Unit to write mode
   I2C_Wr($00);              // Set pointer on I2c Unit
   I2C_Repeated_Start;
   I2C_Wr($D1);              // Set I2c Unit to Read mode
   Gsec :=I2C_Rd(1);         // Read byte
   Gmin :=I2C_Rd(1);         // Read next byte
   Ghr  :=I2C_Rd(1);         // Read next byte
   Gday :=I2C_Rd(1);         // Read next byte
   Gdt  :=I2C_Rd(1);         // Read next byte
   Gmn  :=I2C_Rd(1);         // Read next byte
   Gye  :=I2C_Rd(0);         // Read next byte
   I2C_Stop;
   PortB:=Gsec;
   GSec := Bcd2Dec(Gsec);
   Gmin := Bcd2Dec(Gmin);
   Ghr  := Bcd2Dec(Ghr);
   Gdt  := Bcd2Dec(Gdt);
   Gmn  := Bcd2Dec(Gmn);
   Gye  := Bcd2Dec(Gye);
   Show_time;
   Show_date;
   Show_day;
end;

Procedure Write_time;
begin
    I2C_start;
    I2C_wr($D0);         // write to RTC
    I2C_wr(0);           // set pointer to 00
    I2C_wr(128);         // toggle crystal 32.768 on/off bit
    I2C_stop;
    I2C_start;
    I2C_wr($D0);         // write to RTC
    I2C_wr($01);         // 
    I2C_wr($18);         // set min   0..59
    I2C_wr($23);         // set hour  0..23
    I2C_wr($03);         // set day   1..7
    I2C_wr($14);         // set date  1..31
    I2C_wr($12);         // set month 1..12
    I2C_wr($11);         // set year  1..99
    I2C_Stop();          // Stop I2c BUS
    I2C_start;
    I2C_wr($D0);         // write to RTC
    I2C_wr(0);           // set pointer to 00
    I2C_wr(0);           // toggle crystal 32.768 on/off bit
    I2C_Stop();          // Stop I2c BUS
end;

begin
  Init;
  Write_time;     // rem this line after set DS1307
  Read_time;
  while true do
  begin
   I2C_Start;
   I2C_Wr($D0);              // Set I2c Unit to write mode
   I2C_Wr($00);              // Set pointer on I2c Unit
   I2C_Repeated_Start;
   I2C_Wr($D1);              // Set I2c Unit to Read mode
   Tsec :=I2C_Rd(0);         // Read byte
   I2C_Stop;
   Tsec  := Bcd2Dec(Tsec);
   if Tsec<>Gsec then  // Novi prikaz na ekranu, samo ako se sec promjenila.
   Begin
        Tsec:=Gsec;
        Read_time;
   End;
  end;
end.
Napomena:
Nemam zivaca da programiram tastere. Procedura Write_Time se koristi samo jednom da se postavi vrijeme u DS1307. Nakon toga je removati i isprogramirati PIC istim programom samo bez te procedure i sat ce raditi do vjecnosti bez poremecaja.
Attachments
DS1307.jpg
DS1307.jpg (25.19 KiB) Viewed 3718 times
User avatar
TomicIgor
Pocetnik na forumu
Pocetnik na forumu
Posts: 46
Joined: 25-06-2009, 23:34

Re: DS1307

Post by TomicIgor »

Pozdrav, koristim DS1337, ali imam problem :)

Koristim PIC na 12Mhz, i koristio sam I2C_SLOW 1
Adresa je RTC CON %11010000
Citanje radim ovako: I2CRead SDA, SCL, RTC, SecReg, [sec,MINs,hr,day,date,mon,yr]
SecReg je adresa sekundi i od nje cita danje, SecReg CON $00

I na displeju dobijam samo 2-ce.. i za sekunde, minute, sate.. sve je 2
I uvijek je 2.. ne pomjera se..

Da nije neko imao slucajno isti problem?
Pozz
djanib
Posts: 16
Joined: 14-12-2011, 21:41

Re: DS1307

Post by djanib »

- Napisi koji PIC koristis pa da ti napraviM hex za njega kao ovaj moj gore.
- Takodjer, koji display koristis (2x16, 4x20 ili nesto trece)
- Nadam se da si dobro sastavio RTC plocicu ili sta vec koristis.
Ako sumnjas i u to, uslikaj plocicu i stavi ovdje.

Kako god. Rjesit cemo ti problem. To sto imas sve 22222..... ne znaci nista. Milion razloga za to moze biti.
Ako dobijes ocitanja 65:65:65 ili 00:00:00 itd... znaci da RTC uopste neradi ili ga treba setovati.
User avatar
TomicIgor
Pocetnik na forumu
Pocetnik na forumu
Posts: 46
Joined: 25-06-2009, 23:34

Re: DS1307

Post by TomicIgor »

Koristim 18F2550
Displej je 2x16
RTC sam dobro spojio...
Meni treba samo da proradi ovo.. sa mojim kodom,
jer planiram jos da doradjujem.. pa mi ne odgovara tvoj hex.
Kada SDA i SCL prekinem izmedju pic-a i rtc-a, onda
dobijam ocitanje 00:00:00, kada diram prstom SDA i SCL,
onda dobijem neke brljotine. a kada je SDA i SCL spojen
izmedju pic-a i rtc-a.. onda samo prikazuje 02:02:02, po tome
valjda bi trebalo da je komunikacija ok i da cita iz RTC-a te brojeve
E sad.. da li ima neki registar za start brojanja sata ili sta? :S

Ovako izgleda kod za upis vremena:

Code: Select all

I2CWrite SDA, SCL, RTC, SecReg,[sec,mins,hr,day,date,mon,yr,cntrl] 
Pause 10
 I2CWrite SDA, SCL, RTC, ContReg,[%00000110] 
Pause 10 
I2CWrite SDA, SCL, RTC, StatusReg,[%00000000]
PAUSE 10
djanib
Posts: 16
Joined: 14-12-2011, 21:41

Re: DS1307

Post by djanib »

Mislio sam cisto da testiras hardware koji si napravio i da vidis da sve radi kako treba
da nebude jeli mi program nije uredu, jel me elektronika zeza itd...

Ja radim u MikroPascalu ili Assembleru sve, al sve je to isto. Bitno je da registre koristis
na ispravan nacin.

Iz ovih par linija koje si stavio nevidim nista bitno. Control registar postavljen i vezan
interrupt za Alarm 2, a status na default,,, Kako god....

Poenta koristenja RTC-a i DS1307 i DS1337 je i bilo cega sto je na i2c bus-u:
=================================================================
- Adresiraj i2c jedinicu koju zelis i u kojem modu zelis.
Za DS1337 i 1307 ($D0 write mode) i ($D1 read mode)
U svakom slucaju moras prvo poslati po i2c BUS-u $D0, sto ce RTC postaviti u Write mode, a zatim
$00 sto postavlja pointer na pocetni polozaj.
- Nakon toga ide tzv. RepeatedStart, znaci zaustavis i2c i ponovo ga startujes, ali sad na nacin na
koji ces koristiti RTC.
- $D1 (RTC u read modu), read sec, read min, read hr, ....... itd.
- Procitaj zadnji Byte sa "not acknowledge"
- Stop i2c bus.

I to je cijela pamet citanja RTC-a.

Code: Select all

   I2C_Start;
   I2C_Wr($D0);              // Set I2c Unit to write mode
   I2C_Wr($00);              // Set pointer on I2c Unit
   I2C_Repeated_Start;
   I2C_Wr($D1);              // Set I2c Unit to Read mode
   Gsec :=I2C_Rd(1);         // Read byte
   Gmin :=I2C_Rd(1);         // Read next byte
   Ghr  :=I2C_Rd(1);         // Read next
   Gday :=I2C_Rd(1);         // Read next
   Gdt  :=I2C_Rd(1);         // Read next
   Gmn  :=I2C_Rd(1);         // Read next
   Gye  :=I2C_Rd(0);         // Read last
   I2C_Stop;
Ako cesto citas RTC, zapamti da zadnji byte koji procitas iz RTC moras zavrsiti sa
not acknowledge signalom (Pogledaj u mom kodu predzadnju sintaksu koja cita godinu)
inace ces ga procitati jednom, a drugi put zaglaviti.

Write mode je jednostavniji jer sve mozes uraditi u jednom prolazu. Pri prvoj inicijalizaciji
RTC-a, svakako ga moras staviti u Write mode, da bi mu postavio pointer, al za razliku od
read, vise ti netreba RepeatedStart, nego samo nastavis sta hoces.

Code: Select all

    I2C_start;
    I2C_wr($D0);           // write to RTC
    I2C_wr($00);           // set pointer to 00
    I2C_wr(Gsec);          // set sec   0..59
    I2C_wr(Gmin);          // set min   0..59
    I2C_wr(Ghr);           // set hour  0..23
    I2C_wr(Gday);          // set day   1..7
    I2C_wr(Gdt);           // set date  1..31
    I2C_wr(Gmn);           // set month 1..12
    I2C_wr(Gye);           // set year  0..99
    I2C_Stop();            // Stop I2c BUS
DALLAS RTC i TimeKeeper-i imaju SQW (Square-Wave) koji je pri eksperimentima mudro
iskoristiti u obliku 1Hz i nakaci mu LED-erku. Po njoj znas da RTC-u kuca srce :)
SQW mozes iskoristiti u obliku 1Hz, 4KHz, 8KHz i 32KHz, sto je recimo vrlo korisno, ako
odlucis da ne citas stalno RTC, nego nakon prvog citanja, broji mu otkucaje, vezi ga za
RB Interrupt, radi inc i dec varijabli,,, mogucnosti su velike, samo malo maste :) .

Kako ukljuciti SQW, na koju freq ga staviti, Koristenje alarma 1&2 i koje flagove postavljaju
u Control i Status registrima i sve ovo sto sam ja pisao gore, detaljno imas objasnjeno u ....:

http://www.spikenzielabs.com/SpikenzieL ... S1337C.pdf

Nadam se da ti je ovo pomoglo vise od HEX-a kojeg sam prethodno ponudio za test.
User avatar
78L05
Pravo sam se raspisao :)
Pravo sam se raspisao :)
Posts: 1402
Joined: 28-05-2009, 13:22
Location: Hrvatska

Re: DS1307

Post by 78L05 »

Odlicno djani, svida mi se tvoja koncepcija i primjer.
Ja sam u PICBasic-u davno rijesio problem sa DS1307, napravio sam i mogucnost programiranja sata kod prvog paljenja (sklop uz RTC koristi jos i malu memoriju 24c04 jer interni EEPROM zna nekada zbrljati ili ne upisati vrijednost).
Ne vjeruj u čuda - računaj na njih!
Post Reply