和其他 MCU 处理器一样,在 nrf52840 中定时器的功能是十分强大的。其内部包含了 5 个定时
器 TIMER 模块 :TIMER0 、 TIMER1 、 TIMER2 、 TIMER3 、 TIMER4 ,如下表 10.1 所示。
![图片[1]-nrf52840蓝牙学习(定时器的应用)-ELink墨水屏电子纸社区-FPGA CPLD-ChipDebug](http://chipdebug.com/wp-content/uploads/2025/11/20251112115143365-31762919503.png?v=1762919503)
![图片[2]-nrf52840蓝牙学习(定时器的应用)-ELink墨水屏电子纸社区-FPGA CPLD-ChipDebug](http://chipdebug.com/wp-content/uploads/2025/11/20251112115144311-71762919504.png?v=1762919505)
1. 时钟源
首先定时器 TIMER 工作在高频时钟源( HFLCK )下,同时包含了一个 4bit ( 1 / 2X )的分频
![图片[3]-nrf52840蓝牙学习(定时器的应用)-ELink墨水屏电子纸社区-FPGA CPLD-ChipDebug](http://chipdebug.com/wp-content/uploads/2025/11/20251112115146557-31762919506.png?v=1762919506)
![图片[4]-nrf52840蓝牙学习(定时器的应用)-ELink墨水屏电子纸社区-FPGA CPLD-ChipDebug](http://chipdebug.com/wp-content/uploads/2025/11/20251112115147378-91762919507.png?v=1762919507)
出。
计数模式下,每次触发 COUNT 任务时, TIMER 的内部计数器 Counter 寄存器都会递增 1 ,同
时,计数器模式下是不使用定时器的频率和预分频器, COUNT 任务在定时器模式下无效。通过设
定一个 CAPTURE Task ,捕获的计数器的值存储到 CC[n] 寄存器内,然后对 CC[n] 寄存器进行读取计
数的值。
5. 任务延迟和优先级
任务延迟: TIMER 启动后, CLEAR 任务, COUNT 任务和 STOP 任务将保证在 PCLK16M 的一
个时钟周期内生效。
任务优先级:如果同时触发 START 任务和 STOP 任务,即在 PCLK16M 的同一时段内,则优先
执行 STOP 任务。
下表是定时器的寄存器列表,详细说明如下 10.5 表示所示:
![图片[5]-nrf52840蓝牙学习(定时器的应用)-ELink墨水屏电子纸社区-FPGA CPLD-ChipDebug](http://chipdebug.com/wp-content/uploads/2025/11/20251112115149872-31762919509.png?v=1762919509)
![图片[6]-nrf52840蓝牙学习(定时器的应用)-ELink墨水屏电子纸社区-FPGA CPLD-ChipDebug](http://chipdebug.com/wp-content/uploads/2025/11/20251112115150522-101762919510.png?v=1762919510)
定时器首先需要设置的三个参数,分别为:定时器的模式、定时器的位宽、定时器的时钟频率。
本例中需要进行定时操作,因此还需要设置比较寄存器里的值。如果初始化完成后,定时器就开始
定时,当定时时间的值跟 CC[n] 寄存器的值相等时,将触发一个 COMPARE [n] event ,这时候我们
关掉定时器定时。这样根据 CC[n] 寄存器的值就是实现了一个指定的时间长度的。
文件一:
/******************** (C) COPYRIGHT 2023 青风电子 ******************** * 文件名 :main * 出品论坛 :www.qfv8.com * 实验平台:青云nRF52840蓝牙开发板 * 描述 :定时器定时 * 作者 :青风 * 店铺 :qfv5.taobao.com **********************************************************************/ #include <stdbool.h> #include <stdint.h> //#include "nrf_delay.h" #include "nrf_gpio.h" #include "led.h" #include "time.h" int main(void) { // LED_Init(); while (1) { LED1_Toggle(); //使用定时器0产生1s定时 nrf_timer_delay_ms(TIMER0, TIMER_DELAY_MS); LED2_Toggle(); // 使用定时器1产生1s定时 nrf_timer_delay_ms(TIMER1, TIMER_DELAY_MS); LED3_Toggle(); // 使用定时器2产生1s定时 nrf_timer_delay_ms(TIMER2, TIMER_DELAY_MS); } }
文件二:
#ifndef __LED_H #define __LED_H #include "nrf52840.h" #define LED_0 NRF_GPIO_PIN_MAP(0,13) #define LED_1 NRF_GPIO_PIN_MAP(0,14) #define LED_2 NRF_GPIO_PIN_MAP(0,15) #define LED_3 NRF_GPIO_PIN_MAP(0,16) void LED_Init(void); void LED1_Open(void); void LED1_Close(void); void LED1_Toggle(void); void LED2_Open(void); void LED2_Close(void); void LED2_Toggle(void); void LED3_Open(void); void LED3_Close(void); void LED3_Toggle(void); #endif /* __LED_H */
文件 三:
#include "nrf52840.h" #include "led.h" #include "nrf_gpio.h" #include "time.h" #include <stdbool.h> #include <stdint.h> /** * @brief Function for timer initialization. */ static volatile NRF_TIMER_Type * timer_init(timer_t timer) { volatile NRF_TIMER_Type * p_timer; // 开始16 MHz晶振. NRF_CLOCK->EVENTS_HFCLKSTARTED = 0; NRF_CLOCK->TASKS_HFCLKSTART = 1; // 等待外部振荡器启动 while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0) { // Do nothing. } switch (timer) { case TIMER0: p_timer = NRF_TIMER0; break; case TIMER1: p_timer = NRF_TIMER1; break; case TIMER2: p_timer = NRF_TIMER2; break; default: p_timer = 0; break; } return p_timer; } /** @brief Function for using the peripheral hardware timers to generate an event after requested number of milliseconds. * * @param[in] timer Timer to be used for delay, values from @ref p_timer * @param[in] number_of_ms Number of milliseconds the timer will count. * @note This function will power ON the requested timer, wait until the delay, and then power OFF that timer. */ void nrf_timer_delay_ms(timer_t timer, uint_fast16_t volatile number_of_ms) { volatile NRF_TIMER_Type * p_timer = timer_init(timer); if (p_timer == 0) { while(true) { // Do nothing. } } p_timer->MODE = TIMER_MODE_MODE_Timer; // 设置为定时器模式 p_timer->PRESCALER = 10; // Prescaler 9 produces 31250 Hz timer frequency => 1 tick = 32 us. p_timer->BITMODE = TIMER_BITMODE_BITMODE_16Bit; // 16 bit 模式. p_timer->TASKS_CLEAR = 1; // 清定时器. // With 32 us ticks, we need to multiply by 31.25 to get milliseconds. p_timer->CC[0] = number_of_ms * 31; p_timer->CC[0] += number_of_ms / 4; p_timer->TASKS_START = 1; // Start timer. while (p_timer->EVENTS_COMPARE[0] == 0) { // Do nothing. } p_timer->EVENTS_COMPARE[0] = 0; p_timer->TASKS_STOP = 1; // Stop timer. } /** @} */
文件四:
#include "nrf52840.h" #include "nrf_gpio.h" #include "led.h" void LED_Init(void) { // Configure LED-pins as outputs nrf_gpio_cfg_output(LED_0); nrf_gpio_cfg_output(LED_1); nrf_gpio_cfg_output(LED_2); } void LED1_Open(void) { nrf_gpio_pin_clear(LED_0); } void LED1_Close(void) { nrf_gpio_pin_set(LED_0); } void LED1_Toggle(void) { nrf_gpio_pin_toggle(LED_0); } void LED2_Open(void) { nrf_gpio_pin_clear(LED_1); } void LED2_Close(void) { nrf_gpio_pin_set(LED_1); } void LED2_Toggle(void) { nrf_gpio_pin_toggle(LED_1); } void LED3_Open(void) { nrf_gpio_pin_clear(LED_2); } void LED3_Close(void) { nrf_gpio_pin_set(LED_2); } void LED3_Toggle(void) { nrf_gpio_pin_toggle(LED_2); }
第一节: nrf_timer_delay_ms函数
void nrf





没有回复内容