nRF51822定时器设置

原创 2016年05月31日 09:13:37

一、nRF51822的时钟系统

nRF51822有两种时钟源:1、高频时钟HFCLK;2、低频时钟LFCLK。这两种时钟只有当系统处于System ON模式的情况下才可用。

低频时钟源

系统有三种低频时钟源:1、32.768kHz晶体振荡器;2、32.768kHz RC振荡器;3、32.768kHz合成时钟(从HFCLK合成的32.768kHz时钟)



二、定时器/计数器

1、时钟源启动

无论是STM32还是nRF51822,在开启定时器之前,都要开启对应的时钟源,否则,定时器是无法正常工作的。
nRF51822的定时器工作于HFCLK,也就是使用PCLK1M和PCLK16M作为定时器的时钟源。在这里要注意,当定时器设定的分频值使用的定时器频率小于或者等于1MH,且没有其他功能模块请求HFCLK时,系统将自动使用HFCLK的1MHz模式,这样可以节省功耗。

根据nRF51822用户手册,HFCLK晶体振荡器通过触发HFCLKSTART任务开启,触发HFCLKSTOP任务关闭。当选择的HFCLK晶体振荡器开启时会产生一个HFCLKSTARTED事件。
上图为nRF51822的时钟源寄存器描述。在打开HFCLK时钟时,为避免以前HFCLK开启可能造成的干扰,在开启HFCLK之前,要先将事件寄存器HFCLKSTARTED(事件寄存器在HFCLK启动时会自动更新为1)清除,然后设置任务寄存器HFCLKSTART使HFCLK开启,最后循环等待HFCLK开启成功。程序如下:
void HFCLK_init(void)
{
	NRF_CLOCK->HFCLKSTARTED=0;
	NRF_CLOCK->HFCLKSTART=0;
	while(NRF_CLOCK->HFCLKSTARTED==0)			//HFCLK晶体振荡器开启时会产生一个HFCLKSTARTED事件
	{
		//Do nothing
	}
}



2、定时器配置

工作模式:nRF51822的TIMER有两种工作模式:定时器模式(Timer mode)和计数器模式(Counter mode)。
开启与关闭:在所有模式中,TIMER都是通过触发START任务开启,触发STOP任务关闭。
计时时钟:1、在定时器模式下,TIMER内部的计数寄存器(Counter register)在计时频率fTIMER每滴答一次时加1。计时频率通过预分频寄存器PRESCALER来设置。2、在计数器模式下,每当COUNT任务触发一次TIMER内部的计数寄存器(Counter register)加1,也就是计数频率和预分频寄存器在计数器模式下并没有使用。同样,COUNT任务在定时器模式下也没有任何作用。
计数的最大值(溢出时的值):最大计数值可以通过改变在BITMODE寄存器中的TIMER的位宽来实现。BITMODE设定了Counter寄存器比较/捕获寄存器使用的位数。1、TIMER0:可选择的位宽为8、16、24、32;2、TIMER1和TIMER2:可选择的位宽都为8、16。
比较/捕获寄存器:1、定时器模式:当Counter的值与在比较/捕获寄存器CC[n]中值相等时,对应的比较事件COMPARE[n]将会产生。2、计数器模式:通过设置一个CAPTURE任务,当计数到与比较/捕获寄存器设定的值相等时,CAPTURE[n]任务将会触发“捕获定时器的值(Counter value)到CC[n]寄存器。
nRF51822有TIMER0、TIMER1、TIMER2,这3个TIMER分别带有4个比较/捕获寄存器。比较/捕获寄存器的值不同可以产生不同的定时时间。
定时器配置程序如下所示:
void timer0_init(void)
{
	//设置TIMER0为定时器模式
	NRF_TIMER0->MODE=TIMER_MODE_MODE_Timer;
	//配置预分频寄存器,对时钟源HFCLK进行分频
	NRF_TIMER0->PRESCALER=9;
	//设置计数位宽,决定计数值的最大值
	NRF_TIMER0->BITMODE=TIEMR_BITMODE_BITMODE_16Bit;
}



