Haberler:

Forum kuralları güncellendi LÜTFEN  okuyunuz:  https://bit.ly/2IjR3ME

Ana Menü

Timer 0 ve ds1307

Başlatan baran123, 02 Nisan 2014, 16:59:44

baran123

Merhaba ds1307 ile 6 digit saat yaptım fakat bir problem var tarama cok hızlı degıl proteusta gorebılıyorum boardada aynı sorun olurmu sızce ve devreyı ılk calıstırdıgımda bılgılerı bıraz gec okuyor ds1307 de yeniyim asagıdakı kodlarda bır hatam varmı birde bu sout pını ne oluyor ? yardımcı olursanız sevınırım ıyı calısmalar.

#include <16F877A.h>
#device adc=16
#fuses XT,NOWDT,NOBROWNOUT,NOLVP,NOPUT,NOCPD,NOWRT,NOPROTECT,NODEBUG
#use delay(clock=4M)   
                          
#include "ds1307.c"  

#define d6  pin_D6
#define d5  pin_D5
#define d4  pin_D4
#define d3  pin_D3 
#define d2  pin_D2  
#define d1  pin_D1  
                         
int sayac = 0;
const int digit[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};

int sec,min,hrs,day,month,yr,dow;    
          
#int_timer0        
void timer0_kesme() 
{         
   disable_interrupts(INT_TIMER0);
   switch(sayac)
   {
      case 0:
      output_low(d6);
      output_b(digit[hrs / 10]);
      output_high(d1);    
      sayac = 1;
      break;
      
      case 1:
      output_low(d1);
      output_b(digit[hrs % 10]);
      output_high(d2);
      sayac = 2;     
      break;
      
      case 2:
      output_low(d2);
      output_b(digit[min / 10]);
      output_high(d3);
      sayac = 3;
      break;
      
      case 3:
      output_low(d3);
      output_b(digit[min % 10]); 
      output_high(d4);
      sayac = 4;   
      break;      
      
      case 4:
      output_low(d4);
      output_b(digit[sec / 10]); 
      output_high(d5);
      sayac = 5;
      break;  
                    
      case 5:
      output_low(d5);
      output_b(digit[sec % 10]);
      output_high(d6);
      sayac = 0;   
      break;  
   }
   enable_interrupts(INT_TIMER0);
}

void main()
{
   setup_psp(PSP_DISABLED);   
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(T0_INTERNAL | T0_DIV_16 );
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_CCP1(CCP_OFF);   
   
   set_timer0(131);                            
   enable_interrupts(INT_TIMER0);
   enable_interrupts(GLOBAL);   
   
   ds1307_init();
                                                 
   while(TRUE)                                  
   { 
      delay_ms(1000);                      
                           
      ds1307_get_time(hrs,min,sec);
      ds1307_get_date(day,month,yr,dow);   
   }                            
}                                                 


ve kutuphanem

//////////////////////////////////////////////////////////////////////////////// 
///                               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_C4 
#define RTC_SCL  PIN_C3 

#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)); 
}

Kabil ATICI

#1
Sout bacağı DS1307'nin sinyal çıkışıdır. Yani DS1307'de ayarladığın frekansta darbe üretir.
0x07h adresindeki yaptığın ayara göre 1Hz, 4096Hz, 8192Hz ve 32.768KHz frekanslı sinyal verir.
Örneğin sen sürekli DS1307'den saat okuması yapmak istemiyorsun. Sadece ilk değeri okuyup işlemciye kaydeder ve saat, dakika, saniye işlemlerini işlemcide yaparsın. Saat senkronizasyonu için de DS1307'nin  Sout bacağını işlemcinin kesme girişlerinden birine bağlarsın ve kararlı bir saat kaynağın olur. (1Hz ile)

ek: İsis üzerindeki ayarlarını ve bilgisayarının kapasitesini bilemiyorum; o nedenle kart üzerindeki çalışması konusunu kesin bir şey söyleyemiyorum.

-ds13027'den bilgi alırken (okurken) timer kesmesini kapatsan iyi olur.
-ayarlarını nasıl yapacaksın;
-DS1307 ilk açıldığında saniyenin bit7 'deki değerinin (CH) lojik 0 yapılmalıdır.Yoksa saat çalışmaz. Ama bunu her seferinde yapmana gerek yok. Ancak pili çıkarılarak DS1307 sıfırlandığı zaman gerekir.
ambar7

haydarpasamikro

Ds1307 yi 1 Hz sinyal çıkışı verecek şekilde ayarla. Bunu kesme için kullanacağız. Her saniye palsinde bir kesme oluşup zaman değerini okuyacağız ve yeni değeri ekrana göndereceğiz. Ana programda sonsuz döngüde 6 basamaklı ekranı tarama yöntemi ile göster. Her bir basamakta biraz bekle. Mesela insan gözünün yakalayabileceği bir süre. 20ms gibi.
Mikro Dünyası.Haydarpaşa Teknik ve Endüstri Meslek Lisesi Mikrodenetleyici Atl. Şefi

baran123

Yanıtlar için teşekkürler bir şey daha sormak istiyorum 1 khz darbeyi alıp işlemcide saat işlemini yaparken güç kesintisi olsa tekrar açıldıgında saatde basa donme olmaz mı yoksa ayarlar yınede kaydolur mu ?

elektronart

bunun için işlemcide 1snden daha uzun bir timer (watchdog olabilir) kurup her sn resetleyebilirsin. Eğer 1snden daha uzun süre resetlenmezse bu döngü devreye girer ve bilirsin ki rtcden sana kesme gelmiyor. Ona göre bir kontrol koyup rtc yi ve elektriği kontrol edip duruma göre bir kod yazabilirsin.
Ek olarak out pini open collectordür. Pullup direncini pile bağlarsan sürekli çalıştırırsın, vcc ye bağlarsan haliyle güç kesildiğinde kapanır.
Açık Elektronik

selimkoc

http://elektrokod.wordpress.com/2013/10/18/timer0-zamanlama-uygulamasi/

linkinde hazırlamış olduğum timer0 ile ilgi bir yazı mevcut. Tarama yaparken saniyede en az 25 geçişin olması gerekir. Dolayısı ile timer0 süresini 3-5 ms olarak ayarlamalısın. Kolay gelsin...

Kabil ATICI

@baranekrem9
(1Hz)
Onun için sisteme besleme verildiğinde 1 kez DS1307'den saat değerlerini okuyup sonra saat işlemlerine devam ediyoruz. Bu her besleme verildiğinde yapılıyor.
ambar7