新闻  |   论坛  |   博客  |   在线研讨会
Nrf52832 PPI GPIOTE 中断的理解
电子禅石 | 2018-01-13 01:12:41    阅读:411   发布文章

问题:

1.PPI 有数量限制吗? 31个其中  0-19 用户用;20个通道;

 

2.协议栈用了PPI的什么资源?20~31通道协议栈用。

 

3.PWM 库函数又用了PPI哪个资源?是通过

  err_code = nrf_drv_ppi_channel_alloc(&m_ppi_channel); 只是用这个分配一下,没有说具体哪个通道。会自动在上面的函数里进行分配,调试时候可以打印出来的。

 

 

4.GPIOTE  PPI   中断使能 GPIOTE  其实是专门针对IO口产生event 然后配合PPI 触发任务,GPIO 通过GPIOTE模块,产生EVENT;

也可以产生写的任务,不一定是触发事件,比如引脚上升沿变化,通过GPIOTE模块产生触发事件,再通过PPI 然后完成写另一个引脚的 为高电平的任务;他们之间关系是这样的。

其中这个就相当于中断,并且里面有相应的中断使能寄存器。但是例子里,并没有体现这个中断的使能。

中断主要是引脚作为触发事件时候使用。

Write '1' to Enable interrupt for IN[0] event

 

5.GPIOTE 有数量限制吗?  只有8个通道;

 

A GPIOTE block enables GPIOs to generate events on pin state change which can be used to carry out

tasks through the PPI system. A GPIO can also be driven to change state on system events using the PPI

system. Low power detection of pin state changes is possible when in System ON or System OFF.

4.简单例子介绍来阐述几个的关系:

Void main()

{

ret_code_t err_code;

 

    err_code = nrf_drv_ppi_init();

    APP_ERROR_CHECK(err_code);

 

    err_code = nrf_drv_gpiote_init();//主要清零8个通道

    APP_ERROR_CHECK(err_code);

 

    nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;

err_code = nrf_drv_timer_init(&timer, &timer_cfg, timer_dummy_handler);

}

static void led_blinking_setup()

{

    uint32_t compare_evt_addr;

    uint32_t gpiote_task_addr;

    nrf_ppi_channel_t ppi_channel;

    ret_code_t err_code;

    nrf_drv_gpiote_out_config_t config = GPIOTE_CONFIG_OUT_TASK_TOGGLE(false);

 

    err_code = nrf_drv_gpiote_out_init(GPIO_OUTPUT_PIN_NUMBER, &config);

    APP_ERROR_CHECK(err_code);

 

 

    nrf_drv_timer_extended_compare(&timer, (nrf_timer_cc_channel_t)0, 200 * 1000UL, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, false);

 

    err_code = nrf_drv_ppi_channel_alloc(&ppi_channel);

    APP_ERROR_CHECK(err_code);

 

    compare_evt_addr = nrf_drv_timer_event_address_get(&timer, NRF_TIMER_EVENT_COMPARE0);

    gpiote_task_addr = nrf_drv_gpiote_out_task_addr_get(GPIO_OUTPUT_PIN_NUMBER);

 

    err_code = nrf_drv_ppi_channel_assign(ppi_channel, compare_evt_addr, gpiote_task_addr);

    APP_ERROR_CHECK(err_code);

 

    err_code = nrf_drv_ppi_channel_enable(ppi_channel);

    APP_ERROR_CHECK(err_code);

 

    nrf_drv_gpiote_out_task_enable(GPIO_OUTPUT_PIN_NUMBER);

}

 

中断使能是针对event 触发事件来说的。具体在代码中体现如下:

void nrf_drv_gpiote_in_event_enable(nrf_drv_gpiote_pin_t pin, bool int_enable)

{

    ASSERT(pin < NUMBER_OF_PINS);

    ASSERT(pin_in_use_by_gpiote(pin));

    if (pin_in_use_by_port(pin))

    {

        uint8_t pin_and_sense =

            m_cb.port_handlers_pins[channel_port_get(pin) - GPIOTE_CH_NUM];

        nrf_gpiote_polarity_t polarity =

            (nrf_gpiote_polarity_t)(pin_and_sense >> SENSE_FIELD_POS);

        nrf_gpio_pin_sense_t sense;

        if (polarity == NRF_GPIOTE_POLARITY_TOGGLE)

        {

            /* read current pin state and set for next sense to oposit */

            sense = (nrf_gpio_pin_read(pin)) ?

                    NRF_GPIO_PIN_SENSE_LOW : NRF_GPIO_PIN_SENSE_HIGH;

        }

        else

        {

            sense = (polarity == NRF_GPIOTE_POLARITY_LOTOHI) ?

                    NRF_GPIO_PIN_SENSE_HIGH : NRF_GPIO_PIN_SENSE_LOW;

        }

        nrf_gpio_cfg_sense_set(pin, sense);

    }

    else if (pin_in_use_by_te(pin))

    {

        int32_t             channel = (int32_t)channel_port_get(pin);

        nrf_gpiote_events_t event   = TE_IDX_TO_EVENT_ADDR(channel);

 

        nrf_gpiote_event_enable(channel);

 

        nrf_gpiote_event_clear(event);

        if (int_enable)

        {

            nrf_drv_gpiote_evt_handler_t handler = channel_handler_get(channel_port_get(pin));

            // Enable the interrupt only if event handler was provided.

            if (handler)

            {

                nrf_gpiote_int_enable(1 << channel);  //使能中断。

            }

        }

    }

}




参与讨论
登录后参与讨论
属于自己原创的技术积累分享
推荐文章
最近访客