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
This file contains 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
/* | |
* 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(); | |
} | |
} |
This file contains 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
/* | |
* 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"; | |
} |
setup을 한 이후에는 setup을 위한 코드들은 모두 주석을 한 후 while 안에 코드만 실행시킨다
'임베디드 > ATmega128' 카테고리의 다른 글
ATmega128 I2C 1602 텍스트 LCD 사용자 정의 문자 생성(CGRAM) (0) | 2019.08.15 |
---|---|
ATmega128 tiny RTC BAT 동작이 불능인 이유 (0) | 2019.08.11 |
ATmega128 tiny RTC 제어하기 -1 (0) | 2019.08.11 |
ATmega128 적외선 거리센서(SHARP_2Y0A21) 제어하기 (3) | 2019.08.04 |
Atmel Studio7 prinf float (0) | 2019.08.04 |