행복한 하루

라즈베리파이 제로 프로젝트(16) – Pioneer600 모듈 Real Time Clock (DS3231) 본문

RaspberryPi/Raspberry Pi Zero

라즈베리파이 제로 프로젝트(16) – Pioneer600 모듈 Real Time Clock (DS3231)

변화의 물결 2021. 3. 13. 11:55

 

안녕하세요.

 

  이번에는 시계를 사용해보도록 하겠습니다. 그런데 Pioneer 모듈에는 시계로 보이는 것이 없는데라고 하실 텐데, 모듈에는 Real Time Clock( RTC)라고 하는 칩이 장착되어 있습니다. 이것을 이용해서 초기 설정을 해주고 코인 건전지(시계 건전지)를 넣어주면 전원이 없어도 일반 시계처럼 동작합니다. 이전 메인보드에도 코인 건전지가 포함되었지만, 최근에는 슈퍼 케패시터 등 다른 방법으로 배터리를 대체하고 있습니다.

 

1. RTC (實時間時計, Real Time Clock)란

 

RTC

  현재의 시간을 유지시키는 컴퓨터 시계이다. 이 용어가 개인용 컴퓨터, 서버, 임베디드 시스템의 장치를 일컫기도 하지만 실시간 시계는 정확한 시간을 유지해야 하는 거의 모든 전자기기에 존재한다.

 

  실시간 시계는 컴퓨터 전원이 나가도 시간이 유지되어야 하기 때문에 마이크로프로세서의 개입 없이 초부터 년까지의 시간을 디지털 회로의 카운터에 의존하여 시간을 센다. 컴퓨터의 전원이 인가되지 않아도 시간을 유지하도록 동작하는 것이 필요하다.

 

  만약 컴퓨터를 껐는데 RTC의 카운터 회로에 전원이 인가되지 않으면 카운터 값을 상실하기 때문에 시간을 다시 설정해야 하는 문제가 발생한다. 따라서 컴퓨터의 전원이 꺼져도 RTC의 카운터 회로에 전원을 공급함으로써 시간 카운터를 유지하여 시간 값을 유지하도록 시스템을 구성한다.

  

2. DS3231 스펙

  - The DS3231 is a low-cost, extremely accurate I2C realtime clock (RTC) with an integrated temperature compensated crystal oscillator (TCXO) and crystal.  The device incorporates a battery input, and maintains accurate timekeeping when main power to the device is interrupted.

  - 간단하게 해석하자면 온도 보상 발진기가 포함된 저비용, 정확한 I2C 클럭을 이용하며 메인 전원이 나가면 배터리가 입력 전원으로 시간을 유지한다.

 

 <특  징>

  - Battery Backup Input for Continuous Timekeeping

  - Operating Temperature Ranges Commercial: 0°C to +70°C

  - Real-Time Clock Counts Seconds, Minutes, Hours, Day, Date, Month, and Year with Leap Year   Compensation Valid Up to 2100

  - Two Time-of-Day Alarms

  - Programmable Square-Wave Output

  - Fast (400kHz) I2C Interface

  - 3.3V Operation

  - Digital Temp Sensor Output: ±3°C Accuracy

  - RST Output/Pushbutton Reset Debounce Input

     

3. 회로도 확인

 - 간단하게 전원과 I2C 통신선이 연결되어 있고 배터리로 전원단이 추가 연결되어 있습니다. 그리고  알람을 사용할 수 있는 핀(/INT, SQW)을 사용하지 않아서 테스트할 수 없어 조금 아쉬웠습니다.

 

- DS3231에 I2C로 접근하는 주소는 0x68입니다.

회로도

4. 핀 연결하기

  - 전 편에서와 동일하게 I2C 핀으로 연결하면 됩니다.

 

I2C 핀 연결

 5. 소스 확인

  - wiringPi 소스로 확인해보겠습니다. (bcm2835, python 소스도 형태는 비슷합니다.)

  - buf[] 값은 시간을 시간을 나타내는 값입니다. 왜 이렇게 값을 넣는가 하면 데이터 시트의 메모리 맵 구성 때문입니다.

  - 00h 주소를 시작으로 4비트, 3 비트 등으로 나누어 시간을 기록하도록 되어 있습니다.

 

  - 예를 들어 소스에서 처럼 0x47을 분(minutes)으로 기록한다면 헥사 값 4비트 7(0111)은 십진수 1의 자리 수를 가리키고, 4(0100)으로 입력되는 것입니다.   이런 형식으로 메모리 값에 저장하거나 읽어 옵니다.

 

DS3231 메모리 맵

   - pcf8563SetTime()는 I2C 통신으로 buf 값을 메모리에 저장하는 역할을 합니다.

  - pcf8563ReadTime()는 I2C 통신으로 현재시간 값을 읽어서 buf에 저장하는 역할을 합니다.

 

  - main 함수 내에 보면 pcf8563ReadTime() 후에

    buf[0] = buf[0]&0x7F;  이렇게 프로그래밍되어 있는데 이것은 위에서 본 메모리 맵에 맞게 필요한 부분만 뽑아내기 위해서입니다.

   0x7F라고 함은 이진수로 0111 1111이고 7비트의 값만 and 연산을 해서 끝의 BIT7 만 빼고 읽어 오겠다는 의미입니다.   그 밑의 부분도 비슷하다고 생각하시면 됩니다.

 

  -  buf에 저장한 값을 1초마다 출력합니다.

  

  < ds3231.c>

