Last active
August 29, 2015 14:25
-
-
Save tokolist/0d99eae496dc7c4529d6 to your computer and use it in GitHub Desktop.
AVR ds1302 RTC library
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "ds1302.h" | |
#include <avr/io.h> | |
#include <util/delay.h> | |
void ds1302_write(unsigned char cmd) | |
{ | |
DS1302_CE_DDR |= (1<<DS1302_CE_PNUM); | |
DS1302_SCLK_DDR |= (1<<DS1302_SCLK_PNUM); | |
DS1302_CE_PORT |= (1<<DS1302_CE_PNUM); | |
_delay_us(4); | |
DS1302_IO_DDR |= (1<<DS1302_IO_PNUM); | |
for(unsigned char i=0; i<8; i++) | |
{ | |
if((cmd&(1<<i)) == 1<<i) | |
{ | |
DS1302_IO_PORT |= (1<<DS1302_IO_PNUM); | |
} | |
else | |
{ | |
DS1302_IO_PORT &= ~(1<<DS1302_IO_PNUM); | |
} | |
DS1302_SCLK_PORT |= (1<<DS1302_SCLK_PNUM); | |
_delay_us(1); | |
DS1302_IO_PORT &= ~(1<<DS1302_IO_PNUM); | |
DS1302_SCLK_PORT &= ~(1<<DS1302_SCLK_PNUM); | |
} | |
} | |
unsigned char ds1302_read() | |
{ | |
unsigned char readbyte=0; | |
DS1302_IO_DDR &= ~(1<<DS1302_IO_PNUM); | |
for(unsigned char i=0; i<8; i++) | |
{ | |
DS1302_SCLK_PORT |= (1<<DS1302_SCLK_PNUM); | |
if((DS1302_IO_PIN & (1<<DS1302_IO_PNUM))==0) | |
{ | |
readbyte &= ~(1<<i); | |
} | |
else | |
{ | |
readbyte |= 1<<i; | |
} | |
_delay_us(10); | |
DS1302_SCLK_PORT &= ~(1<<DS1302_SCLK_PNUM); | |
_delay_us(2); | |
} | |
DS1302_CE_PORT &= ~(1<<DS1302_CE_PNUM); | |
_delay_us(4); | |
return readbyte; | |
} | |
unsigned char ds1302_read_byte(unsigned char byte_r) | |
{ | |
ds1302_write(byte_r); | |
return ds1302_read(); | |
} | |
void ds1302_write_byte(unsigned char byte_w, unsigned char val) | |
{ | |
ds1302_write(byte_w); | |
ds1302_write(val); | |
DS1302_CE_PORT &= ~(1<<DS1302_CE_PNUM); | |
} | |
void ds1302_rw(Ds1302_operation oper, Ds1302_register reg, Ds1302_rtc_time &rtc_time) | |
{ | |
unsigned char byte; | |
if(oper == READ){ | |
switch(reg){ | |
case CH: | |
byte = ds1302_read_byte(DS1302_SEC_R); | |
rtc_time.ch = byte & 0b10000000; | |
break; | |
case SEC: | |
byte = ds1302_read_byte(DS1302_SEC_R); | |
rtc_time.sec = (byte & 0b00001111) + ((byte>>4) & 0b00000111) * 10; | |
break; | |
case MIN: | |
byte = ds1302_read_byte(DS1302_MIN_R); | |
rtc_time.min = (byte & 0b00001111) + ((byte>>4) & 0b00000111) * 10; | |
break; | |
case HOUR: | |
byte = ds1302_read_byte(DS1302_HOUR_R); | |
rtc_time.hour.mode12h = (byte & 0b10000000); | |
if(rtc_time.hour.mode12h) | |
{ | |
rtc_time.hour.pm = (byte & 0b00100000); | |
rtc_time.hour.hour = (byte & 0b00001111) + ((byte>>4) & 0b00000001) * 10; | |
} | |
else | |
{ | |
rtc_time.hour.hour = (byte & 0b00001111) + ((byte>>4) & 0b00000011) * 10; | |
} | |
break; | |
case DATE: | |
byte = ds1302_read_byte(DS1302_DATE_R); | |
rtc_time.date = (byte & 0b00001111) + ((byte>>4) & 0b00000011) * 10; | |
break; | |
case MONTH: | |
byte = ds1302_read_byte(DS1302_MONTH_R); | |
rtc_time.month = (byte & 0b00001111) + ((byte>>4) & 0b00000001) * 10; | |
break; | |
case DAY: | |
byte = ds1302_read_byte(DS1302_DAY_R); | |
rtc_time.day = byte & 0b00000111; | |
break; | |
case YEAR: | |
byte = ds1302_read_byte(DS1302_YEAR_R); | |
rtc_time.year = (byte & 0b00001111) + ((byte>>4) & 0b00001111) * 10; | |
break; | |
case WP: | |
byte = ds1302_read_byte(DS1302_WP_R); | |
rtc_time.wp = byte & 0b10000000; | |
break; | |
} | |
} else { //WRITE | |
switch(reg){ | |
case CH: | |
byte = ds1302_read_byte(DS1302_SEC_R); | |
if(rtc_time.ch){ | |
byte |= 0b10000000; | |
} else { | |
byte &= 0b01111111; | |
} | |
ds1302_write_byte(DS1302_SEC_W, byte); | |
break; | |
case SEC: | |
//preserve CH bit value | |
byte = ds1302_read_byte(DS1302_SEC_R) & 0b10000000; | |
byte |= (((rtc_time.sec/10)<<4) & 0b01110000) | (rtc_time.sec%10); | |
ds1302_write_byte(DS1302_SEC_W, byte); | |
break; | |
case MIN: | |
ds1302_write_byte(DS1302_MIN_W, (((rtc_time.min/10)<<4) & 0b01110000) | (rtc_time.min%10)); | |
break; | |
case HOUR: | |
if(rtc_time.hour.mode12h){ | |
byte = 0b10000000 | (((rtc_time.hour.hour/10)<<4) & 0b00010000) | (rtc_time.hour.hour%10); | |
if(rtc_time.hour.pm) byte |= 0b00100000; | |
} else { | |
byte = (((rtc_time.hour.hour/10)<<4) & 0b00110000) | (rtc_time.hour.hour%10); | |
} | |
ds1302_write_byte(DS1302_HOUR_W, byte); | |
break; | |
case DATE: | |
ds1302_write_byte(DS1302_DATE_W, (((rtc_time.date/10)<<4) & 0b00110000) | (rtc_time.date%10)); | |
break; | |
case MONTH: | |
ds1302_write_byte(DS1302_MONTH_W, (((rtc_time.month/10)<<4) & 0b00010000) | (rtc_time.month%10)); | |
break; | |
case DAY: | |
ds1302_write_byte(DS1302_DAY_W, rtc_time.day & 0b00000111); | |
break; | |
case YEAR: | |
ds1302_write_byte(DS1302_YEAR_W, (((rtc_time.year/10)<<4) & 0b11110000) | (rtc_time.year%10)); | |
break; | |
case WP: | |
ds1302_write_byte(DS1302_WP_W, rtc_time.wp ? 0b10000000 : 0b00000000); | |
break; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef DS1302_H_ | |
#define DS1302_H_ | |
#define F_CPU 8000000 //8MHz | |
#define DS1302_CE_PIN PIND | |
#define DS1302_CE_DDR DDRD | |
#define DS1302_CE_PORT PORTD | |
#define DS1302_CE_PNUM 5 | |
#define DS1302_IO_PIN PIND | |
#define DS1302_IO_DDR DDRD | |
#define DS1302_IO_PORT PORTD | |
#define DS1302_IO_PNUM 6 | |
#define DS1302_SCLK_PIN PIND | |
#define DS1302_SCLK_DDR DDRD | |
#define DS1302_SCLK_PORT PORTD | |
#define DS1302_SCLK_PNUM 7 | |
#define DS1302_SEC_W 0x80 | |
#define DS1302_SEC_R 0x81 | |
#define DS1302_MIN_W 0x82 | |
#define DS1302_MIN_R 0x83 | |
#define DS1302_HOUR_W 0x84 | |
#define DS1302_HOUR_R 0x85 | |
#define DS1302_DATE_W 0x86 | |
#define DS1302_DATE_R 0x87 | |
#define DS1302_MONTH_W 0x88 | |
#define DS1302_MONTH_R 0x89 | |
#define DS1302_DAY_W 0x8a | |
#define DS1302_DAY_R 0x8b | |
#define DS1302_YEAR_W 0x8c | |
#define DS1302_YEAR_R 0x8d | |
#define DS1302_WP_W 0x8e | |
#define DS1302_WP_R 0x8f | |
#define DS1302_TRICKLE_CHARGE_W 0x90 | |
#define DS1302_TRICKLE_CHARGE_R 0x91 | |
#define DS1302_CLOCK_BURST_W 0xbe | |
#define DS1302_CLOCK_BURST_R 0xbf | |
#define DS1302_RAM_BURST_W 0xfe | |
#define DS1302_RAM_BURST_R 0xff | |
typedef struct { | |
unsigned char hour; | |
bool pm; | |
bool mode12h; | |
} Ds1302_hour; | |
typedef struct { | |
bool ch; | |
unsigned char sec; | |
unsigned char min; | |
Ds1302_hour hour; | |
unsigned char date; | |
unsigned char month; | |
unsigned char day; | |
unsigned char year; | |
bool wp; | |
} Ds1302_rtc_time; | |
enum Ds1302_operation {READ, WRITE}; | |
enum Ds1302_register {CH, SEC, MIN, HOUR, DATE, MONTH, DAY, YEAR, WP}; | |
void ds1302_write(unsigned char cmd); | |
unsigned char ds1302_read(); | |
unsigned char ds1302_read_byte(unsigned char byte_r); | |
void ds1302_write_byte(unsigned char byte_w, unsigned char val); | |
void ds1302_rw(Ds1302_operation oper, Ds1302_register reg, Ds1302_rtc_time &rtc_time); | |
#endif /* DS1302_H_ */ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "ds1302.h" | |
Ds1302_rtc_time rtc_time; | |
//read | |
ds1302_rw(READ, YEAR, rtc_time); | |
ds1302_rw(READ, MONTH, rtc_time); | |
ds1302_rw(READ, DATE, rtc_time); | |
//write | |
rtc_time.year = 15; | |
rtc_time.month = 7; | |
rtc_time.date = 25; | |
ds1302_rw(WRITE, YEAR, rtc_time); | |
ds1302_rw(WRITE, MONTH, rtc_time); | |
ds1302_rw(WRITE, DATE, rtc_time); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment