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的溢出时间