此文仅用来记录自己使用PPI过程中的问题,方便自己回溯,同时希望对大家有帮助。
官方对于PPI的指导文档
Nordic PPI(Programmable peripheral interconnect)
以及大佬对PPI的学习记录
nRF52832学习记录
PPI可以通过硬件来触发一些预设好的事件,个人感觉是个十分强大的功能,不过目前我对他了解的不是特别深刻,只是会用,还需继续努力。
- 首先,PPI可以用于周期性(或者其他事件来触发的)控制GPIO,相对于软件来控制,优势是不需要CPU参与。
// 周期性反转GPIO
static void gpiote_init(void)
{
nrf_gpio_cfg_output(18);
NRF_GPIOTE->CONFIG[1] = (GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos)
| (18 << GPIOTE_CONFIG_PSEL_Pos)
| (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos);
}
void ppi_init(void)
{
NRF_PPI->CH[0].EEP = (uint32_t)(&NRF_RTC0->EVENTS_COMPARE[0]);
NRF_PPI->CH[0].TEP = (uint32_t)&NRF_EGU5->TASKS_OUT[0];
NRF_PPI->CHEN = (PPI_CHEN_CH0_Enabled << PPI_CHEN_CH0_Pos);
}
- PPI也可以用于触发中断,中断中可自行定义处理函数
void SWI3_EGU3_IRQHandler(void)
{
/* Clear event register */
NRF_EGU3->EVENTS_TRIGGERED[0] = 0;
// Handle the interrupt here
// TO DO
}
void ppi_init(void)
{
NRF_RTC0->CC[0] = RTC_US_TO_TICKS(2000, RTC_DEFAULT_CONFIG_FREQUENCY);
NRF_RTC0->INTENSET = RTC_INTENSET_COMPARE0_Msk;
/* Event signal must be enabled explicitly unlike most other peripherals */
NRF_RTC0->EVTENSET = RTC_EVTEN_COMPARE0_Msk;
NRF_RTC0->TASKS_START = 1;
/* 6 is the default int. priority used in SDK drivers */
NVIC_SetPriority(SWI3_EGU3_IRQn, 6);
NVIC_EnableIRQ(SWI3_EGU3_IRQn);
NRF_EGU3->INTENSET = EGU_INTEN_TRIGGERED0_Msk;
NRF_PPI->CH[0].EEP = (uint32_t)&NRF_RTC0->EVENTS_COMPARE[0];
NRF_PPI->CH[0].TEP = (uint32_t)&NRF_EGU3->TASKS_TRIGGER[0];
/* RTC does not have a SHORT to clear counter on compare match
so using PPI instead */
NRF_PPI->FORK[0].TEP = (uint32_t)&NRF_RTC0->TASKS_CLEAR;
NRF_PPI->CHENSET = PPI_CHENSET_CH0_Msk;
}
以上为记录自己常用的两种PPI使用方法。