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;
}
发布了81 篇原创文章 · 获赞 21 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_33575901/article/details/90043139