ATmega128 tiny RTC 제어하기 -2

2019. 8. 11. 18:06임베디드/ATmega128

코드를 차근차근 작성해보려고 한다. 먼저 TWBR 레지스터 설정하기 위해서 DS1307의 Clock Frequency를 살펴봐야 한다. 데이터시트를 확인하면 최대 100KHz까지 속도를 지원한다

 

 

그리고 정보 설정 부분 글을 읽어보면

 

 

1. BCD 포멧으로 데이터를 저장하고, 읽을 때도 BCD 포멧으로 읽힌다

2. 00시가 되면 요일이 갱신된다. 1이 일요일, 2가 월요일로 시작하여 7이 토요일로 끝난다

3. CH는 크리스탈을 멈추게 하는 비트로 평상시엔 0으로 둬서 동작시키게 한다

4. 12/24시 모드가 있으며, bit6이 high 모드라면, 12시간 모드로, bit5를 읽어서 AM/PM을 구분할 수 있다

 

그리고 RTC 제어의 핵심인 bcd와 decimal간의 포멧변환 함수다. 저장할 때는 위의 함수를, 읽을 때는 아래 함수를 사용하면 된다

 

uint8_t decimal_to_bcd(uint8_t decimal)
{
	return (((decimal/10) << 4) | (decimal%10));
}

uint8_t bcd_to_decimal(uint8_t bcd)
{
	return (bcd>>4) * 10 + (bcd & 0x0F);
}

 

깃허브주소: https://github.com/surinoel/avr/tree/master/i2c/tinyRTC/tinyRTC

 

/*
* tinyRTC.c
*
* Created: 2019-08-11 오후 4:19:14
* Author : yeong
*/
#define F_CPU 16000000UL
#include <util/delay.h>
#include <avr/io.h>
#include "tinyRTC.h"
int main(void)
{
uart0_init();
tinyRTC_init();
tinyRTC_setup(00, 10, 17, 1, 11, 8, 19);
tinyRTC_set_date();
tinyRTC_read_date();
_delay_ms(2000);
tinyRTC_read_date();
while (1)
{
// 이 부분은 setup 이후에 실행
// tinyRTC_read_date();
}
}
view raw main.c hosted with ❤ by GitHub
/*
* tinyRTC.c
*
* Created: 2019-08-11 오후 4:23:38
* Author: yeong
*/
#include "tinyRTC.h"
#define SLAVE_ADDR 0x68
uint8_t setup_data[7];
uint8_t decimal_to_bcd(uint8_t decimal)
{
return (((decimal/10) << 4) | (decimal%10));
}
uint8_t bcd_to_decimal(uint8_t bcd)
{
return (bcd>>4) * 10 + (bcd & 0x0F);
}
void tinyRTC_init(void)
{
i2c_init();
DDRD |= (1<<0) | (1<<1);
}
void tinyRTC_setup(int sec, int min, int hour, int day, int date, int month, int year)
{
setup_data[0] = decimal_to_bcd(sec);
setup_data[1] = decimal_to_bcd(min);
setup_data[2] = decimal_to_bcd(hour);
setup_data[3] = decimal_to_bcd(day);
setup_data[4] = decimal_to_bcd(date);
setup_data[5] = decimal_to_bcd(month);
setup_data[6] = decimal_to_bcd(year);
}
void tinyRTC_set_date(void)
{
while(i2c_writeReg((SLAVE_ADDR << 1), 0x00, setup_data, 7));
}
void tinyRTC_read_date(void)
{
uint8_t data[7];
memset(data, 0, sizeof(data));
while(i2c_readReg((SLAVE_ADDR << 1), 0x00, data, 7));
printf("20%d,%d,%d (%s) %d:%d:%d\r\n", bcd_to_decimal(data[6]),
bcd_to_decimal(data[5]),
bcd_to_decimal(data[4]),
change_day(bcd_to_decimal(data[3])),
bcd_to_decimal(data[2]),
bcd_to_decimal(data[1]),
bcd_to_decimal(data[0]));
}
char *change_day(uint8_t day)
{
if (day == 1) return "sun";
else if (day == 2) return "mon";
else if (day == 3) return "tue";
else if (day == 4) return "wed";
else if (day == 5) return "thu";
else if (day == 6) return "fri";
else if (day == 7) return "sat";
}
view raw tinyRTC.c hosted with ❤ by GitHub

 

setup을 한 이후에는 setup을 위한 코드들은 모두 주석을 한 후 while 안에 코드만 실행시킨다