Chapter 15 - Hongjayeong-02/Basic_SoC_implementation GitHub Wiki

15. Real-Time Clock (RTC)

Goal

STM32F439ZI์˜ RTC peripheral์„ LSI clock์œผ๋กœ ๋™์ž‘์‹œํ‚ค๊ณ , ํ˜„์žฌ ์‹œ๊ฐ„๊ณผ ๋‚ ์งœ๋ฅผ UART๋กœ ์ถœ๋ ฅํ•œ๋‹ค.

์ด๋ฒˆ ์‹ค์Šต:

LSI
 โ†“
RTC Clock
 โ†“
Prescaler
 โ†“
1 Hz Calendar Clock
 โ†“
RTC Time / Date
 โ†“
UART
 โ†“
PC Terminal

์‹ค์ œ board์—์„œ ๋‹ค์Œ๊นŒ์ง€ ํ™•์ธํ–ˆ๋‹ค.

Time count     : PASS
1-second tick  : PASS
Date rollover  : PASS

09-19
  โ†“
09-20

1. RTC vs General-Purpose Timer

Ch09 TIM2:

System / Peripheral Clock
        โ†“
Timer Counter
        โ†“
Periodic Event

RTC:

Low-Speed Clock
      โ†“
Backup Domain
      โ†“
Calendar Hardware
      โ†“
Second / Minute / Hour
Day / Month / Year

RTC๋Š” ๋‹จ์ˆœ counter๊ฐ€ ์•„๋‹ˆ๋ผ ์‹œ๊ฐ„๊ณผ ๋‚ ์งœ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” calendar peripheral์ด๋‹ค.


2. Backup Domain

RTC๋Š” ์ผ๋ฐ˜ peripheral๊ณผ ๋‹ฌ๋ฆฌ Backup Domain์— ์กด์žฌํ•œ๋‹ค.

๋”ฐ๋ผ์„œ ๋ฐ”๋กœ register๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์—†๋‹ค.

๋จผ์ €:

PWR Clock Enable
       โ†“
DBP = 1
       โ†“
Backup Domain Write Access

์ˆœ์„œ๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

ํ•ต์‹ฌ:

RCC->APB1ENR |= PWREN;
PWR->CR |= CR_DBP;

3. RTC Clock Source

RTC๋Š” ์—ฌ๋Ÿฌ clock source๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

LSE
โ†’ External 32.768 kHz crystal

LSI
โ†’ Internal low-speed RC oscillator

HSE
โ†’ External high-speed clock division

์ด๋ฒˆ ์‹ค์Šต์—์„œ๋Š”:

LSI

๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

์žฅ์ :

External crystal ๋ถˆํ•„์š”
๋ฐฐ์„  ๋ถˆํ•„์š”
๊ฐ„๋‹จํ•œ ์‹ค์Šต์— ์ ํ•ฉ

๋‹จ์ :

LSE๋ณด๋‹ค ์ •ํ™•๋„๊ฐ€ ๋‚ฎ์Œ

์ฆ‰ ์‹ค์ œ ์ •๋ฐ€ RTC application์—์„œ๋Š” ๋ณดํ†ต LSE๊ฐ€ ๋” ์ ํ•ฉํ•˜๋‹ค.


4. RTC Clock Flow

์ด๋ฒˆ ์‹ค์Šต์˜ ์„ค์ •:

LSI โ‰ˆ 32 kHz
    โ†“
Asynchronous Prescaler
    โ†“
Synchronous Prescaler
    โ†“
โ‰ˆ 1 Hz
    โ†“
Calendar

์‚ฌ์šฉ๊ฐ’:

RTC_ASYNCH_PREDIV = 0x7F
                   = 127
                   โ†’ divide by 128

RTC_SYNCH_PREDIV  = 0x00F9
                   = 249
                   โ†’ divide by 250

๋”ฐ๋ผ์„œ:

128 ร— 250
=
32000

LSI๊ฐ€ ์•ฝ 32kHz๋ผ๋Š” ๊ฐ€์ •์— ๋งž์ถ˜ ์„ค์ •์ด๋‹ค.


