CCS C de DS1307 nin saat ve dakika sorunu

Başlatan mrs. engineer, 31 Temmuz 2017, 10:47:42

mrs. engineer

Merhaba saat sıcaklık devresi yapmaya çalışıyorum. ds1307 için internetten bulduğum driver(aynı driver ile sorun yaşamadan devrenin çalıştığı belirtilmektedir) ile çalıştırdığımda saat ve dakika kısmında sorun oluyor. Saat sistem saatini almayıp sürekl, 00:07 olarak başlıyor. Sorun driver yada yazdığım kodda mı çözemedim . Driver ve kodlar aşağıdadır. Yardımcı olursanız çok sevinirim.
program kodları
#include <saat.h>
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD // Denetleyici konfigürasyon ayarları

#use delay (clock=4000000)

#define use_portb_lcd TRUE
#include <lcd.c>
#include <C:\Users\Arge\Desktop\DS1307\ds1307(1).c>

#define LCD_ENABLE_PIN  PIN_B0                                   
#define LCD_RS_PIN      PIN_B1                                    
#define LCD_RW_PIN      PIN_B2                                  
#define LCD_DATA4       PIN_B4                                    
#define LCD_DATA5       PIN_B5                                    
#define LCD_DATA6       PIN_B6                                    
#define LCD_DATA7       PIN_B7     

byte saniye,dakika,saat,gun,ay,yil,haftanin_gunu;

void main()
{
  
   lcd_init();
   ds1307_init();
   
   //ds1307_set_date_time(20,07,07,6,22,52,11);
  
   while(1)
   {
      ds1307_get_time(saat,dakika,saniye);
      ds1307_get_date(gun,ay,yil,haftanin_gunu);
      printf(lcd_putc,"\fTarih:%02d/%02d/20%02d",gun,ay,yil);    
      
         switch(haftanin_gunu)
     {   // metin olarak karşılık atanıyor
         case 1: printf(lcd_putc,"PAZ"); break; // Eğer "1" ise LCD'ye PAZ yaz
         case 2: printf(lcd_putc,"PZT"); break; // Eğer "2" ise LCD'ye PZT yaz
         case 3: printf(lcd_putc,"SAL"); break; // Eğer "3" ise LCD'ye SAL yaz
         case 4: printf(lcd_putc,"CRS"); break; // Eğer "4" ise LCD'ye CRS yaz
         case 5: printf(lcd_putc,"PER"); break; // Eğer "5" ise LCD'ye PER yaz
         case 6: printf(lcd_putc,"CUM"); break; // Eğer "6" ise LCD'ye CUM yaz
         case 7: printf(lcd_putc,"CTS"); break; // Eğer "7" ise LCD'ye CTS yaz
      }
      
     printf(lcd_putc,"\nSaat:%02d:%02d:%02d",saat,dakika,saniye); // LCD'ye saat,dakika ve saniye değerlerini yaz
     delay_ms(1000); // 1 sn gecikme veriliyo
     
   }
     
   }


ds1307 driver
//////////////////////////////////////////////////////////////////////////////// 
///                               DS1307.C                                   /// 
///                     Driver for Real Time Clock                           /// 
///                                                                          /// 
/// ds1307_init() - Enable oscillator without clearing the seconds register -/// 
///                 used when PIC loses power and DS1307 run from 3V BAT     /// 
///               - Disable squarewave output                                /// 
///                                                                          /// 
/// ds1307_set_date_time(day,mth,year,dow,hour,min,sec)  Set the date/time   /// 
///                                                                          /// 
/// ds1307_get_date(day,mth,year,dow)               Get the date             /// 
///                                                                          /// 
/// ds1307_get_time(hr,min,sec)                     Get the time             /// 
///                                                                          /// 
//////////////////////////////////////////////////////////////////////////////// 

#define RTC_SDA  PIN_D1
#define RTC_SCL  PIN_D0

#use i2c(master, sda=RTC_SDA, scl=RTC_SCL) 

BYTE bin2bcd(BYTE binary_value); 
BYTE bcd2bin(BYTE bcd_value); 

void ds1307_init(void) 
{ 
   BYTE seconds = 0; 

   i2c_start(); 
   i2c_write(0xD0);      // WR to RTC 
   i2c_write(0x00);      // REG 0 
   i2c_start(); 
   i2c_write(0xD1);      // RD from RTC 
   seconds = bcd2bin(i2c_read(0)); // Read current "seconds" in DS1307 
   i2c_stop(); 
   seconds &= 0x7F; 

   delay_us(3); 

   i2c_start(); 
   i2c_write(0xD0);      // WR to RTC 
   i2c_write(0x00);      // REG 0 
   i2c_write(bin2bcd(seconds));     // Start oscillator with current "seconds value 
   i2c_start(); 
   i2c_write(0xD0);      // WR to RTC 
   i2c_write(0x07);      // Control Register 
   i2c_write(0x80);     // Disable squarewave output pin 
   i2c_stop(); 

} 

