[应用相关] 如何在 AT32F403A, AT32F407, AT32F403, AT32F413, AT32F415, AT32F421 获得 毫秒计时?

[复制链接]
 楼主| 菜鸟的第一步 发表于 2025-3-25 11:01 | 显示全部楼层 |阅读模式
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 设置:

  1. typedef struct
  2. {
  3. __IO uint8_t hour; /*!< specifies the hours of calendar. */
  4. __IO uint8_t min; /*!< specifies the minutes of calendar. */
  5. __IO uint8_t sec; /*!< specifies the second of calendar. */
  6. __IO uint16_t msec; /*!< specifies the millisecond of calendar. */
  7. } calendar_type;
  8. calendar_type time_struct;
  9. /* config calendar */
  10. time_struct.hour = 12;
  11. time_struct.min = 0;
  12. time_struct.sec = 0;
  13. time_struct.msec = 100;
  14. rtc_init(&time_struct);
  15. uint8_t rtc_init(calendar_type *calendar)
  16. {
  17. /* enable pwc and bpr clocks */
  18. crm_periph_clock_enable(CRM_PWC_PERIPH_CLOCK, TRUE);
  19. crm_periph_clock_enable(CRM_BPR_PERIPH_CLOCK, TRUE);
  20. /* enable the battery-powered domain write operations */
  21. pwc_battery_powered_domain_access(TRUE);
  22. /* reset battery-powered domain register */
  23. bpr_reset();
  24. /* enable the lext osc */
  25. crm_clock_source_enable(CRM_CLOCK_SOURCE_LEXT, TRUE);
  26. /* wait lext is ready */
  27. while(crm_flag_get(CRM_LEXT_STABLE_FLAG) == RESET);
  28. /* select the rtc clock source */
  29. crm_rtc_clock_select(CRM_RTC_CLOCK_LEXT);
  30. /* enable rtc clock */
  31. crm_rtc_clock_enable(TRUE);
  32. /* wait for rtc registers update */
  33. rtc_wait_update_finish();
  34. /* wait for the register write to complete */
  35. rtc_wait_config_finish();

  36. /* set rtc divider: set rtc period to 1sec */
  37. rtc_divider_set(32);

  38. /* wait for the register write to complete */
  39. rtc_wait_config_finish();
  40. /* set time */
  41. rtc_time_set(calendar);
  42. /* writes data to bpr register */
  43. bpr_data_write(BPR_DATA1, 0x1234);

  44. return 1;
  45. }
AT32F415 ERTC 设置:
  1. void ertc_config(void)
  2. {
  3. /* enable the pwc clock interface */
  4. crm_periph_clock_enable(CRM_PWC_PERIPH_CLOCK, TRUE);

  5. /* allow access to ertc */
  6. pwc_battery_powered_domain_access(TRUE);
  7. /* reset ertc domain */
  8. crm_battery_powered_domain_reset(TRUE);
  9. crm_battery_powered_domain_reset(FALSE);

  10. #if defined (ERTC_CLOCK_SOURCE_LICK)
  11. /* enable the lick osc */
  12. crm_clock_source_enable(CRM_CLOCK_SOURCE_LICK, TRUE);
  13. /* wait till lick is ready */
  14. while(crm_flag_get(CRM_LICK_STABLE_FLAG) == RESET)
  15. {
  16. }
  17. /* select the ertc clock source */
  18. crm_ertc_clock_select(CRM_ERTC_CLOCK_LICK);

  19. /* ertc second(1hz) = ertc_clk(lick) / (ertc_clk_div_a + 1) * (ertc_clk_div_b + 1) */
  20. ertc_clk_div_b = 999;
  21. ertc_clk_div_a = 32;
  22. #elif defined (ERTC_CLOCK_SOURCE_LEXT)
  23. /* enable the lext osc */
  24. crm_clock_source_enable(CRM_CLOCK_SOURCE_LEXT, TRUE);
  25. /* wait till lext is ready */
  26. while(crm_flag_get(CRM_LEXT_STABLE_FLAG) == RESET)
  27. {
  28. }
  29. /* select the ertc clock source */
  30. crm_ertc_clock_select(CRM_ERTC_CLOCK_LEXT);
  31. /* ertc second(1hz) = ertc_clk / (ertc_clk_div_a + 1) * (ertc_clk_div_b + 1) */
  32. ertc_clk_div_b = 999;
  33. ertc_clk_div_a = 32;
  34. #endif
  35. /* enable the ertc clock */
  36. crm_ertc_clock_enable(TRUE);
  37. /* deinitializes the ertc registers */
  38. ertc_reset();
  39. /* wait for ertc registers update */
  40. ertc_wait_update();

  41. /* configure the ertc divider */
  42. ertc_divider_set(ertc_clk_div_a, ertc_clk_div_b);

  43. /* configure the ertc hour mode */
  44. ertc_hour_mode_set(ERTC_HOUR_MODE_24);

  45. /* set date: 2021-05-01 */
  46. ertc_date_set(21, 5, 1, 5);

  47. /* set time: 12:00:00 */
  48. ertc_time_set(12, 0, 0, ERTC_AM);
  49. /* indicator for the ertc configuration */
  50. ertc_bpr_data_write(ERTC_DT1, 0x1234);
  51. }
需注意以下事项:
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 )。
9633467e21c5f4afc4.png
4. 实际示波器测试和打印结果
8307567e21c70d272c.png
您需要登录后才可以回帖 登录 | 注册

本版积分规则

60

主题

459

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部

60

主题

459

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部