5. Important Registers

Register ์—ญํ• 
RTC->TR Hour / Minute / Second
RTC->DR Year / Month / Day / Weekday
RTC->CR RTC control / format
RTC->ISR Initialization / synchronization status
RTC->PRER Async / Sync prescaler
RTC->WPR Write protection
RCC->CSR LSI enable / ready
RCC->BDCR RTC clock select / RTC enable
PWR->CR Backup domain write access

6. BCD

RTC์˜ ์‹œ๊ฐ„๊ณผ ๋‚ ์งœ๋Š” ์ผ๋ฐ˜ binary integer๊ฐ€ ์•„๋‹ˆ๋ผ BCD ํ˜•ํƒœ๋กœ ์ €์žฅ๋œ๋‹ค.

์˜ˆ:

Decimal 59

์ผ๋ฐ˜ binary:

0x3B

BCD:

0x59

BCD์—์„œ๋Š” ๊ฐ decimal digit์„ 4bit์”ฉ ์ €์žฅํ•œ๋‹ค.

5 โ†’ 0101
9 โ†’ 1001

59
โ†’ 0101 1001
โ†’ 0x59

๋”ฐ๋ผ์„œ RTC register์—:

0x59

๊ฐ€ ๋ณด์ด๋ฉด ์‹ค์ œ ๊ฐ’:

59

๋กœ ์ฝ์„ ์ˆ˜ ์žˆ๋‹ค.


7. BCD to Decimal

์›๋ณธ ์‹ค์Šต ์ฝ”๋“œ:

uint8_t rtc_convert_bcd2dec(uint8_t value)
{
    return (uint8_t)(((value >> 4U) * 10U)
                     + (value & 0x0FU));
}

์˜ˆ:

value = 0x59

์ƒ์œ„ nibble:

0x5 ร— 10
=
50

ํ•˜์œ„ nibble:

0x9
=
9

๊ฒฐ๊ณผ:

50 + 9
=
59

8. RTC Write Protection

RTC ์ฃผ์š” register๋Š” ์‹ค์ˆ˜๋กœ ๋ณ€๊ฒฝ๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด write protection์ด ๊ฑธ๋ ค ์žˆ๋‹ค.

Unlock sequence:

RTC->WPR = 0xCA;
RTC->WPR = 0x53;

์ˆœ์„œ๊ฐ€ ์ค‘์š”ํ•˜๋‹ค.

0xCA
 โ†“
0x53
 โ†“
RTC Write Protection Disabled

์„ค์ •์ด ๋๋‚œ ํ›„:

RTC->WPR = 0xFF;

๋กœ write protection์„ ๋‹ค์‹œ ํ™œ์„ฑํ™”ํ•œ๋‹ค.


9. Practice Code Status

ํ˜„์žฌ Notion์— ์ „์ฒด๊ฐ€ ๋ช…ํ™•ํžˆ ๋‚จ์•„ ์žˆ๋Š” ํ•ต์‹ฌ:

rtc_init()
rtc_convert_bcd2dec()
main()

๋‹ค์Œ helper๋Š” ํ˜ธ์ถœ ๊ตฌ์กฐ์™€ ์—ญํ• ์€ ๋‚จ์•„ ์žˆ์ง€๋งŒ ์ „์ฒด ํ•จ์ˆ˜ ๋ณธ๋ฌธ์€ ํ˜„์žฌ ๊ธฐ๋ก์— ๋ณด์กด๋˜์–ด ์žˆ์ง€ ์•Š๋‹ค.

rtc_init_seq()
exit_init_seq()

rtc_date_config()
rtc_time_config()

rtc_set_asynch_prescaler()
rtc_set_synch_prescaler()

display_rtc_calendar()

๋”ฐ๋ผ์„œ ์—†๋Š” ์›๋ณธ ์ฝ”๋“œ๋ฅผ ์ž„์˜๋กœ ๋งŒ๋“ค์–ด ๋„ฃ์ง€๋Š” ์•Š๋Š”๋‹ค.


10. rtc.h

