1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading ... Loading ...
Nis
21st

PCF8583 İçin Sürücü Programı

pcf8583.JPG

 

Bu sayfada PCF8583 gerçek zaman entegresi için sürücü programı verilmiştir.

Bu entegre yıl bilgisini tutacak 8 bitlik yazmacı olmaması ve yedek pil için besleme bacağına sahip olmadığından saat devreleri için çok ideal değildir. DS1307 veya sürücüsü ccs’de hazır olan DS1302 entegresi uygulamalarınızda daha yararlı olabilir.

Bu sürücü dosyasında yıl bilgisini tutmak için NVRAM’den yazılımsal olarak faydalanılmıştır. Her 3 yıılda bir yıl bilgisi okunduğu sürece sıkıntı olmayacaktır.

 


Tasarımında bu entegreyi kullanmak isteyenler için örnek uygulama bağlantıları, programı ve sürücü yazılımı aşağıda verilmiştir.

Örnek Uygulama Programı

#include <16F877.H>

#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP

#use delay(clock=4000000)

#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

#include

#include

// Bu uygulama programında tarih zaman bilgileri

// seri porttan gösterilir veya değiştirilebilir

void main()

{

char c;

char weekday[10];

date_time_t dt;

PCF8583_init();

printf(”Ornek tarih ve zaman bilgileri\n\r”);

printf(”23/12/06 23:59:50 (Pazar) yazilsin mi ? (Y/N)\n\r”);

while(1)

{

c = getc(); // Wait for user to press a key

c = toupper(c);

if(c == ‘Y’)

{

dt.month = 12; // Aralık

dt.day = 31; // 31

dt.year = 07; // 2007

dt.hours = 23; // 23 saat

dt.minutes = 59; // 59 dakika

dt.seconds = 50; // 50 saniye

dt.weekday = 0; // 0 = Pazar, 1 = Pzartesi, vs.

PCF8583_set_datetime(&dt);

printf(”\n\r”);

printf(”Yani tarih ve zaman bilgieri yazildi.\n\r”);

printf(”2008′e gecise bakiniz \r”);

break;

}

if(c == ‘N’)

break;

}

printf(”\n\r”);

printf(” Tarih zaman bilgileri okunuyor\n\r”);

// Tarih ve zaman bilgileri birer saniye aralıklarla gösterilir

.

while(1)

{

delay_ms(1000);

PCF8583_read_datetime(&dt);

strcpy(weekday, weekday_names[dt.weekday]);

printf(”%s, %u/%u/%02u, %u:%02u:%02u\n\r”,

weekday, dt.day, dt.month, dt.year,

dt.hours, dt.minutes, dt.seconds);

}

}

Sürücü Programı

//Bu kodları PCF8583.C olarak kaydediniz //PCM Programmer

#ifndef PCF8583_SDA

#define PCF8583_SDA PIN_C4

#define PCF8583_SCL PIN_C3

#endif

#use i2c(master, sda=PCF8583_SDA, scl=PCF8583_SCL)

#ifndef PCF8583_WRITE_ADDRESS

#define PCF8583_WRITE_ADDRESS 0xA0

#define PCF8583_READ_ADDRESS 0xA1

#endif

// Register adresleri

#define PCF8583_CTRL_STATUS_REG 0×00

#define PCF8583_100S_REG 0×01

#define PCF8583_SECONDS_REG 0×02

#define PCF8583_MINUTES_REG 0×03

#define PCF8583_HOURS_REG 0×04

#define PCF8583_DATE_REG 0×05

#define PCF8583_MONTHS_REG 0×06

#define PCF8583_TIMER_REG 0×07

#define PCF8583_ALARM_CONTROL_REG 0×08

#define PCF8583_ALARM_100S_REG 0×09

#define PCF8583_ALARM_SECS_REG 0×0A

#define PCF8583_ALARM_MINS_REG 0×0B

#define PCF8583_ALARM_HOURS_REG 0×0C

#define PCF8583_ALARM_DATE_REG 0×0D

#define PCF8583_ALARM_MONTHS_REG 0×0E

#define PCF8583_ALARM_TIMER_REG 0×0F

//İlk NVRAM adresi yıl bilgisini tutmak için kullanılır.

#define PCF8583_YEAR_REG 0×10

//Control/Status yazmacı (register) için komutlar.

#define PCF8583_START_COUNTING 0×00

#define PCF8583_STOP_COUNTING 0×80

char const weekday_names[7][10] =

{

{”Pazar”},

{”Pazartesi”},

{”Sali”},

{”Carsamba”},

{”Persembe”},

{”Cuma”},

{”Cumartesi”}

};

// Bu yapı kullanıcının tarih ve zaman bilgilerini tanımlar

// Değerler işaretsiz int olarak tutulur. Kullanıcı da

// PCF8583 ile haberleşmek için yazdığı programda bu aşağıdakine

// benzer bir şekilde bir yapı oluşturarak,bu sürücüdeki yazma/okuma

// fonksiyolarına değer aktarmalıdır

typedef struct

{

int8 seconds; // 0′dan 59′a

int8 minutes; // 0′dan 59′a

int8 hours; // 0′dan 23′e

int8 day; // 1′den 31′e

int8 month; // 1′den 12′ye

int8 year; // 00′dan 99′a

int8 weekday; // 0 = Pazar, 1 = Pazartesi, vs.

}date_time_t;

//Yazma fonksiyonu

void PCF8583_write_byte(int8 address, int8 data)

{

disable_interrupts(GLOBAL);

i2c_start();

i2c_write(PCF8583_WRITE_ADDRESS);

i2c_write(address);

i2c_write(data);

i2c_stop();

enable_interrupts(GLOBAL);

}

