nRF5使用RTC用作延迟

/ 0评 / 0

nRF52840含有3个RTC模块,如果使用官方FreeRTOS适配,则只能使用RTC0和RTC2.

RTC其中一个功能用于定时.此处RTC全称Real Timer Counter,不是我们说的走时间的那个RTC.

为了便于理解,最简化模型如此.

/* 用哪一个RTC. */

#define BLINK_RTC 0

/* 用这个RTC哪一个比较通道. */

#define BLINK_RTC_CC 1

/* 定义多少TICKS一次中断,这个计算公式可以算出1秒一次中断所需TICKS数. */

#define BLINK_RTC_TICKS (RTC_US_TO_TICKS( 1 * 1000 * 1000ULL, RTC_DEFAULT_CONFIG_FREQUENCY ) )

/* 中断传递的信号量 */

static SemaphoreHandle_t m_led_semaphore;

/* RTC配置 */

static nrf_drv_rtc_config_t const m_rtc_config = NRF_DRV_RTC_DEFAULT_CONFIG;

/* RTC实例 */

static nrf_drv_rtc_t const m_rtc = NRF_DRV_RTC_INSTANCE( BLINK_RTC );





static void blink_rtc_handler( nrf_drv_rtc_int_type_t int_type )

{

	BaseType_t yield_req = pdFALSE;

	if ( int_type == NRFX_RTC_INT_COMPARE1 )

	{

		/* 每次需要加时间,因为是绝对时间定时的. */

		nrf_drv_rtc_cc_set( &m_rtc, BLINK_RTC_CC, (nrf_rtc_cc_get( m_rtc.p_reg, BLINK_RTC_CC ) + BLINK_RTC_TICKS) & RTC_COUNTER_COUNTER_Msk, true );

	}

	portYIELD_FROM_ISR( yield_req );

}





static void led_toggle_task_function( void * pvParameter )

{

	/* blink_rtc_handler => 指定回调函数 */

	nrf_drv_rtc_init( &m_rtc, &m_rtc_config, blink_rtc_handler );

	/* m_rtc => 实例,BLINK_RTC_CC => 通道,BLINK_RTC_TICKS => 绝对间隔,true => 使能中断 */

	nrf_drv_rtc_cc_set( &m_rtc, BLINK_RTC_CC, BLINK_RTC_TICKS, true );

	nrf_drv_rtc_enable( &m_rtc );



	m_led_semaphore = xSemaphoreCreateBinary();



	while ( true )

	{

		nrf_gpio_pin_toggle( 13 );

		xSemaphoreTake( m_led_semaphore, portMAX_DELAY )

	}

}





这里的关键就那么几个,中断源的判断.

每次进去都要增加,到OVR的时候,肯定会产生一次误差,就看误差影响大不大,不大可以忽略.

计数器是24Bit的,0x8000一秒(32768分频),溢出需要511秒.当然愿意的话,你寄存器实现也是没人管你的.只是有API看起来舒服一些.