void ds1307_set_date_time(BYTE day, BYTE mth, BYTE year, BYTE dow, BYTE hr, BYTE min, BYTE sec) 
{ 
  sec &= 0x7F; 
  hr &= 0x3F; 

  i2c_start(); 
  i2c_write(0xD0);            // I2C write address 
  i2c_write(0x00);            // Start at REG 0 - Seconds 
  i2c_write(bin2bcd(sec));      // REG 0 
  i2c_write(bin2bcd(min));      // REG 1 
  i2c_write(bin2bcd(hr));      // REG 2 
  i2c_write(bin2bcd(dow));      // REG 3 
  i2c_write(bin2bcd(day));      // REG 4 
  i2c_write(bin2bcd(mth));      // REG 5 
  i2c_write(bin2bcd(year));      // REG 6 
  i2c_write(0x80);            // REG 7 - Disable squarewave output pin 
  i2c_stop(); 
} 

void ds1307_get_date(BYTE &day, BYTE &mth, BYTE &year, BYTE &dow) 
{ 
  i2c_start(); 
  i2c_write(0xD0); 
  i2c_write(0x03);            // Start at REG 3 - Day of week 
  i2c_start(); 
  i2c_write(0xD1); 
  dow  = bcd2bin(i2c_read() & 0x7f);   // REG 3 
  day  = bcd2bin(i2c_read() & 0x3f);   // REG 4 
  mth  = bcd2bin(i2c_read() & 0x1f);   // REG 5 
  year = bcd2bin(i2c_read(0));            // REG 6 
  i2c_stop(); 
} 

void ds1307_get_time(BYTE &hr, BYTE &min, BYTE &sec) 
{ 
  i2c_start(); 
  i2c_write(0xD0); 
  i2c_write(0x00);            // Start at REG 0 - Seconds 
  i2c_start(); 
  i2c_write(0xD1); 
  sec = bcd2bin(i2c_read() & 0x7f); 
  min = bcd2bin(i2c_read() & 0x7f); 
  hr  = bcd2bin(i2c_read(0) & 0x3f); 
  i2c_stop(); 

} 

BYTE bin2bcd(BYTE binary_value) 
{ 
  BYTE temp; 
  BYTE retval; 

  temp = binary_value; 
  retval = 0; 

  while(true) 
  { 
    // Get the tens digit by doing multiple subtraction 
    // of 10 from the binary value. 
    if(temp >= 10) 
    { 
      temp -= 10; 
      retval += 0x10; 
    } 
    else // Get the ones digit by adding the remainder. 
    { 
      retval += temp; 
      break; 
    } 
  } 

  return(retval); 
} 


// Input range - 00 to 99. 
BYTE bcd2bin(BYTE bcd_value) 
{ 
  BYTE temp; 

  temp = bcd_value; 
  // Shifting upper digit right by 1 is same as multiplying by 8. 
  temp >>= 1; 
  // Isolate the bits for the upper digit. 
  temp &= 0x78; 

  // Now return: (Tens * 8) + (Tens * 2) + Ones 

  return(temp + (temp >> 2) + (bcd_value & 0x0f)); 
}


devre


amigoska

sorunu çözebildiniz mi bendede aynı problem sayılır haftanın günü, ve ayın kaçı olduğu verisi tutmuyor.
İyi yaşadıkça hayalleriniz gelir sizi bulur...

elektronart

#2
includeları .c şeklinde yapmak pek alışıldık bir yöntem değildir. Neden buna ihtiyaç duydun. Bir de saat.h de neler var. Ortalığı o karıştırıyor olabilir mi?
Açık Elektronik

ziyaretci

"sistemin saatini almıyor" derken siz önce ayarlıyor musunuz bu saati? Ve harici batarya takılı mı, devre enerjisi kesildiğinde sistemin saymaya devam etmesi için? Eğer takıldı ise bu bataryanın ayarı yapıldı mı ds1307 üzerinde?(Dahili diyot bağlantısı register ayarlarından bahsediyorum.)

Kurduğunuz devrenin şemasını paylaşır mısınız?

fide


#define RTC_SDA  PIN_D1
#define RTC_SCL  PIN_D0

Satırlarını kendi mcunuza güncelleyin.
Bir de mcuda birden fazla i2c kanalı varsa use i2c de hangi kanalı kullanıyorsanız o kanalın ismini yazın. İ2c1, i2c2 gibi.
Saatin takıldığı kanal farklı, okunan kanal farklı olabilir.
Her birimiz, geride bıraktığımız eserler kadar ölümsüzüz. Evlat gibi, talebe gibi, icatlar gibi...   http://fidenetgaraj.blogspot.com