nRF52832開發之PPI淺析

一、PPI原理

1.概念
PPI是可編程外設互連(Programmable Peripheral Interconnect)的縮寫
2.作用
提供一個硬件通道,將不同外設的事件和任務"連接"在一起,當事件產生時硬件自動觸發事件"連接"的任務
3.優點
PPI機制的設計,使得被"連接"的任務由硬件自動觸發完成,省去了原本CPU需要參與的步驟。這一方面降低了CPU的負荷,另一方面保證了產生事件到執行任務的實時性。

4.實現原理
1)nRF52832共有32個通道(編號爲0~31),其中,有12個通道(通道20~31)已經被預編程,剩餘20個通道(通道0~19)是用戶可編程的;
2)每個PPI通道由3個端點寄存器組成,1個EEP(Event End-Point:事件端點)和2個TEP(Task End-Point:任務端點,次級任務端點)寄存器;
3)任務端點和次級任務端點同時被觸發;
4)使用PPI連接外設事件和外設任務的時候,將外設事件寄存器的地址寫入到PPI通道的EEP,將外設任務寄存器的地址寫入到PPI通道的TEP,最後使能該PPI通道實現事件和任務間的連接;

5.PPI組
nRF52832共用6個PPI組CHG[0]~CHG[5],PPI通道可以加入PPI組中集中管理,實現同時使能或禁用PPI通道的功能。
注意:當一個PPI通道同時屬於兩個PPI組時,如果使能一個PPI組禁用另一個PPI組,則使能作用優先執行。

二、PPI寄存器

PPI只有任務寄存器和通用寄存器,它沒有事件寄存器,所以PPI產生不了事件
1.任務寄存器
1)CHG[n].EN(n=0~5):使能PPI通道組n
2)CHG[n].DIS(n=0~5):禁用PPI通道組n

2.通用寄存器
1)CHEN:使能/禁用PPI通道
2)CHENSET:使能PPI通道
3)CHENCLR:禁用PPI通道
4)CH[n].EEP(n=0~19):PPI通道n事件端點
5)CH[n].TEP(n=0~19):PPI通道n任務端點
6)CHG[n](n=0~5):PPI通道組n
7)FORK[n].TEP(n=0~31):PPI通道n次級任務端點

三、編程分析

sdk版本:nRF5_SDK_15.2.0_9412b96

1.基本編寫步驟
1)初始化PPI模塊
2)向驅動程序申請PPI通道
3)配置通道的EEP和TEP
4)使能PPI通道

2.相關庫函數使用
1)ret_code_t nrf_drv_ppi_init(void);
功能:初始化PPI模塊
2)nrfx_err_t nrfx_ppi_channel_alloc(nrf_ppi_channel_t * p_channel);
功能:申請PPI通道
3)nrfx_err_t nrfx_ppi_channel_assign(nrf_ppi_channel_t channel, uint32_t eep, uint32_t tep);
功能:配置通道的EEP和TEP
4)nrfx_err_t nrfx_ppi_channel_fork_assign(nrf_ppi_channel_t channel, uint32_t fork_tep);
功能:配置通道次級任務端點
5)nrfx_err_t nrfx_ppi_group_alloc(nrf_ppi_channel_group_t * p_group);
功能:申請PPI通道組
6)__STATIC_INLINE nrfx_err_t nrfx_ppi_channel_include_in_group(nrf_ppi_channel_t channel, nrf_ppi_channel_group_t group)
功能:向PPI通道組加入指定通道
7) __STATIC_INLINE nrfx_err_t nrfx_ppi_channel_remove_from_group(nrf_ppi_channel_t channel, nrf_ppi_channel_group_t group)
功能:從PPI通道組移除指定通道
8)nrfx_err_t nrfx_ppi_channel_enable(nrf_ppi_channel_t channel);
功能:使能PPI通道
9)nrfx_err_t nrfx_ppi_channel_disable(nrf_ppi_channel_t channel);
功能:禁用PPI通道
10)nrfx_err_t nrfx_ppi_group_enable(nrf_ppi_channel_group_t group);
功能:使能PPI通道組
11)nrfx_err_t nrfx_ppi_group_disable(nrf_ppi_channel_group_t group);
功能:禁用PPI通道組

3.代碼示例

#include "boards.h"
#include "nrf_drv_gpiote.h"
#include "nrf_drv_ppi.h"

void gpiote_init(void)
{
	ret_code_t err_code;
	//初始化GPIOTE模塊
	err_code = nrf_drv_gpiote_init();
	APP_ERROR_CHECK(err_code);
	//定義GPIOTE輸出初始化結構體並賦值
	nrf_drv_gpiote_out_config_t out_config = NRFX_GPIOTE_CONFIG_OUT_TASK_TOGGLE(true);
	//初始化GPIOTE輸出引腳
	err_code = nrfx_gpiote_out_init(LED_1,&out_config);
	APP_ERROR_CHECK(err_code);
	//使能任務模式
	nrf_drv_gpiote_out_task_enable(LED_1);
	//定義GPIOTE輸入初始化結構體並賦值,配置下降沿產生事件
	nrf_drv_gpiote_in_config_t in_config = NRFX_GPIOTE_CONFIG_IN_SENSE_HITOLO(true);
	in_config.pull = NRF_GPIO_PIN_PULLUP;
	//配置引腳爲GPIOTE輸入
	err_code = nrfx_gpiote_in_init(BUTTON_1,&in_config,NULL);
	APP_ERROR_CHECK(err_code);
	//使能事件模式
	nrf_drv_gpiote_in_event_enable(BUTTON_1,true);
}

//定義PPI通道
nrf_ppi_channel_t my_ppi_channel;
void ppi_config(void)
{
	ret_code_t err_code = NRF_SUCCESS;
	//初始化PPI模塊
	err_code = nrf_drv_ppi_init();
	APP_ERROR_CHECK(err_code);
	//申請PPI通道
	err_code = nrfx_ppi_channel_alloc(&my_ppi_channel);
	APP_ERROR_CHECK(err_code);
	//設置PPI通道EEP和TEP端點地址	
	err_code = nrfx_ppi_channel_assign(my_ppi_channel,nrfx_gpiote_in_event_addr_get(BUTTON_1),nrfx_gpiote_out_task_addr_get(LED_1));
	APP_ERROR_CHECK(err_code);
	//使能PPI通道
	err_code = nrfx_ppi_channel_enable(my_ppi_channel);
	APP_ERROR_CHECK(err_code);
}

int main(void)
{
	gpiote_init();
	ppi_config();
	return 0;
}

 

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