简介: ARM的Cortex系列一般都有滴答时钟,使用RTOS的前辈应该对滴答时钟再熟悉不过了,但是Nordic虽然使用的也是Cortex_M0的内核,为了节省硬件资源,芯片内部省略了滴答时钟,今天,使用RTC定时器模拟滴答时钟进行定时。
查看芯片手册中RTC时钟结构 由图可知,其实Nordic芯片中的RTC其实就是一个独立的定时器,因此对其配置应该跟一般的timer设置差不离,区别是RTC是由LFCLK提供时钟,因此,在运行RTC时必须断开16MHz时钟。
选择RTC的时钟源
NRF_CLOCK->LFCLKSRC = 1 << 0; //使用外部32.768KHz NRF_CLOCK->EVENTS_LFCLKSTARTED = 0; //关输出16MHz时钟 0:关 1:开 NRF_CLOCK->TASKS_LFCLKSTART = 1; //开输入32.768KHz时钟 while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0) { //如果时钟关闭,则不作操作 } NRF_CLOCK->EVENTS_LFCLKSTARTED = 0; //确保输出时钟一直处于关闭状态 RTC的配置由芯片手册计算频率公式可知,如果需要8Hz的RTC时钟,则预分频寄存器的值为 PRESCALER = round (32.768 kHz / 8 Hz) – 1 = 4095
NVIC_EnableIRQ(RTC0_IRQn); //使能RTC中断 NRF_RTC0->PRESCALER = 4095; //RTC时钟8Hz,计数周期125ms NRF_RTC0->CC[0] = 8; //1*8 8Hz的时钟 需要比较8次才能接近1s的定时 (125ms*8 = 1s) NRF_RTC0->EVTENSET = 1; //开启滴答事件 NRF_RTC0->INTENSET = 1; //开启滴答中断 NRF_RTC0->EVTENSET = 1<<16; //开启比较器事件 NRF_RTC0->INTENSET = 1<<16; //开启比较器中断 写中断处理函数,此处仅判断中断发生后,进行LED灯的翻转 void RTC0_IRQHandler() { if ((NRF_RTC0->EVENTS_TICK != 0) && ((NRF_RTC0->INTENSET & RTC_INTENSET_TICK_Msk) != 0)) { NRF_RTC0->EVENTS_TICK = 0; LED1_Toggle(); } //滴答中断 翻转LED1 每125ms翻转一次 if ((NRF_RTC0->EVENTS_COMPARE[0] != 0) && ((NRF_RTC0->INTENSET & RTC_INTENSET_COMPARE0_Msk) != 0)) { NRF_RTC0->EVENTS_COMPARE[0] = 0; LED2_Toggle(); } //比较器中断 翻转LED2 每1s翻转一次 } 主函数 int main(void) { //配置LED灯引脚为输出,关闭LED灯 //调用RTC时钟源配置 //调用RTC配置 NRF_RTC0->TASKS_START = 1; //开启RTC定时器 while (1) { //空转,等待中断并处理中断,进行LED灯翻转 } }将程序下载到开发板, 实验现象应该与预想的一致,LED1每过125ms就会翻转一次,而LED2则会1s翻转一次