😊 转载请全文转载,并标明文章出处
环境介绍
- 操作系统: Window10 企业版
- IDE开发环境: ARM_MDK5 (Keil5)
- SDK版本: SDK_17.0.0
- 硬件开发板: 官方开发板 PCA10040
TIMER-Timer/Counter (定时器/计数器)
1. 概述介绍
定时器有两种模式:定时器 和 计数器。定时器和计数器内部结构框图如下:
不管使用什么 MCU 处理器,都必定含有定时器和计数器,针对Nordic芯片,nRF52xx系列的Timer定时器页十分强大,其内部含有5个定时器,Timer0、Timer1、Timer2、Timer3、Timer4。如果使用蓝牙的话,Timer0是被 BLE 占有的,所以只能使用后边4个定时器,Timer1、Timer2、Timer3、Timer4。
2. Timer / Counter 原理分析
2.1 Timer / Counter 定时器和计数器的区别
- 定时器和计数器实际都是通过计数器来计数。
- 定时器是对周期不变的脉冲计数 (一般来自系统时钟),由计数的个数和脉冲的周期即可计算出时间。同时,通过一个给定的预期值 (即比较值),当计数值达到预期值时产生中断,这实现了定时,应用程序通过设置不同的预期值实现不同时间的定时。
- 计数器时对某一事件进行计数,此事件没发生一次,计数值加/减1,事件的产生可能时没有规律的,计数器的用途是对事件发生的次数进行计数,由计数值来反映事件产生的次数。
2.2 Timer 时钟源
Timer时钟源主要来源是 PCLK1M 或 PCLK16M,系统会自动根据Timer时钟设置的频率 f 自动选择使用哪一种时钟源,时钟源的设置是无需软件操作的,当我们设置好Timer时钟频率后,系统会根据时钟频率自动选择时钟源。
f TIMER = 16MHz / 2PRESCALER
f TIMER > 1MHz,定时器使用 PCLK16M 作为时钟源。
f TIMER <= 1MHz,定时器使用 PCLK1M 代替 PCLK16M,降低功耗。
2.3 Timer 时钟频率
Timer 的时钟频率 f TIMER 计算公式: f TIMER = 16MHz / 2PRESCALER,无论时钟源使用的是 PCLK1M 或 PCLK16M ,时钟频率计算都以 16MHz 为基准。
分频系数 | 时钟频率 | 系统时钟源 |
---|---|---|
0 | 16MHz | PCLK16M |
1 | 8MHz | PCLK16M |
2 | 4MHz | PCLK16M |
3 | 2MHz | PCLK16M |
4 | 1MHz | PCLK1M |
5 | 500KHz | PCLK1M |
6 | 250KHz | PCLK1M |
7 | 125KHz | PCLK1M |
8 | 62.5KHz | PCLK1M |
9 | 31.25KHz | PCLK1M |
2.4 Timer 位宽
nRF52832 5个定时器最大位宽都是 32 Bit, BITMODE 寄存器可以设置定时器的位宽。
Bit Width ID | Bit Width Select | Description |
---|---|---|
16Bit | 0 | 16 bit timer bit width |
8Bit | 1 | 8 bit timer bit width |
24Bit | 2 | 24 bit timer bit width |
32Bit | 3 | 32 bit timer bit width |
定时器频率和定时器位宽建议设置 16MHz 和 32Bit (本人比较懒不想去算了),也可以根据自己的定时时间及频率来选择合适的值。
2.5 Timer 捕获
Timer 中的每一个CC[n]寄存器都对应一个捕获任务 TASKS_CAPTURE,每次出发任务寄存器 CAPTURE[n],捕获值会被存储到对应的CC[n]寄存器。
2.6 Timer 溢出和清零
Timer 计数寄存器的值增加到最大值时,计数寄存器溢出,计数寄存器的数值会清零并自动从零开始计数。出发任务寄存器 CLEAR,计数寄存器的值也会被清零。
2.7 Timer 比较
Timer 中每一个CC[n]寄存器都对应一个比较事件 COMPARE,计数值增加到和CC[n]寄存器设置的数值一样时,会产生比较事件 COMPARE[n]。
2.8 Timer 任务延迟和任务优先级
- 任务延迟:Timer 启动后,CLEAR 任务、COUNT任务、STOP任务会在PCLK16M 的一个时钟周期内生效。
- 任务优先级:START 任务和 STOP 任务在同一个时钟周期内同时触发时,STOP 任务优先执行。
3. Timer/Counter (定时器/计数器) 代码实现
3.1 Timer.c 配置
/* |
3.2 Timer.h 配置
/* |
3.3 Main.c 配置
/** |