#ifndef RTC_H__
#define RTC_H__

#include <stdint.h>
#include "stm32f4xx.h"

/*
 * Initialize RTC using the LSI clock.
 */
void rtc_init(void);


/*
 * Convert one BCD encoded value
 * into normal decimal integer form.
 *
 * Example:
 *
 *     0x59 โ†’ 59
 */
uint8_t rtc_convert_bcd2dec(uint8_t value);


/*
 * Read RTC time/date registers and
 * print current calendar data through UART.
 *
 * Full archived implementation body
 * is not currently available.
 */
void display_rtc_calendar(void);

#endif

11. RTC Definitions

#include "rtc.h"

/*
 * ============================================================
 * RCC / PWR Control Bits
 * ============================================================
 */

/*
 * APB1 PWR peripheral clock enable.
 */
#define PWREN               (1U << 28)


/*
 * PWR CR DBP:
 *
 * Enable write access to Backup Domain.
 */
#define CR_DBP              (1U << 8)


/*
 * RCC CSR LSION:
 *
 * Enable internal low-speed oscillator.
 */
#define CSR_LSION           (1U << 0)


/*
 * RCC CSR LSIRDY:
 *
 * Indicates LSI oscillator is stable.
 */
#define CSR_LSIRDY          (1U << 1)


/*
 * Backup Domain Reset.
 */
#define BDCR_BDRST          (1U << 16)


/*
 * RTC Enable.
 */
#define BDCR_RTCEN          (1U << 15)


/*
 * ============================================================
 * RTC Write Protection
 * ============================================================
 */

#define RTC_WRITE_PROTECTION_KEY_1   0xCAU
#define RTC_WRITE_PROTECTION_KEY_2   0x53U


/*
 * ============================================================
 * Prescaler
 * ============================================================
 */

#define RTC_ASYNCH_PREDIV   0x7FU
#define RTC_SYNCH_PREDIV    0x00F9U

12. rtc_init()

