PPI是可编程外设互联(Programmable Peripheral Interconnect)的缩写,PPI的作用是提供一个硬件通道,将不同外设的时间和任务“连接”在一起,当事件产生时,不用经过CPU干涉,而是由硬件自动触发事件“连接”的任务。
nRF52832的PPI有32个通道,编号为0~31,其中有12个通道(通道20~31)已经被预编程,剩余的20个通道(通道0~19)是用户可编程的。每隔通道到包含一个EEP(Event End-Point:事件端点)和一个TEP(Task End-Point:任务端点),使用PPI连接外设事件和任务的时候,将外设事件寄存器的地址写入PPI通道的EEP,将外设任务寄存器的地址写入到PPI通道的TEP,然后使能该PPI通道即可实现外设事件和外设任务的连接。
PPI的原理图如下:
库函数应用
应用流程图如下图所示:
具体代码实现:
//该变量用来保存应用程序向驱动程序申请的PPI通道编号
nrf_ppi_channel_t my_ppi_channel;
//初始化GPIOTE程序模块,配置P0.13为GPIOTE输入引脚,P0.17为GPIOTE输出引脚
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输出引脚,初始化时会分配一个GPIOTE通道
err_code = nrfx_gpiote_out_init(LED_1, &out_config);0.
APP_ERROR_CHECK(err_code);
//使能引脚LED_1(P0.17)所在GPIOTE通道的任务触发
nrf_drv_gpiote_out_task_enable(LED_1);
//以下代码配置P0.13作为GPIOTE输入,下降沿产生事件
nrf_drv_gpiote_in_config_t in_config = NRFX_GPIOTE_CONFIG_IN_SENSE_HITOLO(true);
//开启P0.13引脚的上拉电阻
in_config.pull = NRF_GPIO_PIN_PULLUP;
//配置该引脚为GPIOTE输入,因为使用PPI连接,所以不需要注册事件回调函数
err_code = nrfx_gpiote_in_init(BUTTON_1, &in_config, NULL);
APP_ERROR_CHECK(err_code);
//使能该引脚所在GPIOTE通道的事件模式
nrf_drv_gpiote_in_event_enable(BUTTON_1, true);
}
//初始化PPI程序模块,向PPI驱动程序申请PPI通道,申请成功后配置PPI通道的EEP和TEP,之后使能该PPI通道。
void ppi_config(void)
{
uint32_t err_code = NRF_SUCCESS;
//初始化PPI程序模块
err_code = nrf_drv_ppi_init();
APP_ERROR_CHECK(err_code);
//申请PPI通道,注意PPI通道的分配是由驱动函数完成的,分配的通道号保存到my_ppi_channel
err_code = nrfx_ppi_channel_alloc(&my_ppi_channel);
//检查返回值,确定是否申请到了空闲的PPI通道
APP_ERROR_CHECK(err_code);
//设置PPI通道my_ppi_channel的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);
}
/***************************************************************************
* 描 述 : main函数
* 入 参 : 无
* 返回值 : int 类型
**************************************************************************/
int main(void)
{
//初始化GPIOTE
gpiote_init();
//初始化PPI
ppi_config();
while(true)
{
}
}