static void nrf_timer0_delay_ms(uint_fast16_t voloatile number_of_ms)
{
	//每次定时器开始计数前,都要将TIMER内部的计数器清零
	NRF_TIMER0->TASK_CLEAR=1;
	//2^9分频值后,TIMER的计数频率为31250Hz,也就是每32us tick一次。则1ms tick 31.25次,但是CC[0]寄存器不能存储小数,故采用下面方法
	NRF_TIMER0->CC[0]=number_of_ms*31;
	NRF_TIMER0->CC[0]+=number_of_ms/4;
	//启动定时器
	NRF_TIMER0->TASK_START=1;
	
	
	//等待对应的COMPARE[0]事件的发生
	while(NRF_TIMER0->EVENTS_COMPARE[0]==0)
	{
		//COMPARE[0]事件发生之后,跳出循环
	}
	//清除COMPARE[0]事件,为下次定时做准备
	NRF_TIMER0->EVENTS_COMPARE[0]=0;
	
	//关闭定时器
	NRF_TIMER0->TASK_STOP=1;
}

    
定时器设置流程图如上图所示。其中TIMER的内部计数寄存器的值必须清除。因为它会一直计数,直到溢出,然后进入下次循环。当定时器开启时,它会接着定时器停止时的值继续计数,计数器计数就会产生差错。



版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

nrf51822在使用Timer1和Timer2定时器的时候如何设置定时注意地方

在51822的产品手册中,可以看到TIMER1和TIMER2最高只有16位,也就是2^16 = 65536,所以在配置定时器1和定时器2是,分频之后的时钟不能超过65536, 如下是配置1S时钟定时...

nrf51822学习之定时器PWM例程的笔记

nrf51822并没有PWM模块,但是如果巧妙的结合PPI模块,并加上一个定时器中断就可以轻松的实现了PWM,思路是这样的: 定时器使用三个比较器 cc0、cc1和cc2,当三个比较器任何一产生比较事...

nrf51822学习之定时器的探究

主程序调用的定时器初始化函数:timers_init(); 内容如下: static void timers_init(void) {     // Initialize timer module,...

BLE-NRF51822教程8-软件定时器的使用

本讲教程还是会基于 9.0 sdk中的uart例子。 在该例子上使用 sdk中自带的软件定时器来实现一些功能 Uart例子在sdk 中如下目录 XXX\Keil_v5\ARM\Pack\N...

nrf51822 app_timer

它的源代码和头文件分别为app_timer.c/app_timer.h。这是Nordic为我们提供的虚拟定时器,这个定时器不同于硬件上的TIMER,而是基于RTC1实现的一种虚拟定时器,其将定时功能作...

BLE-NRF51822教程8-软件定时器的使用

本讲教程还是会基于 9.0 sdk中的uart例子。 在该例子上使用 sdk中自带的软件定时器来实现一些功能 Uart例子在sdk 中如下目录 XXX\Keil_v5\ARM\Pack\Nordi...

nRF51822使用Timer制作4路PWM波详解

Date:2015.5.8 Author:杨正  QQ:1209758756  一、            pwm简介 PWM英文名叫Pulse Width Modulation,中文名叫脉宽调制...

NRF51822 Timer

定时器可谓是熟悉一个芯片主频之后第二个要熟悉的模块

基于NRF51822实现触摸按键方案

nrf51822 capsense

nRF51822外设时钟之串口时钟

在使用串口配置的时候吗,发现前辈们并没有像STM32那样配置GPIO引脚的速度,甚是奇怪,找到参考手册关于时钟管理的,发现并没有关于串口时钟的配置要求,然后就翻到数据手册,OMG,终于真身现形了,原来...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:nRF51822定时器设置
举报原因:
原因补充:

(最多只允许输入30个字)