void rtc_init(void)
{
    /*
     * --------------------------------------------------------
     * Step 1. Enable PWR Peripheral Clock
     * --------------------------------------------------------
     *
     * RTC belongs to the Backup Domain.
     *
     * Backup-domain write permission is controlled
     * through the PWR peripheral.
     */
    RCC->APB1ENR |= PWREN;


    /*
     * --------------------------------------------------------
     * Step 2. Enable Backup Domain Write Access
     * --------------------------------------------------------
     *
     * DBP = Disable Backup-domain Protection.
     *
     * DBP = 1
     *
     * allows RTC / backup domain registers
     * to be modified.
     */
    PWR->CR |= CR_DBP;


    /*
     * --------------------------------------------------------
     * Step 3. Enable LSI
     * --------------------------------------------------------
     *
     * LSI:
     *
     *     Low-Speed Internal RC oscillator
     *
     * Used as the RTC source in this project.
     */
    RCC->CSR |= CSR_LSION;


    /*
     * --------------------------------------------------------
     * Step 4. Wait Until LSI Is Stable
     * --------------------------------------------------------
     *
     * LSIRDY = 1
     *
     * means the LSI oscillator is ready.
     *
     * RTC clock should not be configured until
     * the selected source clock is stable.
     */
    while ((RCC->CSR & CSR_LSIRDY) != CSR_LSIRDY)
    {
    }


    /*
     * --------------------------------------------------------
     * Step 5. Reset Backup Domain
     * --------------------------------------------------------
     *
     * BDRST = 1
     *
     * resets RTC / backup-domain configuration.
     */
    RCC->BDCR |= BDCR_BDRST;


    /*
     * Release reset.
     */
    RCC->BDCR &= ~BDCR_BDRST;


    /*
     * --------------------------------------------------------
     * Step 6. Select LSI as RTC Clock
     * --------------------------------------------------------
     *
     * RTCSEL field is configured to:
     *
     *     10b
     *
     * for LSI.
     *
     * Existing code performs this by:
     *
     * bit8 = 0
     * bit9 = 1
     */
    RCC->BDCR &= ~(1U << 8);
    RCC->BDCR |=  (1U << 9);


    /*
     * --------------------------------------------------------
     * Step 7. Enable RTC
     * --------------------------------------------------------
     */
    RCC->BDCR |= BDCR_RTCEN;


    /*
     * --------------------------------------------------------
     * Step 8. Disable RTC Write Protection
     * --------------------------------------------------------
     *
     * Hardware-defined unlock sequence:
     *
     *     0xCA
     *       โ†“
     *     0x53
     */
    RTC->WPR = RTC_WRITE_PROTECTION_KEY_1;
    RTC->WPR = RTC_WRITE_PROTECTION_KEY_2;


    /*
     * --------------------------------------------------------
     * Step 9. Enter RTC Initialization Mode
     * --------------------------------------------------------
     *
     * RTC calendar registers must be configured
     * while the RTC is in initialization mode.
     *
     * Full helper body is not preserved
     * in the current archive.
     */
    rtc_init_seq();


    /*
     * --------------------------------------------------------
     * Step 10. Configure Date
     * --------------------------------------------------------
     *
     * Existing practice value:
     *
     *     Weekday : Friday
     *     Date    : 19
     *     Month   : 09
     *     Year    : 26
     *
     * Values are BCD encoded.
     */
    rtc_date_config(
        WEEKDAY_FRIDAY,
        0x19,
        0x09,
        0x26
    );


    /*
     * --------------------------------------------------------
     * Step 11. Configure Time
     * --------------------------------------------------------
     *
     * Existing practice:
     *
     *     11:59:55 PM
     *
     * Starting close to midnight allows
     * date rollover to be tested quickly.
     */
    rtc_time_config(
        TIME_FORMAT_PM,
        0x11,
        0x59,
        0x55
    );


    /*
     * --------------------------------------------------------
     * Step 12. RTC Time Format
     * --------------------------------------------------------
     *
     * IMPORTANT:
     *
     * The archived Notion source contains:
     *
     *     RTC->CR |= CR_FMT;
     *
     * together with the comment "24-hour format".
     *
     * However the same source calls:
     *
     *     TIME_FORMAT_PM
     *
     * so the archived notes are internally inconsistent
     * regarding 12-hour / 24-hour format.
     *
     * Keep this as a re-test item and verify CR.FMT
     * against the STM32F439 RTC Reference Manual
     * before finalizing the driver.
     */
    RTC->CR |= CR_FMT;


    /*
     * --------------------------------------------------------
     * Step 13. Configure Asynchronous Prescaler
     * --------------------------------------------------------
     *
     * 0x7F = 127
     *
     * Actual division:
     *
     *     127 + 1
     *     = 128
     */
    rtc_set_asynch_prescaler(
        RTC_ASYNCH_PREDIV
    );


    /*
     * --------------------------------------------------------
     * Step 14. Configure Synchronous Prescaler
     * --------------------------------------------------------
     *
     * 0xF9 = 249
     *
     * Actual division:
     *
     *     249 + 1
     *     = 250
     */
    rtc_set_synch_prescaler(
        RTC_SYNCH_PREDIV
    );


    /*
     * --------------------------------------------------------
     * Step 15. Exit Initialization Mode
     * --------------------------------------------------------
     *
     * Calendar counting starts/resumes.
     *
     * Helper also waits for register synchronization
     * in the original experiment flow.
     */
    exit_init_seq();


    /*
     * --------------------------------------------------------
     * Step 16. Re-enable RTC Write Protection
     * --------------------------------------------------------
     */
    RTC->WPR = 0xFF;
}

13. Why Start at 11:59:55 PM?

์ด ๊ฐ’์€ ์ž„์˜๋กœ ๊ณ ๋ฅธ ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๋‚ ์งœ rollover๋ฅผ ๋น ๋ฅด๊ฒŒ ๊ฒ€์ฆํ•˜๊ธฐ ์œ„ํ•ด ์œ ๋ฆฌํ•œ test condition์ด๋‹ค.

11:59:55 PM
 โ†“
11:59:56
 โ†“
