rtc

20
RTC Tujuan : Agar kami dapat memahami Real Time Clock dan memanfaatkan untuk membuat program dengan mengimpelentasi penggunaan data , control dan status bus dari AVR untuk menghubungkan dengan Real Time Clock DS1307. Teori : Prinsip dari Real Time Clock Real time clock pada dasarnya seperti jam biasa yang bekerja dengan baterai dan tetap menghitung waktu walaupun supply daya dimatikan. Dengan menggunakan RTC, kamu dapat tetap menjaga perhitungan waktu walaupun microcontroller yang digunakan diprogram ulang ataupun dicabut dari USB ataupun dari sumber daya.

TAGS:

Transcript of rtc

Page 1: rtc

RTC

Tujuan :

Agar kami dapat memahami Real Time Clock dan memanfaatkan untuk membuat program

dengan mengimpelentasi penggunaan data , control dan status bus dari AVR untuk

menghubungkan dengan Real Time Clock DS1307.

Teori :

Prinsip dari Real Time Clock

Real time clock pada dasarnya seperti jam biasa yang bekerja dengan baterai dan tetap

menghitung waktu walaupun supply daya dimatikan. Dengan menggunakan RTC, kamu dapat

tetap menjaga perhitungan waktu walaupun microcontroller yang digunakan diprogram ulang

ataupun dicabut dari USB ataupun dari sumber daya.

Kebanyakan microcontroller, termasuk ABR pada Codevision ABR mempiliki built-in

timekeeper yang disebut dengan millis() dan terdapat timer yang terintegrasi dalam chip yang

dapat menghitung periode waktu seperti menit ataupun hari. Permasalahan penggunaan chip

RTC yang terpisah karena millis90 hanya menghitung waktu ketika chip AVR dinyalakan yaitu

ketika power on, kemudian ketika dimatikan maka timer akan di set kembali ke 0. AVR tidak

akan tahu kapan akan hari “Selasa” atau bulan “Maret” atau tanggal 8 , yang bisa dilaporkan

hanya “ sudah 14,000 milisecond sejak saya terakhir dinyalakan.”

Page 2: rtc

Jadi , ketika kita ingin menentukan waktu pada AVR maka kita harus membuat program hari dan

waktu dengan menghitung dari hasil laporan dari millis, tetapi perlu diingat jika daya mati maka

perhitungan waktu akan diulang dari awal kembali.

Untuk beberapa project sederhana, metode timekeeping sederhana ini dapat digunakan , namun

untuk beberapa project seperti data-loggers , clock dsbnya memerlukan perhitungan waktu yang

konsisten yang tidak memerlukan reset ketika arduino battery mati ataupun di program ulang.

Oleh karena itu, kami menambahkan chip RTC secara terpisah. . Chip RTC adalah chip khusus

yang hanya menjaga perhitungan waktu. RTC dapat menghitung tahun dan dapat mengetahui

hari dalam bulan , namun dengan catatan bahwa RTC tidak mengurusi masalah daylight savings

time ( waktu pada musim panas karena hal ini berbeda beda pada tiap daerah).

IC DS1307

The DS1307adalah IC serial real-time clock (RTC) yang berdaya rendah , full binary-coded

decimal.(BCD) clock/calendar dengan 56 bytes N SRAM. Alamat dan data dikirim secara Serial

melalui I2C, bidirectional bus. The clock/calendar menyediakan informasi detik, menit , jam,

hari, bulan , dan tahun. Akhir dari bulan secara otomatis disesuaikan untuk bulan yang kurang

dari 31 hari , termasuk koreksi untuk tahun kabisat . Jam dapat beroperasi baik dalam mode 24

jam ataupun format 12 jam dengan indicator AM/PM.

Page 3: rtc

Gambar 7.1 Konfigurasi Pin pada IC DS1307

A. Procedure

a. Initializing RTC

I/O Configuration PORT B LCD

PORT C IC DS1307

Main.c

#include <avr/io.h>

#include "i2c.h"

#include "lcd.h"

#define CLOCK_ADDRESS 0xD0

char bcd2bin(char input)

{

return ((input>>4)*10)+(input&0x0f);

}

char bin2bcd(char binary)

{

return ((binary/10)<<4)+(binary%10);

Page 4: rtc

}

unsigned char rtcReadByte(unsigned char address)

