Example Code 请见雅特力官网示例代码《SC0007_AT32F4xx_RTC_毫秒计时》。 因 AT32F403A, AT32F407, AT32F403, AT32F413 的 RTC 硬 件 结 构 相 同 , 请 参 考 项 目 工 程AT32F403A_407_Firmware_Library。用 AT-START-F403 V1.2 下载验证时,请将 R7 焊上 0 欧电阻。因 AT32F415, AT32F421 的 ERTC 硬件结构相同,请参考项目工程 AT32F415_Firmware_Library。AT32F403A RTC 设置:
typedef struct
{
__IO uint8_t hour; /*!< specifies the hours of calendar. */
__IO uint8_t min; /*!< specifies the minutes of calendar. */
__IO uint8_t sec; /*!< specifies the second of calendar. */
__IO uint16_t msec; /*!< specifies the millisecond of calendar. */
} calendar_type;
calendar_type time_struct;
/* config calendar */
time_struct.hour = 12;
time_struct.min = 0;
time_struct.sec = 0;
time_struct.msec = 100;
rtc_init(&time_struct);
uint8_t rtc_init(calendar_type *calendar)
{
/* enable pwc and bpr clocks */
crm_periph_clock_enable(CRM_PWC_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(CRM_BPR_PERIPH_CLOCK, TRUE);
/* enable the battery-powered domain write operations */
pwc_battery_powered_domain_access(TRUE);
/* reset battery-powered domain register */
bpr_reset();
/* enable the lext osc */
crm_clock_source_enable(CRM_CLOCK_SOURCE_LEXT, TRUE);
/* wait lext is ready */
while(crm_flag_get(CRM_LEXT_STABLE_FLAG) == RESET);
/* select the rtc clock source */
crm_rtc_clock_select(CRM_RTC_CLOCK_LEXT);
/* enable rtc clock */
crm_rtc_clock_enable(TRUE);
/* wait for rtc registers update */
rtc_wait_update_finish();
/* wait for the register write to complete */
rtc_wait_config_finish();
/* set rtc divider: set rtc period to 1sec */
rtc_divider_set(32);
/* wait for the register write to complete */
rtc_wait_config_finish();
/* set time */
rtc_time_set(calendar);
/* writes data to bpr register */
bpr_data_write(BPR_DATA1, 0x1234);
return 1;
}
AT32F415 ERTC 设置:
void ertc_config(void)
{
/* enable the pwc clock interface */
crm_periph_clock_enable(CRM_PWC_PERIPH_CLOCK, TRUE);
/* allow access to ertc */
pwc_battery_powered_domain_access(TRUE);
/* reset ertc domain */
crm_battery_powered_domain_reset(TRUE);
crm_battery_powered_domain_reset(FALSE);
#if defined (ERTC_CLOCK_SOURCE_LICK)
/* enable the lick osc */
crm_clock_source_enable(CRM_CLOCK_SOURCE_LICK, TRUE);
/* wait till lick is ready */
while(crm_flag_get(CRM_LICK_STABLE_FLAG) == RESET)
{
}
/* select the ertc clock source */
crm_ertc_clock_select(CRM_ERTC_CLOCK_LICK);
/* ertc second(1hz) = ertc_clk(lick) / (ertc_clk_div_a + 1) * (ertc_clk_div_b + 1) */
ertc_clk_div_b = 999;
ertc_clk_div_a = 32;
#elif defined (ERTC_CLOCK_SOURCE_LEXT)
/* enable the lext osc */
crm_clock_source_enable(CRM_CLOCK_SOURCE_LEXT, TRUE);
/* wait till lext is ready */
while(crm_flag_get(CRM_LEXT_STABLE_FLAG) == RESET)
{
}
/* select the ertc clock source */
crm_ertc_clock_select(CRM_ERTC_CLOCK_LEXT);
/* ertc second(1hz) = ertc_clk / (ertc_clk_div_a + 1) * (ertc_clk_div_b + 1) */
ertc_clk_div_b = 999;
ertc_clk_div_a = 32;
#endif
/* enable the ertc clock */
crm_ertc_clock_enable(TRUE);
/* deinitializes the ertc registers */
ertc_reset();
/* wait for ertc registers update */
ertc_wait_update();
/* configure the ertc divider */
ertc_divider_set(ertc_clk_div_a, ertc_clk_div_b);
/* configure the ertc hour mode */
ertc_hour_mode_set(ERTC_HOUR_MODE_24);
/* set date: 2021-05-01 */
ertc_date_set(21, 5, 1, 5);
/* set time: 12:00:00 */
ertc_time_set(12, 0, 0, ERTC_AM);
/* indicator for the ertc configuration */
ertc_bpr_data_write(ERTC_DT1, 0x1234);
}
需注意以下事项:
1. 修改 RTC 设置时需修改写入备份域寄存器的值(如下代码),或者是断主电源的同时拨掉纽扣电池;bpr_data_write(BPR_DATA1, 0x1234);
2. 程序中 RTC 分频系数寄存器(RTC_DIVH/RTC_DIVL)设置时要实际计算值减 1,因为寄存器会自动加 1,时钟频率为 = fRTCCLK/(DIV[19:0]+1);ERTC 预分频器寄存器(ERTC_DIV) 设置时 DIVA/DIVB要实际计算值减 1, 因为寄存器会自动加 1,日历时钟=ERTC_CLK/((DIVA+1)x(DIVB+1))。
3. AT32F403A 与 AT32F415 获取毫秒的差别在于 AT32F403A 是通过分频,获得 1ms 时基,如下AT32F403A RTC 框图(最小可获得时基 61us); AT32F415 是在 1s 时基,通过亚秒寄存器(ERTC_SBS)获得同步分频值,如下 AT32F415 ERTC 框图,计算得到毫秒值 SBS = (DIVB - SBS ) / (DIVB + 1 )。
4. 实际示波器测试和打印结果
|