11:59:57
 โ†“
11:59:58
 โ†“
11:59:59
 โ†“
12:00:00

๋™์‹œ์— ๋‚ ์งœ:

09-19
  โ†“
09-20

์ด ๋˜๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

์ฆ‰ ๋‹จ์ˆœํžˆ RTC๊ฐ€ ์ฆ๊ฐ€ํ•˜๋Š” ๊ฒƒ๋ฟ ์•„๋‹ˆ๋ผ:

Second rollover
Minute rollover
Hour rollover
Date rollover

๋ฅผ ํ•œ ๋ฒˆ์— ๊ฒ€์ฆํ•  ์ˆ˜ ์žˆ๋‹ค.


14. Initialization Mode

RTC๋Š” ๊ณ„์† ์‹œ๊ฐ„์„ countํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— calendar register๋ฅผ ๋™์ž‘ ์ค‘์— ์•„๋ฌด ๋•Œ๋‚˜ ์ˆ˜์ •ํ•˜๋ฉด ์•ˆ ๋œ๋‹ค.

์„ค์ • ๊ณผ์ •:

Normal RTC Operation
        โ†“
Enter Init Mode
        โ†“
Calendar Counter Paused
        โ†“
Configure
TR / DR / PRER / CR
        โ†“
Exit Init Mode
        โ†“
RTC Counting Starts

์ด ๊ณผ์ •์„ helper:

rtc_init_seq()
exit_init_seq()

๊ฐ€ ๋‹ด๋‹นํ•œ๋‹ค.


15. Why Wait for Flags?

Bare-metal peripheral initialization์—์„œ๋Š”:

Write configuration

๋งŒ ํ•˜๊ณ  ๋ฐ”๋กœ ๋‹ค์Œ ๋‹จ๊ณ„๋กœ ๋„˜์–ด๊ฐ€๋ฉด ์•ˆ ๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๋‹ค.

์˜ˆ:

RCC->CSR |= CSR_LSION;

while ((RCC->CSR & CSR_LSIRDY)
       != CSR_LSIRDY)
{
}

์ด๋Š”:

LSI Enable
   โ†“
Oscillator starting...
   โ†“
Not Ready
   โ†“
Not Ready
   โ†“
LSIRDY = 1
   โ†“
Continue

๋ผ๋Š” hardware synchronization ๊ณผ์ •์ด๋‹ค.

์ด ํŒจํ„ด์€ ์ดํ›„์—๋„ ๋ฐ˜๋ณต๋œ๋‹ค.

Enable
 โ†“
Wait Ready Flag
 โ†“
Configure Next Stage

16. rtc_convert_bcd2dec()

uint8_t rtc_convert_bcd2dec(uint8_t value)
{
    /*
     * Upper nibble contains the tens digit.
     *
     * Example:
     *
     *     0x59 >> 4
     *     =
     *     0x05
     *
     *     5 ร— 10
     *     =
     *     50
     */
    uint8_t tens =
        (uint8_t)((value >> 4U) * 10U);


    /*
     * Lower nibble contains the ones digit.
     *
     *     0x59 & 0x0F
     *     =
     *     9
     */
    uint8_t ones =
        (uint8_t)(value & 0x0FU);


    /*
     * 50 + 9 = 59
     */
    return (uint8_t)(tens + ones);
}

์›๋ณธ์˜ ํ•œ ์ค„ ํ˜•ํƒœ:

return (uint8_t)(((value >> 4U) * 10U)
                 + (value & 0x0FU));

๊ณผ ๋™์ผํ•œ ๋™์ž‘์ด๋‹ค.


17. main.c

#include "rtc.h"
#include "uart.h"
#include "systick.h"