{

unsigned char data;

i2c_start();

i2c_write(CLOCK_ADDRESS);

i2c_write(address);

i2c_start();

i2c_write(CLOCK_ADDRESS+1);

data=i2c_read(0);

i2c_stop();

return data;

}

void rtcWriteByte(unsigned char address,unsigned char data)

{

i2c_start();

i2c_write(CLOCK_ADDRESS);

i2c_write(address);

i2c_write(data);

i2c_stop();

}

void rtcInitialize(unsigned char rs,unsigned char sqwe,unsigned char

out)

Page 5: rtc

{

rs&=3;

if (sqwe) rs|=0x10;

if (out) rs|=0x80;

i2c_start();

i2c_write(CLOCK_ADDRESS);

i2c_write(7);

i2c_write(rs);

i2c_stop();

}

void rtcGetTime(unsigned char *hour,unsigned char *min,unsigned char

*sec)

{

i2c_start(); // Wake up everyone on I2C

Bus

i2c_write(CLOCK_ADDRESS); // Select one device to talk on I2C

Bus

i2c_write(0); // Write the register to R/W

Info

i2c_start(); // RepeatStart to Read in

info

i2c_write(CLOCK_ADDRESS+1); // Chip address to read from

*sec=bcd2bin(i2c_read(1)); // Read data, if more data to read,

Page 6: rtc

send ACK

*min=bcd2bin(i2c_read(1));

*hour=bcd2bin(i2c_read(0)); // Send NACK --> End

Transmission

i2c_stop(); // End I2C Transaction

}

void rtcSetTime(unsigned char hour,unsigned char min,unsigned char sec)

{

i2c_start();

i2c_write(CLOCK_ADDRESS);

i2c_write(0); // Address to write first

byte to

i2c_write(bin2bcd(sec)); // Continue writing data, DS1307

automatically increments address

i2c_write(bin2bcd(min)); // Write to next register

i2c_write(bin2bcd(hour));

i2c_stop(); // End transaction

}

void rtcGetDate(unsigned char *date,unsigned char *month,unsigned char

*year)

{

i2c_start();

i2c_write(CLOCK_ADDRESS);

Page 7: rtc

i2c_write(4);

i2c_start();

i2c_write(CLOCK_ADDRESS+1);

*date=bcd2bin(i2c_read(1));

*month=bcd2bin(i2c_read(1));

*year=bcd2bin(i2c_read(0));

i2c_stop();

}

void rtcSetDate(unsigned char date,unsigned char month,unsigned char

year)

{

i2c_start();

i2c_write(CLOCK_ADDRESS);

i2c_write(4);

i2c_write(bin2bcd(date));

i2c_write(bin2bcd(month));

i2c_write(bin2bcd(year));

i2c_stop();

}

unsigned char rtcGetDayOfWeek(void)

{

unsigned char day;

i2c_start();

Page 8: rtc

i2c_write(CLOCK_ADDRESS);

i2c_write(3);

i2c_start();

i2c_write(CLOCK_ADDRESS+1);

day=bcd2bin(i2c_read(0));

i2c_stop();

return day;

}

void rtcSetDayOfWeek(unsigned char day)

{

i2c_start();

i2c_write(CLOCK_ADDRESS);

i2c_write(3);

i2c_write(day);

i2c_stop();

}

int main(void)

{

unsigned char hour =1, min =1 , sec =1;

i2c_init();

DDRB = 0xFF;

initlcd();

rtcSetTime(11,30,0);

Page 9: rtc

while(1)

{

rtcGetTime(&hour, &min, &sec);

lcd_gotoxy(0,0);

lcd_putnum(hour);

LCD_putch(' ');

lcd_putnum(min);

LCD_putch(' ');

lcd_putnum(sec);

LCD_putch(' ');

}

}

I2c.c

#include <avr/io.h>

#include "i2c.h"

void i2c_init(void)

{

PORTC |= (1<<1)|(1<<0);

// SCL freq = F_CPU/(16+2*TWBR*(4^Prescaler)))

TWSR &= ~((1<<TWPS1)|(1<<TWPS0));

TWBR = 4; //SCL = 50KHz

TWCR |= (1<<TWEN)|(1<<TWEA); // Enable I2C Hardware bit

}

Page 10: rtc

void i2cWaitForComplete(void)

{

while(!(TWCR&(1<<TWINT)));

}

void i2c_start(void)

{

TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);

i2cWaitForComplete();

}

void i2c_stop(void)