#include <wiringPi.h>
#include <wiringPiI2C.h>
#include <stdio.h>

#define DS3231_Address 0x68
//seconds,minutes,hours,weekdays,days,months,yeas
char  buf[]={0x00,0x47,0x11,0x05,0x19,0x06,0x15};
char  *str[]  ={"SUN","Mon","Tues","Wed","Thur","Fri","Sat"};
int fd,i;

void pcf8563SetTime()
{
        for(i = 0;i < 7;i++)
        {
                wiringPiI2CWriteReg8(fd,i,buf[i]);
        }
}

void pcf8563ReadTime()
{
        for(i = 0;i < 7;i++)
        {
                buf[i] = (char)wiringPiI2CReadReg8(fd,i);
        }
}

int main(int argc, char **argv)
{
        if(wiringPiSetup() < 0)return 1;
        fd = wiringPiI2CSetup(DS3231_Address);
    printf("DS3231 Test Program ...\n\n");

    pcf8563SetTime();
    while(1)
    {
        pcf8563ReadTime();
                buf[0] = buf[0]&0x7F; //sec
                buf[1] = buf[1]&0x7F; //min
                buf[2] = buf[2]&0x3F; //hour
                buf[3] = buf[3]&0x07; //week
                buf[4] = buf[4]&0x3F; //day
                buf[5] = buf[5]&0x1F; //mouth
                //year/month/day
                printf("20%02x/%02x/%02x  ",buf[6],buf[5],buf[4]);
                //hour:minute/second
                printf("%02x:%02x:%02x  ",buf[2],buf[1],buf[0]);
                //weekday
                printf("%s\n",str[(unsigned char)buf[3]]);
                delay(1000);
        }
    return 0;
}

 

  < Makefile>

ds3231:ds3231.c
        gcc -Wall ds3231.c -o ds3231 -lwiringPi
clean:
        rm ds3231

 

6. 동작 결과

  pi@raspberrypi:~/Pioneer600/DS3231/wiringPi $ make clean && make

  pi@raspberrypi:~/Pioneer600/DS3231/wiringPi $ ./ds3231

 

  - 2015년 06월 19일 초기화되어 표시되고 있습니다. 시작할 때마다 시간을 새롭게 메모리에 입력하기 때문에 동일한 날짜가 나오지만, 코인 건전지를 넣고 처음에만 날짜를 기록해주는 코딩만 해준다면 이후부터는 저장된 시간으로 표시됩니다.

 

  - 아쉬운 점은 소스상 함수명이 ds3231로 하지 않고 이전 코드를 복사해서 사용하다 보니 pcf8563이라고 되어있습니다. 그리고 알람 설정 핀이 활성화되어 있었다면 좀 더 활용성이 높지 않았을까 합니다.

 

실행결과

7. (참고) 코인 건전지 정보

  코인 건전지 정보 찾아보다가 간단하게 알고 있으면 도움이 될 것 같아 공유드립니다.

코인 건전지

  사실 코인 건전지를 볼일은 잘 없습니다. 시계 혹은 리모컨에 사용되고 OTP 같은 몇 번씩 사용하지 않는 제품들에 들어 있습니다.

  건전지가 사용 다하면 어떤 것으로 교체해야 하는지 모를 때가 많습니다. 보통 건전지에 제품번호 같은 것들이 있는데 이것만 이해하고 있으면 쉽게 선택할 수 있습니다. 글자가 보이지 않는다면 작은 자(Ruler)가 하나 있으면 좋습니다.

 

  다 사용한 건전지에 CR, SR, LR로 시작하는 글자와 숫자가 보일 것입니다.

앞은 영문은 C, S, L 은 배터리 화학성분을 말하고(전압), R은 Round라고 해서 둥근 형태라고 보시면 됩니다.

 

  그리고 제품에 따라 조금 차이가 있는데,  4개의 숫자를 가진다면 앞의 두 자리가 원의 지름을 나타내고 숫자가 3개 라면 한자리가 원의 지름이고 뒤의 두 숫자가 두께(높이)를 나타냅니다. 그래서 만약 코인 건전지에 글자가 보이지 않는다면 자로 측정해보면 어떤 타입을 구입하면 되는지 파악이 되실 겁니다. 그리고 사용되는 전압 확인 필요합니다.

 

<전기화학 시스템 - wikipedia, 단추형 전지>

  - 예로 Pioneer600 같은 경우 CR1220 이 사용되는데,  C : 리튬, R : Round, 12mm : 지름,  20mm : 높이

 로 해석하시면 됩니다. 즉, 3V 형  둥근 형태의 지름 12mm이고 두께 20mm 것을 구입하면 되는 것이죠.

 

감사합니다.

 

 

<참고 사이트>

1. 실시간 시계

https://ko.wikipedia.org/wiki/%EC%8B%A4%EC%8B%9C%EA%B0%84_%EC%8B%9C%EA%B3%84

2. 단추형 전지

https://ko.wikipedia.org/wiki/%EB%8B%A8%EC%B6%94%ED%98%95_%EC%A0%84%EC%A7%80

3. 동전 건전지 총정리 (원형 코인 배터리, 아기 장난감 동그란 밧데리 사이즈)

https://m.blog.naver.com/laheefkgml/221216993921  

4. DS3231 Datasheet

DS3231.pdf
0.29MB

 

 

"쿠팡 파트너스 활동을 통해 일정액의 수수료를 받을 수 있음"

Comments