int main(void)
{
    /*
     * --------------------------------------------------------
     * Step 1. Initialize UART
     * --------------------------------------------------------
     *
     * Current RTC date/time is printed
     * through USART3.
     */
    uart_init();


    /*
     * --------------------------------------------------------
     * Step 2. Initialize RTC
     * --------------------------------------------------------
     *
     * RTC setup:
     *
     *     Clock Source โ†’ LSI
     *     Prescaler
     *     Date
     *     Time
     */
    rtc_init();


    while (1)
    {
        /*
         * ----------------------------------------------------
         * Step 3. Read and Display RTC Calendar
         * ----------------------------------------------------
         *
         * Expected information:
         *
         *     Hour
         *     Minute
         *     Second
         *     Month
         *     Day
         *     Year
         *
         * The complete archived implementation of
         * display_rtc_calendar() is not currently
         * preserved in the source notes.
         */
        display_rtc_calendar();


        /*
         * ----------------------------------------------------
         * Step 4. Print Approximately Once Per Second
         * ----------------------------------------------------
         *
         * SysTick driver from Ch08 is reused.
         */
        systick_msec_delay(1000);
    }
}

18. Complete RTC Initialization Flow

rtc_init()
   โ”‚
   โ”œโ”€โ”€ PWR Clock Enable
   โ”‚
   โ”œโ”€โ”€ DBP = 1
   โ”‚
   โ”œโ”€โ”€ LSI Enable
   โ”‚
   โ”œโ”€โ”€ Wait LSIRDY
   โ”‚
   โ”œโ”€โ”€ Backup Domain Reset
   โ”‚
   โ”œโ”€โ”€ RTCSEL = LSI
   โ”‚
   โ”œโ”€โ”€ RTC Enable
   โ”‚
   โ”œโ”€โ”€ WPR Unlock
   โ”‚
   โ”œโ”€โ”€ Enter Init Mode
   โ”‚
   โ”œโ”€โ”€ Date Configure
   โ”‚
   โ”œโ”€โ”€ Time Configure
   โ”‚
   โ”œโ”€โ”€ Prescaler Configure
   โ”‚
   โ”œโ”€โ”€ Exit Init Mode
   โ”‚
   โ””โ”€โ”€ WPR Lock

19. Runtime Flow

LSI
 โ†“
RTC Prescaler
 โ†“
1-second Calendar Tick
 โ†“
TR / DR Update
 โ†“
display_rtc_calendar()
 โ†“
BCD โ†’ Decimal
 โ†“
UART
 โ†“
PC Terminal

20. TR โ€” Time Register

RTC time register stores:

Hours
Minutes
Seconds

๊ฐœ๋…์ ์œผ๋กœ:

TR
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Hour   โ”‚ Minute  โ”‚ Second  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๊ฐ field๋Š” BCD encoded value๋‹ค.

์˜ˆ:

11:59:55

์ด๋ฉด register field๋“ค์„ ์‚ฌ๋žŒ์ด hex๋กœ ๋ดค์„ ๋•Œ:

11
59
55

์ฒ˜๋Ÿผ ์ฝ๊ธฐ ์‰ฝ๋‹ค.


21. DR โ€” Date Register

RTC date register์—๋Š”:

Year
Month
Date
Weekday

์ •๋ณด๊ฐ€ ์ €์žฅ๋œ๋‹ค.

์ด๋ฒˆ ์ดˆ๊ธฐ๊ฐ’:

Year    = 0x26
Month   = 0x09
Date    = 0x19
Weekday = Friday

์ž์ •์ด ์ง€๋‚˜๋ฉด hardware calendar๊ฐ€ ์ž๋™์œผ๋กœ:

09-19
 โ†“
09-20

์œผ๋กœ ์ฆ๊ฐ€์‹œํ‚จ๋‹ค.


22. Shadow Register Note

RTC register read๋Š” ๋‚ด๋ถ€ shadow register์™€ ๊ด€๋ จ๋œ synchronization์ด ์กด์žฌํ•œ๋‹ค.

๊ธฐ์กด ์‹ค์Šต์—์„œ reset ์งํ›„ ์ˆœ๊ฐ„์ ์œผ๋กœ:

01-01-2000

์ฒ˜๋Ÿผ ์ดˆ๊ธฐ๊ฐ’์ด ํ‘œ์‹œ๋  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ธฐ๋ก์ด ์žˆ์—ˆ๋‹ค.