{

TWCR = (1<<TWINT)|(1<<TWEA)|(1<<TWSTO);

}

void i2cSendByte(char data)

{

TWDR = data;

TWCR = (1<<TWINT) | (1<<TWEN);

}

void i2cReceiveByte(char ackFlag)

{

if(ackFlag)

TWCR = (1<<TWEN)|(1<<TWINT)|(1<<TWEA);

else

Page 11: rtc

TWCR = (1<<TWEN)|(1<<TWINT);

}

unsigned char i2c_write(char data)

{

i2cSendByte(data);

i2cWaitForComplete();

if((TWSR & 0xF8) == 0x18) return 1;

if((TWSR & 0xF8) == 0x28) return 1;

return 0;

}

char i2c_read(char ack)

{

i2cReceiveByte(ack);

i2cWaitForComplete();

return TWDR;

}

I2c.h

#ifndef __I2C_H__

#define __I2C_H__

void i2c_init(void);

void i2cWaitForComplete(void);

void i2c_start(void);

void i2c_stop(void);

Page 12: rtc

void i2cSendByte(char data);

void i2cReceiveByte(char ackFlag);

unsigned char i2c_write(char data);

char i2c_read(char ack);

#endif

Lcd.c

#include <avr/io.h>

#include <util/delay.h>

#include "lcd.h"

void LCD_putch(unsigned char data)

{

LCD_PORT = (1<<EN)|(1<<RS)|(data & 0xF0);

LCD_PORT &= ~(1<<EN);

_delay_us(1);

LCD_PORT = (1<<RS)|(1<<EN)|((data & 0x0F) << 4);

LCD_PORT &= ~(1<<EN);

_delay_ms(5);

}

void LCD_putcmd(unsigned char data,unsigned char cmdtype)

{

LCD_PORT = (1<<EN)|(data & 0xF0);

LCD_PORT &= ~(1<<EN);

_delay_us(1);

Page 13: rtc

if(cmdtype){

LCD_PORT = (1<<EN)|((data & 0x0F) << 4);

LCD_PORT &= ~(1<<EN);

}

_delay_ms(5);

}

void initlcd()

{

_delay_ms(30);

LCD_putcmd(0x30,LCD_1CYCLE);

_delay_ms(8);

LCD_putcmd(0x30,LCD_1CYCLE);

_delay_us(200);

LCD_putcmd(0x30,LCD_1CYCLE);

LCD_putcmd(0x20,LCD_1CYCLE);

LCD_putcmd(0x28,LCD_2CYCLE);

LCD_putcmd(0x0C,LCD_2CYCLE);

LCD_putcmd(0x01,LCD_2CYCLE);

LCD_putcmd(0x06,LCD_2CYCLE);

}

void lcd_puts(char *s)

{

while(*s != 0)

Page 14: rtc

{

if (*s == '\n')

LCD_putcmd(0xC0,LCD_2CYCLE);

else

LCD_putch(*s);

s++;

}

}

void lcd_gotoxy (unsigned char x, unsigned char y)

{

unsigned char Position = (1 << 7);

if (y==1)

Position |= 0x40;

else if (y==2)

Position |= 0x14;

else if (y==3)

Position |= 0x54;

Position += x;

LCD_putcmd(Position, LCD_2CYCLE);

}

void lcd_clear()

{

LCD_putcmd(0x01, LCD_2CYCLE);

Page 15: rtc

}

void lcd_putnum(int number)

{

unsigned char digit;

digit = '0';

while(number >= 100)

{

digit++;

number -= 100;

}

if (digit != '0')

LCD_putch(digit);

else

LCD_putch('0');

digit = '0';

while(number >= 10)

{

digit++;

number -= 10;

}

if (digit != '0')

LCD_putch(digit);

else

Page 16: rtc

LCD_putch('0');

LCD_putch('0' + number);

}

Lcd.h

#ifndef __LCD_H__

#define __LCD_H__

#define LCD_PORT PORTB

#define EN PB2

#define RD PB1

#define RS PB0

#define LCD_1CYCLE 0

#define LCD_2CYCLE 1

void LCD_putch(unsigned char data);

void LCD_putcmd(unsigned char data, unsigned char cmdtype);

void initlcd();

void lcd_puts(char *s);

void lcd_gotoxy(unsigned char x, unsigned char y);

void lcd_clear();

void lcd_putnum(int number);

#endif