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
(https://s1.postimg.cc/b7z38pz9n/devre.png) (https://postimg.cc/image/b7z38pz9n/)
sorunu çözebildiniz mi bendede aynı problem sayılır haftanın günü, ve ayın kaçı olduğu verisi tutmuyor.
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?
"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?
#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.