๊ทธ ํ›„ RTC register synchronization์ด ๋๋‚˜๋ฉด ์‹ค์ œ ์„ค์ •ํ•œ calendar ๊ฐ’์ด ํ‘œ์‹œ๋๋‹ค.

๋”ฐ๋ผ์„œ reset ์งํ›„ ํ•œ ๋ฒˆ์˜ ์ž˜๋ชป๋œ ํ™”๋ฉด๋งŒ ๋ณด๊ณ :

RTC initialization failed

๋ผ๊ณ  ๋ฐ”๋กœ ํŒ๋‹จํ•˜๋ฉด ์•ˆ ๋œ๋‹ค.


23. Important Re-Test Item โ€” CR.FMT

ํ˜„์žฌ ๋ณด์กด๋œ ์‹ค์Šต ์ฝ”๋“œ์—๋Š”:

rtc_time_config(
    TIME_FORMAT_PM,
    0x11,
    0x59,
    0x55
);

RTC->CR |= CR_FMT;

๊ฐ€ ์žˆ๊ณ , ๊ธฐ์กด ์ฃผ์„์€:

24์‹œ๊ฐ„์ œ

๋ผ๊ณ  ๋˜์–ด ์žˆ๋‹ค.

ํ•˜์ง€๋งŒ:

TIME_FORMAT_PM

์ด๋ผ๋Š” ์„ค์ •๊ณผ ๊ฐ™์€ ์ฝ”๋“œ ์•ˆ์— ์กด์žฌํ•˜๋ฏ€๋กœ 12/24-hour format์— ๋Œ€ํ•œ ๊ธฐ๋ก์ด ๋‚ด๋ถ€์ ์œผ๋กœ ์ผ๊ด€๋˜์ง€ ์•Š๋Š”๋‹ค.

๋”ฐ๋ผ์„œ ์žฌ์‹ค์Šต ์‹œ ๋ฐ˜๋“œ์‹œ:

STM32F439 RTC CR.FMT definition

์„ Reference Manual์—์„œ ๋‹ค์‹œ ํ™•์ธํ•˜๊ณ  ์ตœ์ข… ์ฝ”๋“œ์˜:

FMT
AM/PM
Hour encoding

์„ ์ผ์น˜์‹œํ‚จ๋‹ค.

์ด ๋ถ€๋ถ„์€ ํ˜„์žฌ Wiki์—์„œ โ€œ๊ฒ€์ฆ ํ•„์š”โ€ ํ•ญ๋ชฉ์œผ๋กœ ๋‚จ๊ธด๋‹ค.


24. Build Result

๊ธฐ์กด ์‹ค์Šต:

Build    : PASS
Download : PASS
Run      : PASS

Program size:

text = 2260 bytes
data = 0 bytes
bss  = 2560 bytes

๊ฒฝ๊ณ  ์—†์ด build ์™„๋ฃŒ.


25. Board Result

์‹ค์ œ terminal์—์„œ:

Second
 โ†“
Second
 โ†“
Second

๊ฐ€ ์•ฝ 1์ดˆ์”ฉ ์ฆ๊ฐ€ํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ–ˆ๋‹ค.

๋˜ํ•œ:

09-19
11:59:59 PM

์ดํ›„:

09-20
12:00:00

์œผ๋กœ ๋‚ ์งœ๊ฐ€ ๋„˜์–ด๊ฐ€๋Š” ๊ฒƒ์„ ํ™•์ธํ–ˆ๋‹ค.

์ฆ‰:

Second increment PASS
Minute rollover PASS
Hour rollover PASS
Date rollover PASS

๋กœ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.


26. Verification

1. Build

make clean
make

Expected:

text = 2260
data = 0
bss  = 2560

2. LSI

Debugger:

RCC->CSR

ํ™•์ธ:

LSION  = 1
LSIRDY = 1

3. Backup Domain

ํ™•์ธ:

PWR->CR

Expected:

DBP = 1

initialization ์ค‘ backup domain access๊ฐ€ ํ—ˆ์šฉ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.


4. RTC Clock Source

