Nordic NRF52832串口功耗優化

NRF52832串口功耗優化

NRF52832串口作爲NRF52832的一個重要外設,經常被用於與外部設備進行通信,但是,作爲低功耗應用的場景,開啓串口意味着設備功耗的大幅增加。於是一個大膽的猜想便引發出來,如何能使串口在使用的時候纔打開,不使用的時候關閉從而實現低功耗呢?這個猜想的主要問題是我們串口的使用是不能人爲的預測的(這裏說的是串口接收,串口發送可以知道)。要解決這個問題,關鍵是解決串口接收時纔打開串口這個問題。進一步分析,串口接收數據時,串口RX引腳電平會變化,於是,一個方案便應運而生,我們把串口RX引腳配置成中斷引腳,當有接收數據來時,我們打開串口外設,當沒有數據了,我們關閉串口外設,經過反覆嘗試和優化,證明了這個方案的可行,實現了串口的低功耗。主要源碼分享如下:

系統復位時只初始化串口RX引腳爲中斷引腳,RX引腳中斷配置如下:

void bsp_uart_rx_pin_init(void)
{ 
	ret_code_t err_code;
	
	err_code = nrf_drv_gpiote_init();  /*初始化GPIOTE模塊*/
	APP_ERROR_CHECK(err_code);
	
	/*RX 任意電平事件*/
	nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(true);
	in_config.pull = NRF_GPIO_PIN_NOPULL;
	
	err_code = nrf_drv_gpiote_in_init(RX_PIN_NUMBER,&in_config,in_pin_handler);
	NRF_LOG_INFO("err_code:%d\r\n",err_code);
	APP_ERROR_CHECK(err_code);
	
	/*使能事件觸發*/
	nrf_drv_gpiote_in_event_enable(RX_PIN_NUMBER,true);
}

接着當RX引腳上有接收數據來時,觸發RX中斷回調函數 in_pin_handler,回調中主要是RX引腳中斷失能,初始化串口,然後開始RX定時器,這個定時器是一個單次定時器,定時時間到後關閉串口外設,這個定時器的定時時間我這裏設置的是100ms,

static void in_pin_handler(nrf_drv_gpiote_pin_t pin,nrf_gpiote_polarity_t action)
{
	ret_code_t err_code;
	
	NRF_LOG_INFO("rx gpiote.\r\n");
	nrf_drv_gpiote_in_event_disable(RX_PIN_NUMBER);   /*失能RX引腳中斷*/
	bsp_uart_init();  /*初始化串口*/

	uart_rx_timers_stop();
	uart_rx_timers_start();
}

串口初始化程序跟平時使用的一樣:

void bsp_uart_init(void)
{
    uint32_t err_code;

		const app_uart_comm_params_t comm_params =
		{
				.rx_pin_no    = RX_PIN_NUMBER,
				.tx_pin_no    = TX_PIN_NUMBER,
				.rts_pin_no   = RTS_PIN_NUMBER,
				.cts_pin_no   = CTS_PIN_NUMBER,
				.flow_control = APP_UART_FLOW_CONTROL_DISABLED,
				.use_parity   = false,
				.baud_rate    = UART_BAUDRATE_BAUDRATE_Baud115200
				//.baud_rate    = UART_BAUDRATE_BAUDRATE_Baud9600
		};
		
    APP_UART_FIFO_INIT(&comm_params,
                       UART_RX_BUF_SIZE,
                       UART_TX_BUF_SIZE,
                       uart_event_handle,
                       APP_IRQ_PRIORITY_LOWEST,
                       err_code);
    APP_ERROR_CHECK(err_code);
}

如下是定時器回調函數,主要實現功能是關閉串口外設,然後從新使能串口rx引腳爲中斷引腳,

void uart_rx_timeout_handler(void * p_context)
{
	app_uart_close();
	nrf_drv_gpiote_in_event_enable(RX_PIN_NUMBER,true);
}

如此便實現了串口接收數據纔打開外設,沒使用時關閉外設,關於發送,這個就很easy了發送時初始化一遍串口,發送完重新配置RX引腳爲中斷引腳即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章