Telink 时钟模块
系统时钟(systemclock)是 MCU 执⾏程序的时钟
系统定时器(SystemTimer)是⼀个只读的定时器,为BLE的时序控制提供时间基准,同时也可以提供给⽤⼾ 使⽤。
在Telink 上⼀代IC(826x系列)上,SystemTimer的时钟来源于systemclock,⽽B85m系列IC上,System Timer 和 system clock 是独⽴分开的。如下图所⽰,SystemTimer是由外部24MCrystalOscillator 经 3/2 分 频得到的16M。
图上可以看到,system clock 可以由外部 24M 晶体振荡器经“doubler”电路倍频到 48M 后再分频得到 16M、 24M、32M、48M等,这⼀类clock我们称为crystalclock(如16Mcrystal system clock、24M crystal system clock);也可以由 IC 内部24MRCOscillator 处理后得到24MRCclock、32M RC clock、48M RC clock 等。这 ⼀类我们称为RCclock(BLESDK不⽀持RCclock)
上面可以看出:
1. system timer 和system clock 不一样,用户需要了解MCU上各个硬件模块的clock是来自于system clock 还是system tick。我们以system clock 为 24M crystal 的情况来进⾏说明,此时system clock 为 24M,⽽ System Timer 是 16M。
在⽂件app_config.h 中 system clock 以及对应的 s、ms、us 的定义如下:
#define CLOCK_SYS_CLOCK_HZ 24000000enum{CLOCK_SYS_CLOCK_1S = CLOCK_SYS_CLOCK_HZ,CLOCK_SYS_CLOCK_1MS = (CLOCK_SYS_CLOCK_1S / 1000),CLOCK_SYS_CLOCK_1US = (CLOCK_SYS_CLOCK_1S / 1000000),};
System Timer 是固定的 16M,所以对于这个timer,SDKcode中使⽤如下的数值来表⽰s、ms和us。
//system timer clock source is constant 16M, never change
enum{ CLOCK_16M_SYS_TIMER_CLK_1S = 16000000, CLOCK_16M_SYS_TIMER_CLK_1MS = 16000, CLOCK_16M_SYS_TIMER_CLK_1US = 16,
}
由于SystemTimer 是 BLE 计时的基准,SDK中所有BLE时间相关的参数和变量,在涉及到时间的表达时,都 是⽤”CLOCK_16M_SYS_TIMER_CLK_xxx” 的方式。
System Timer 的使⽤
System Timer tick 的读取可以通过 clock_time() 函数获得:
u32 current_tick = clock_time();
BLE SDK 整个BLE 时序都是基于SystemTimer tick 设计的,程序中也⼤量使⽤这个SystemTimertick 来完 成各种计时和超时判断,强烈推荐user使⽤这个SystemTimertick来实现⼀些简单的定时和超时判断。
⽐如要实现⼀个简单的软件定时。软件定时器的实现基于查询机制,由于是通过查询来实现,不能保证⾮常好 的实时性和准备性,⼀般⽤于对误差要求不是特别苛刻的应⽤。实现⽅法: (1) 启动计时:设置⼀个u32的变量,读取并记录当前SystemTimertick。
u32 start_tick = clock_time(); // clock_time() returns System Timer tick value
假设需要定时的时间为100ms,查询计时是否到达的写法为:
if( (u32) ( clock_time()- start_tick) > 100 * CLOCK_16M_SYS_TIMER_CLK_1MS)
实际上SDK中为了解决系统时钟不同导致和u32转换的问题,提供了统⼀的调⽤函数,不管系统时钟多少,都 可以下⾯函数进⾏查询判断:
if( clock_time_exceed(start_tick, 100 * 1000)) //第⼆个参数单位为 us
需要注意的是:由于16MHz时钟转⼀圈为268秒,这个查询函数只适⽤于268秒以内的定时。如果超过268 秒,需要在软件上加计数器累计实现(这⾥不介绍)。 应⽤举例:A条件触发(只会触发⼀次)的2秒后,程序进⾏B()操作
u32 a_trig_tick;int a_trig_flg = 0;while(1){if(A){a_trig_tick = clock_time();a_trig_flg = 1;}if(a_trig_flg && clock_time_exceed(a_trig_tick,2 *1000 * 1000)){a_trig_flg = 0;B();}}
总结
Telink采用24MHz系统时钟 + 16MHz系统定时器这种不对称设计的主要原因:
功耗优化:16MHz RC振荡器比24MHz PLL方案功耗显著更低
精度需求:16MHz为定时器提供62.5ns分辨率,满足大多数应用需求
成本控制:避免为定时器也使用复杂的PLL时钟生成电路
系统稳定性:定时器使用独立时钟源,不受系统时钟调节影响
射频时序:16MHz更便于BLE等射频协议的精确时序控制
外设兼容性:24MHz便于生成各种标准外设时钟频率
这种设计在性能、功耗和成本之间取得了最佳平衡,特别适合物联网设备对低功耗和成本敏感的应用场景。