ํ™•์ธ:

RCC->BDCR

ํ™•์ธํ•  ํ•ญ๋ชฉ:

RTCSEL
RTCEN

Expected:

RTC Clock Source = LSI
RTC Enable       = 1

5. Prescaler

ํ™•์ธ:

RTC->PRER

Expected:

Asynchronous = 0x7F
Synchronous  = 0x00F9

6. Time Register

Watch:

RTC->TR

์ดˆ๊ฐ€ ์ฆ๊ฐ€ํ•˜๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.

55
56
57
58
59
00

7. Date Register

์ž์ • ์ „:

RTC->DR
โ†’ 09-19

์ž์ • ํ›„:

RTC->DR
โ†’ 09-20

์ธ์ง€ ํ™•์ธํ•œ๋‹ค.


27. Screenshots to Add

images/ch15_build.png
images/ch15_lsi.png
images/ch15_rtc_registers.png
images/ch15_time_before_midnight.png
images/ch15_time_after_midnight.png
images/ch15_rollover_terminal.png

๊ฐ€์žฅ ์ค‘์š”ํ•œ evidence:

11:59:59 / 09-19
        โ†“
12:00:00 / 09-20

terminal ํ™”๋ฉด์ด๋‹ค.

์ด ํ•œ ์žฅ์ด:

RTC counting
+
Time rollover
+
Calendar rollover

๋ฅผ ๋™์‹œ์— ๋ณด์—ฌ์ค€๋‹ค.


28. Key Points

LSI
 โ†“
Backup Domain
 โ†“
RTC
 โ†“
Prescaler
 โ†“
Calendar
 โ†“
BCD Time / Date
 โ†“
UART
  • RTC๋Š” ์ผ๋ฐ˜ timer์™€ ๋‹ฌ๋ฆฌ calendar hardware๋‹ค.
  • RTC๋Š” Backup Domain์— ์กด์žฌํ•œ๋‹ค.
  • RTC register๋ฅผ ์ˆ˜์ •ํ•˜๋ ค๋ฉด DBP๋กœ backup domain write access๋ฅผ ํ—ˆ์šฉํ•ด์•ผ ํ•œ๋‹ค.
  • ์ด๋ฒˆ ์‹ค์Šต์€ LSI๋ฅผ RTC clock source๋กœ ์‚ฌ์šฉํ•œ๋‹ค.
  • LSI๋ฅผ enableํ•œ ํ›„ LSIRDY๋ฅผ ๊ธฐ๋‹ค๋ฆฐ๋‹ค.
  • RTC register write ์ „ 0xCA โ†’ 0x53 key sequence๋กœ write protection์„ ํ•ด์ œํ•œ๋‹ค.
  • RTC ์„ค์ •์€ initialization mode์—์„œ ์ˆ˜ํ–‰ํ•œ๋‹ค.
  • TR์€ time, DR์€ date๋ฅผ ์ €์žฅํ•œ๋‹ค.
  • RTC ๊ฐ’์€ BCD ํ˜•์‹์œผ๋กœ ์ €์žฅ๋œ๋‹ค.
  • 0x59 BCD๋Š” decimal 59๋ฅผ ์˜๋ฏธํ•œ๋‹ค.
  • Prescaler๋Š” 0x7F / 0x00F9 ์„ค์ •์„ ์‚ฌ์šฉํ–ˆ๋‹ค.
  • ์‹ค์ œ board์—์„œ 1์ดˆ ์ฆ๊ฐ€์™€ 09-19 โ†’ 09-20 ๋‚ ์งœ rollover๋ฅผ ๊ฒ€์ฆ ์™„๋ฃŒํ–ˆ๋‹ค.
  • ๊ธฐ์กด ๊ธฐ๋ก์˜ CR.FMT์™€ TIME_FORMAT_PM ์กฐํ•ฉ์€ ์žฌ์‹ค์Šต ์‹œ ๋‹ค์‹œ ํ™•์ธํ•ด์•ผ ํ•œ๋‹ค.
โš ๏ธ **GitHub.com Fallback** โš ๏ธ