GD32固件库学习(八)—F4xx系列定时器时钟配置

前言

定时器作为收集和处理数据的重要参考标准,相关配置应当尽可能准确,以前看了又忘了,借着整理代码的机会记录一下

GD32的时钟树

在用户手册中看到GD32时钟树如下所示:

找到需要配置的外设部分,如下图红框部分所示:

系统时钟、AHB、APB2和APB1的时钟频率

AHB 和 APB2/APB1 域的最高时率分别为 240 MHz/120 MHz/60 MHz,TIMER时钟由AHB时钟分频获得,它的频率可以
等于CK_APBx、CK_APBx的两倍或CK_APBx的四倍。

系统时钟定义代码

取消不同的注释可以获得不同频率的系统时钟代码

/* select a system clock by uncommenting the following line */
//#define __SYSTEM_CLOCK_IRC16M                   (uint32_t)(__IRC16M)
//#define __SYSTEM_CLOCK_HXTAL                    (uint32_t)(__HXTAL)
//#define __SYSTEM_CLOCK_120M_PLL_IRC16M          (uint32_t)(120000000)
//#define __SYSTEM_CLOCK_120M_PLL_8M_HXTAL        (uint32_t)(120000000)
//#define __SYSTEM_CLOCK_120M_PLL_25M_HXTAL       (uint32_t)(120000000)
//#define __SYSTEM_CLOCK_168M_PLL_IRC16M          (uint32_t)(168000000)
//#define __SYSTEM_CLOCK_168M_PLL_8M_HXTAL        (uint32_t)(168000000)
//#define __SYSTEM_CLOCK_168M_PLL_25M_HXTAL       (uint32_t)(168000000)
//#define __SYSTEM_CLOCK_200M_PLL_IRC16M          (uint32_t)(200000000)
//#define __SYSTEM_CLOCK_200M_PLL_8M_HXTAL        (uint32_t)(200000000)
#define __SYSTEM_CLOCK_200M_PLL_25M_HXTAL       (uint32_t)(200000000)
//#define __SYSTEM_CLOCK_240M_PLL_IRC16M          (uint32_t)(240000000)
//#define __SYSTEM_CLOCK_240M_PLL_8M_HXTAL        (uint32_t)(240000000)
//#define __SYSTEM_CLOCK_240M_PLL_25M_HXTAL       (uint32_t)(240000000)

这里我选择的是200MHz

AHB、APB1、APB2时钟域

    /* HXTAL is stable */
    /* AHB = SYSCLK */
    RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
    /* APB2 = AHB/2 */
    RCU_CFG0 |= RCU_APB2_CKAHB_DIV2;
    /* APB1 = AHB/4 */
    RCU_CFG0 |= RCU_APB1_CKAHB_DIV4;

由此可得的
AHB=200MHz,
APB1=50MHz,
APB2=100MHz,

Timer分频

CK_APBx的频率已经得到,GD32所有的定时器都挂在这两个下面,定时器1挂在APB1下:

CK_APB1C乘以1或者2或者4得到定时器时钟频率(在F1系列中,非1即2);
因此这里我们的时钟频率将会是50Mhz乘以上面的系数,

Timer时钟源选择

/*利用以下函数实现定时器时钟源的配置*/
rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);

这里的参数可以是RCU_TIMER_PSC_MUL2,也可以是RCU_TIMER_PSC_MUL4,
如果是RCU_TIMER_PSC_MUL2:
如果 RCU_CFG0 寄存器的 APB1PSC/APB2PSC 位域的值为 0b0xx(CK_APBx= CK_AHB)或 0b100(CK_APBx = CK_AHB/2),
定时器时钟等于 CK_AHB(CK_TIMERx = CK_AHB),否则定时器时钟等于 APB 时钟的两倍(在 APB1 域的定时器:
CK_TIMERx = 2 x CK_APB1,在 APB2 域的定时器:CK_TIMERx = 2x CK_APB2)。

如果是RCU_TIMER_PSC_MUL4:
如果 RCU_CFG0 寄存器的 APB1PSC/APB2PSC 位域的值为 0b0xx(CK_APBx
= CK_AHB),0b100(CK_APBx = CK_AHB/2),或 0b101(CK_APBx = CK_AHB/4),
定时器时钟等于 CK_AHB(CK_TIMERx = CK_AHB)。否则定时器时钟等于 APB
时钟的四倍(在 APB1 域的定时器:CK_TIMERx = 4 x CK_APB1;在 APB2 域的定
时器:CK_TIMERx = 4 x CK_APB2)。

显然这里我们应当配置为RCU_TIMER_PSC_MUL4,则定时器时钟频率应当为:
\(CK_{TIMER1}=4\times CK_{APB1} =200MHz\)

定时器溢出时间计算

$T_{out}=\frac{((arr+1)*(psc+1))}{T_{clk}} $

    timer_initpara.prescaler         = 199;
    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
    timer_initpara.counterdirection  = TIMER_COUNTER_UP;
    timer_initpara.period            = 999;//counter 999
    timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;

分频系数参照如下,即可实现1ms的溢出时间

posted @ 2023-02-07 15:38  Phoenix-Tree  阅读(899)  评论(0编辑  收藏  举报