版权声明:原创文章转载请注明出处。 https://blog.csdn.net/wwt18811707971/article/details/81668598
1.概述
RTC实时计数器是一个低频的24位时钟,带有分频,滴答,比较,溢出事件。NRF51822有两个RTC时钟:RTC0,RTC1。RTC0被协议栈使用了。所以在跑蓝牙程序的情况下,RTC0不可以使用。
RTC运行在LFCLK下,COUNTER的分辨率为30.517us,即使HFCLK和外部PCLKK16M不能使用时,RTC可以继续运行。
1.1 内部结构
1.2 计数器递增频率的计算
PRESCALER:分频寄存器,在RTC停止时可以读写,开启时,只能读溢出,不能写操作。PRESCALER在START,CLEAR,TRIGOVRFLW事件都会重新启动,分频值锁存在任务的内部寄存器PRESC中。
计算举例:
2.软件实现
//1----时钟配置
void RTC_CLK_Config(void)
{
NRF_CLOCK->LFCLKSRC = 1/*(CLOCK_LFCLKSRC_SRC_Xtal<<CLOCK_LFCLKSRC_SRC_Pos)*/;//使用外部32.768KHz
NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;//关闭16M时钟
NRF_CLOCK->TASKS_LFCLKSTART = 1; //开启32K
while(NRF_CLOCK->EVENTS_LFCLKSTARTED == 0)
{
}
NRF_CLOCK->EVENTS_LFCLKSTARTED = 0; //确保输出时钟一直处于关闭状态
}
//2----初始化配置
void RTC_INIT_Config(void)
{
NVIC_EnableIRQ(RTC0_IRQn);//使能RTC0中断
//NVIC_SetPriority(RTC0_IRQn, 1);
//NVIC_ClearPendingIRQ(RTC0_IRQn);
NRF_RTC0->PRESCALER = 4095; //RTC时钟频率
NRF_RTC0->CC[0] = 24;//24次计数为3s,触发比较事件
NRF_RTC0->EVTENSET = 1;//开启滴答事件
NRF_RTC0->INTENSET = 1;//开启滴答中断
NRF_RTC0->EVTENSET = 1<<16; //开启比较器事件
NRF_RTC0->INTENSET = 1<<16; //开启比较器中断
NRF_RTC0->TASKS_START = 1;//开启RTC
}
//3-----中断服务函数
void RTC0_IRQHandler(void)
{
//滴答事件,125ms触发
if((NRF_RTC0->EVENTS_TICK !=0 )&&((NRF_RTC0->INTENSET & RTC_INTENSET_TICK_Msk)!=0))
{
NRF_RTC0->EVENTS_TICK = 0;
LED1_Toggle();
}
//比较事件,3S触发
if((NRF_RTC0->EVENTS_COMPARE[0]!=0)&&(NRF_RTC0->INTENSET&RTC_INTENSET_COMPARE0_Msk)!=0)
{
NRF_RTC0->EVENTS_COMPARE[0] = 0;
LED2_Toggle();
}
}
初始化中参数计算:
#define LFCLK_FREQUENCY (32768UL)
#define COUNTER_PRESCALER ((LFCLK_FREQUENCY/RTC_FREQUENCY)-1)
#define RTC_FREQUENCY (8UL)
#define COMPARE_COUNTER (3UL)
参考:
扫描二维码关注公众号,回复:
3414679 查看本文章