//Okuma fonksiyonu

int8 PCF8583_read_byte(int8 address)

{

int8 retval;

disable_interrupts(GLOBAL);

i2c_start();

i2c_write(PCF8583_WRITE_ADDRESS);

i2c_write(address);

i2c_start();

i2c_write(PCF8583_READ_ADDRESS);

retval = i2c_read(0);

i2c_stop();

enable_interrupts(GLOBAL);

return(retval);

}

void PCF8583_init(void)

{

PCF8583_write_byte(PCF8583_CTRL_STATUS_REG,

PCF8583_START_COUNTING);

}

// Bu fonksiyon 8 bit ikili deÄŸeri

// 8 bit BCD değere çevirir.(Binary Coded Decimal)

// Giriş aralığı 0 ile 99 arasında olmalıdır.

int8 bin2bcd(int8 value)

{

char retval;

retval = 0;

while(1)

{

// Onlar basamağı, ikili değerden

// 10 sayısını sürekli çıkararak elde edilir

if(value >= 10)

{

value -= 10;

retval += 0×10;

}

else // Birler basamağı kalanı ekleyerek bulunur

{

retval += value;

break;

}

}

return(retval);

}

// Bu fonksiyon 8 bit BCD deÄŸeri

// 8 bit ikili değere çevirir.(Binary Coded Decimal)

// Giriş aralığı 0 ile 99 arasında olmalıdır.

char bcd2bin(char bcd_value)

{

char temp;

temp = bcd_value;

// En değerli biti sağa kaydırma

// 8 ile çarpma ile aynıdır.

temp >>= 1;

// Değerli bit için diğerleri izole edilir.

temp &= 0×78;

// Sonuç: (Tens * 8) + (Tens * 2) + Ones

return(temp + (temp >> 2) + (bcd_value & 0×0f));

}

void PCF8583_set_datetime(date_time_t *dt)

{

int8 bcd_sec;

int8 bcd_min;

int8 bcd_hrs;

int8 bcd_day;

int8 bcd_mon;

// Giriş tarih/zaman bilgileri PCF8583 yazmaçlarındaki

// kayıtlara uygun olarak BCD’ye çevrilir

bcd_sec = bin2bcd(dt->seconds);

bcd_min = bin2bcd(dt->minutes);

bcd_hrs = bin2bcd(dt->hours);

bcd_day = bin2bcd(dt->day) | (dt->year << 6);

bcd_mon = bin2bcd(dt->month) | (dt->weekday << 5);

// Tarih ve zaman yazmaçlarına kayıt yapmadan önce

// saat durdurulur.

PCF8583_write_byte(PCF8583_CTRL_STATUS_REG,

PCF8583_STOP_COUNTING);

// Tarih ve zaman yazmaçlara yazılırken i2c işlemlerinin

// aksamaması için kesmeler iptal edilir.

disable_interrupts(GLOBAL);

i2c_start();

i2c_write(PCF8583_WRITE_ADDRESS);

i2c_write(PCF8583_100S_REG);

i2c_write(0×00);

i2c_write(bcd_sec);

i2c_write(bcd_min);

i2c_write(bcd_hrs);

i2c_write(bcd_day);

i2c_write(bcd_mon);

i2c_stop();

enable_interrupts(GLOBAL);

// Yıl bilgisi NVRAM’in ilk yerine yazılır.

// İkili değer olarak bırakılır.

PCF8583_write_byte(PCF8583_YEAR_REG, dt->year);

// Şimdi PCF8583 saymaya başlatılır

PCF8583_write_byte(PCF8583_CTRL_STATUS_REG,

PCF8583_START_COUNTING);

}

// Tarih ve zaman bilgileri PCF8583′ün yazmaçlarından okunur

void PCF8583_read_datetime(date_time_t *dt)

{

int8 year_bits;

int8 year;

int8 bcd_sec;

int8 bcd_min;

int8 bcd_hrs;

int8 bcd_day;

int8 bcd_mon;

// i2c sürecinin kesintiye uğramaması için kesmeler iptal edilir

disable_interrupts(GLOBAL);

// Tarih ve zaman PCF8583 yazmaçlarından alınır.

i2c_start();

i2c_write(PCF8583_WRITE_ADDRESS);

i2c_write(PCF8583_SECONDS_REG); // Saniyeyi tutan yazmaçtan başlanır.

i2c_start();

i2c_write(PCF8583_READ_ADDRESS);

bcd_sec = i2c_read();

bcd_min = i2c_read();

bcd_hrs = i2c_read();

bcd_day = i2c_read();

bcd_mon = i2c_read(0);

i2c_stop();

enable_interrupts(GLOBAL);

// Tarih zaman deÄŸerleri BCD’den iÅŸaretsiz

// 8 bit tamsayılara çevrilir

dt->seconds = bcd2bin(bcd_sec);

dt->minutes = bcd2bin(bcd_min);

dt->hours = bcd2bin(bcd_hrs & 0×3F);

dt->day = bcd2bin(bcd_day & 0×3F);

dt->month = bcd2bin(bcd_mon & 0×1F);

dt->weekday = bcd_mon >> 5;

year_bits = bcd_day >> 6;

// Yıl bilgisi NVRAM’dan alınır.

year = PCF8583_read_byte(PCF8583_YEAR_REG);

// İki bitlik yıl bilgisi entegre tarafından artırılıp

// artırılmadığı kontrol edilir. Eğer artırılmışsa

// NVRAM’deki yıl deÄŸeri bir artırılır

while(year_bits != (year & 3))

year++;

dt->year = year;

// Yıl bilgisi hafızada güncellenir

PCF8583_write_byte(PCF8583_YEAR_REG, year);

}


Benzer Yazılar

Yorum yapın