【nordic】外设第一章:一灯大师来点灯了

GPIO的基本操作

首先包含头文件,该头文件定了GPIO的相关定义

#include "nrf_gpio.h"

函数采用内联函数的形式定义
常用的函数如下:

//配置为输出模式
__STATIC_INLINE void nrf_gpio_cfg_output(uint32_t pin_number);
//配饰为输入模式
__STATIC_INLINE void nrf_gpio_cfg_input(uint32_t pin_number, nrf_gpio_pin_pull_t pull_config);
//复位引脚
__STATIC_INLINE void nrf_gpio_cfg_default(uint32_t pin_number);
//引脚置高
__STATIC_INLINE void nrf_gpio_pin_set(uint32_t pin_number);
//引脚置低
__STATIC_INLINE void nrf_gpio_pin_clear(uint32_t pin_number);
//翻转引脚
__STATIC_INLINE void nrf_gpio_pin_toggle(uint32_t pin_number);
//读取引脚电平
__STATIC_INLINE uint32_t nrf_gpio_pin_read(uint32_t pin_number);

延时函数

随便添加一下延时函数吧

#include "nrf_delay.h"

//延时函数包含了微妙延时和毫秒延时

#define nrf_delay_us(us_time) NRFX_DELAY_US(us_time);
__STATIC_INLINE void nrf_delay_ms(uint32_t ms_time);

GPIOTE,操作寄存器

事件模式就是配置中断下面代码配置了GPIO引脚按键的中断模式

void EXIT_KEY_Init(void)
{

	 nrf_gpio_cfg_input(KEY_0,NRF_GPIO_PIN_PULLUP);//设置管脚位上拉输入
	 nrf_gpio_cfg_input(KEY_1,NRF_GPIO_PIN_PULLUP);//设置管脚位上拉输入
    
    NVIC_EnableIRQ(GPIOTE_IRQn);//中断嵌套设置
	
    NRF_GPIOTE->CONFIG[0] =  (GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos)//下降沿触发
                           | (11 << GPIOTE_CONFIG_PSEL_Pos)  //引脚11
                           | (GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos);//事件模式 
    NRF_GPIOTE->INTENSET  = GPIOTE_INTENSET_IN0_Set << GPIOTE_INTENSET_IN0_Pos;// 使能中断类型:
    
	NRF_GPIOTE->CONFIG[1] =  (GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos)//下降沿触发
                           | (12<< GPIOTE_CONFIG_PSEL_Pos)  //引脚12
                           | (GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos);//事件模式 
    NRF_GPIOTE->INTENSET  = GPIOTE_INTENSET_IN1_Set << GPIOTE_INTENSET_IN1_Pos;// 使能中断类型:
}


void GPIOTE_IRQHandler(void)
{
   if(nrf_gpio_pin_read(KEY_0)== 0)
	 {
    if ((NRF_GPIOTE->EVENTS_IN[0] == 1) && 
        (NRF_GPIOTE->INTENSET & GPIOTE_INTENSET_IN0_Msk))
    {
        NRF_GPIOTE->EVENTS_IN[0] = 0; //中断事件清零.
			  Delay(10000);	
			 if(nrf_gpio_pin_read(KEY_0)== 0)
			 {
			  LED1_Toggle();//led灯翻转
			 }
			
    }
	 }
	 if(nrf_gpio_pin_read(KEY_1)== 0)
	 {
		 if ((NRF_GPIOTE->EVENTS_IN[1] == 1) && 
        (NRF_GPIOTE->INTENSET & GPIOTE_INTENSET_IN1_Msk))
    {
        NRF_GPIOTE->EVENTS_IN[1] = 0; //中断事件清零.
			  LED2_Toggle();//led灯翻转
			
    }
	}
 
}

GPIO 操作驱动库

//GPIOTE 初始化函数
#define nrf_drv_gpiote_init               nrfx_gpiote_init

//输出配置为任务
#define nrf_drv_gpiote_out_init           nrfx_gpiote_out_init
#define nrf_drv_gpiote_out_task_enable    nrfx_gpiote_out_task_enable

//输入配置为 事件模式
#define nrf_drv_gpiote_in_init            nrfx_gpiote_in_init
#define nrf_drv_gpiote_in_event_enable    nrfx_gpiote_in_event_enable

//配置
    ret_code_t err_code;

    err_code = nrf_drv_gpiote_init();
    APP_ERROR_CHECK(err_code);

    nrf_drv_gpiote_out_config_t out_config =  GPIOTE_CONFIG_OUT_TASK_TOGGLE(true);

    err_code = nrf_drv_gpiote_out_init(PIN_OUT, &out_config);
    APP_ERROR_CHECK(err_code);
	
	  nrf_drv_gpiote_out_task_enable(PIN_OUT); 

    nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(true);
    in_config.pull = NRF_GPIO_PIN_PULLUP;

    err_code = nrf_drv_gpiote_in_init(PIN_IN, &in_config, in_pin_handler);
    APP_ERROR_CHECK(err_code);

    nrf_drv_gpiote_in_event_enable(PIN_IN, true);

下面我们对以上函数逐个说明
函数定义在 #include <nrfx_gpiote.h>

1. nrf_drv_gpiote_init

nrfx_err_t nrfx_gpiote_init(void)
{
    nrfx_err_t err_code;

    if (m_cb.state != NRFX_DRV_STATE_UNINITIALIZED)
    {
        err_code = NRFX_ERROR_INVALID_STATE;
        NRFX_LOG_WARNING("Function: %s, error code: %s.",
                         __func__,
                         NRFX_LOG_ERROR_STRING_GET(err_code));
        return err_code;
    }

    uint8_t i;

    for (i = 0; i < NUMBER_OF_PINS; i++)
    {
        pin_in_use_clear(i);
    }

    for (i = 0; i < (GPIOTE_CH_NUM + NRFX_GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS); i++)
    {
        channel_free(i);
    }

    memset(m_cb.configured_pins, 0, sizeof(m_cb.configured_pins));

    NRFX_IRQ_PRIORITY_SET(GPIOTE_IRQn, NRFX_GPIOTE_CONFIG_IRQ_PRIORITY);
    NRFX_IRQ_ENABLE(GPIOTE_IRQn);
    nrf_gpiote_event_clear(NRF_GPIOTE_EVENTS_PORT);
    nrf_gpiote_int_enable(GPIOTE_INTENSET_PORT_Msk);
    m_cb.state = NRFX_DRV_STATE_INITIALIZED;

    err_code = NRFX_SUCCESS;
    NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
    return err_code;
}

首先判断是否已经定义了驱动库if (m_cb.state != NRFX_DRV_STATE_UNINITIALIZED)
清除掉所有引脚初始化pin_in_use_clear(i);
释放所有通道channel_free(i);
设置中断,并配置优先级NRFX_IRQ_PRIORITY_SET(GPIOTE_IRQn, NRFX_GPIOTE_CONFIG_IRQ_PRIORITY);NRFX_GPIOTE_CONFIG_IRQ_PRIORITY);
使能中断NRFX_IRQ_ENABLE(GPIOTE_IRQn);
清除事件标志nrf_gpiote_event_clear(NRF_GPIOTE_EVENTS_PORT);
使能通道事件nrf_gpiote_int_enable(GPIOTE_INTENSET_PORT_Msk);
修改状态m_cb.state = NRFX_DRV_STATE_INITIALIZED;

2. nrfx_gpiote_out_init

nrfx_err_t nrfx_gpiote_out_init(nrfx_gpiote_pin_t                pin,
                                nrfx_gpiote_out_config_t const * p_config)
{
    NRFX_ASSERT(pin < NUMBER_OF_PINS);
    NRFX_ASSERT(m_cb.state == NRFX_DRV_STATE_INITIALIZED);
    NRFX_ASSERT(p_config);

    nrfx_err_t err_code = NRFX_SUCCESS;

    if (pin_in_use(pin))
    {
        err_code = NRFX_ERROR_INVALID_STATE;
    }
    else
    {
        if (p_config->task_pin)
        {
            int8_t channel = channel_port_alloc(pin, NULL, true);

            if (channel != NO_CHANNELS)
            {
                nrf_gpiote_task_configure((uint32_t)channel,
                                          pin,
                                          p_config->action,
                                          p_config->init_state);
            }
            else
            {
                err_code = NRFX_ERROR_NO_MEM;
            }
        }
        else
        {
            pin_in_use_set(pin);
        }

        if (err_code == NRFX_SUCCESS)
        {
            if (p_config->init_state == NRF_GPIOTE_INITIAL_VALUE_HIGH)
            {
                nrf_gpio_pin_set(pin);
            }
            else
            {
                nrf_gpio_pin_clear(pin);
            }

            nrf_gpio_cfg_output(pin);
            pin_configured_set(pin);
        }
    }

    NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
    return err_code;
}

判断引脚是否初始化完成if (pin_in_use(pin))
判断引脚是否存在task中if (p_config->task_pin)
为GPIOTE分配通道 nrf_gpiote_task_configure
根据参数设置引脚电平if (p_config->init_state == NRF_GPIOTE_INITIAL_VALUE_HIGH)
{
nrf_gpio_pin_set(pin);
}
else
{
nrf_gpio_pin_clear(pin);
}
配置引脚为输出模式nrf_gpio_cfg_output(pin);
pin_configured_set(pin);

3. nrf_drv_gpiote_out_task_enable

使能任务模式

4. nrf_drv_gpiote_in_init

nrfx_err_t nrfx_gpiote_in_init(nrfx_gpiote_pin_t               pin,
                               nrfx_gpiote_in_config_t const * p_config,
                               nrfx_gpiote_evt_handler_t       evt_handler)
{
    NRFX_ASSERT(pin < NUMBER_OF_PINS);
    nrfx_err_t err_code = NRFX_SUCCESS;

    /* Only one GPIOTE channel can be assigned to one physical pin. */
    if (pin_in_use_by_gpiote(pin))
    {
        err_code = NRFX_ERROR_INVALID_STATE;
    }
    else
    {
        int8_t channel = channel_port_alloc(pin, evt_handler, p_config->hi_accuracy);
        if (channel != NO_CHANNELS)
        {
            if (!p_config->skip_gpio_setup)
            {
                if (p_config->is_watcher)
                {
                    nrf_gpio_cfg_watcher(pin);
                }
                else
                {
                    nrf_gpio_cfg_input(pin, p_config->pull);
                }
                pin_configured_set(pin);
            }

            if (p_config->hi_accuracy)
            {
                nrf_gpiote_event_configure((uint32_t)channel, pin, p_config->sense);
            }
            else
            {
                m_cb.port_handlers_pins[channel -
                                        GPIOTE_CH_NUM] |= (p_config->sense) << SENSE_FIELD_POS;
            }
        }
        else
        {
            err_code = NRFX_ERROR_NO_MEM;
        }
    }

    NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
    return err_code;
}

5. nrf_drv_gpiote_in_event_enable

使能事件模式

示例代码(附注释)

在sdk_config,h中使能宏定义GPIOTE
可使用Configuration Wizard可视化配置,使能nRF_Drivers 下的 GPIOTE_ENABLEDNRFX_GPIOTE_ENABLED

// <e> GPIOTE_ENABLED - nrf_drv_gpiote - GPIOTE peripheral driver - legacy layer
//==========================================================
#ifndef GPIOTE_ENABLED
#define GPIOTE_ENABLED 1
#endif
// <o> GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS - Number of lower power input pins 
#ifndef GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS
#define GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS 1
#endif

// <o> GPIOTE_CONFIG_IRQ_PRIORITY  - Interrupt priority
 

// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
// <0=> 0 (highest) 
// <1=> 1 
// <2=> 2 
// <3=> 3 
// <4=> 4 
// <5=> 5 
// <6=> 6 
// <7=> 7 

#ifndef GPIOTE_CONFIG_IRQ_PRIORITY
#define GPIOTE_CONFIG_IRQ_PRIORITY 7
#endif

// </e>



// <e> NRFX_GPIOTE_ENABLED - nrfx_gpiote - GPIOTE peripheral driver
//==========================================================
#ifndef NRFX_GPIOTE_ENABLED
#define NRFX_GPIOTE_ENABLED 1
#endif
// <o> NRFX_GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS - Number of lower power input pins 
#ifndef NRFX_GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS
#define NRFX_GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS 1
#endif

// <o> NRFX_GPIOTE_CONFIG_IRQ_PRIORITY  - Interrupt priority
 
// <0=> 0 (highest) 
// <1=> 1 
// <2=> 2 
// <3=> 3 
// <4=> 4 
// <5=> 5 
// <6=> 6 
// <7=> 7 

#ifndef NRFX_GPIOTE_CONFIG_IRQ_PRIORITY
#define NRFX_GPIOTE_CONFIG_IRQ_PRIORITY 7
#endif

// <e> NRFX_GPIOTE_CONFIG_LOG_ENABLED - Enables logging in the module.
//==========================================================
#ifndef NRFX_GPIOTE_CONFIG_LOG_ENABLED
#define NRFX_GPIOTE_CONFIG_LOG_ENABLED 0
#endif
// <o> NRFX_GPIOTE_CONFIG_LOG_LEVEL  - Default Severity level
 
// <0=> Off 
// <1=> Error 
// <2=> Warning 
// <3=> Info 
// <4=> Debug 

#ifndef NRFX_GPIOTE_CONFIG_LOG_LEVEL
#define NRFX_GPIOTE_CONFIG_LOG_LEVEL 3
#endif

// <o> NRFX_GPIOTE_CONFIG_INFO_COLOR  - ANSI escape code prefix.
 
// <0=> Default 
// <1=> Black 
// <2=> Red 
// <3=> Green 
// <4=> Yellow 
// <5=> Blue 
// <6=> Magenta 
// <7=> Cyan 
// <8=> White 

#ifndef NRFX_GPIOTE_CONFIG_INFO_COLOR
#define NRFX_GPIOTE_CONFIG_INFO_COLOR 0
#endif

// <o> NRFX_GPIOTE_CONFIG_DEBUG_COLOR  - ANSI escape code prefix.
 
// <0=> Default 
// <1=> Black 
// <2=> Red 
// <3=> Green 
// <4=> Yellow 
// <5=> Blue 
// <6=> Magenta 
// <7=> Cyan 
// <8=> White 

#ifndef NRFX_GPIOTE_CONFIG_DEBUG_COLOR
#define NRFX_GPIOTE_CONFIG_DEBUG_COLOR 0
#endif

// </e>

// </e>

主函数代码如下;

#include <stdbool.h>
#include "nrf.h"
#include "nrf_drv_gpiote.h"
#include "app_error.h"
#include "boards.h"
#include "nrf_delay.h"

//按键的中断函数,在nrf_drv_gpiote_in_init(BSP_BUTTON_0,&in_config,in_handle_event);中定义
void in_handle_event(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{
    if(pin == BSP_BUTTON_0)
    {
        nrf_delay_ms(50);//消抖
        if(0 == nrf_gpio_pin_read(BSP_BUTTON_0))//下降沿
        {
            nrf_drv_gpiote_out_task_trigger(BSP_LED_0);//翻转LED
            nrf_drv_gpiote_out_task_trigger(BSP_LED_1);
        }
        
    }
    
}
//GPIOTE初始化函数
static void gpiote_init(void)
{
    ret_code_t err_code;   
/*初始化GPIOTE*/ 
    err_code = nrf_drv_gpiote_init();
    APP_ERROR_CHECK(err_code);

/*初始化BSP_LED_0的task模式*/
    nrfx_gpiote_out_config_t  out_config = GPIOTE_CONFIG_OUT_TASK_TOGGLE(true);//翻转模式
    err_code = nrf_drv_gpiote_out_init(BSP_LED_0,&out_config);
    APP_ERROR_CHECK(err_code);
    nrf_drv_gpiote_out_task_enable(BSP_LED_0);

/*初始化BSP_LED_1的task模式*/  
    err_code = nrf_drv_gpiote_out_init(BSP_LED_1,&out_config);
    APP_ERROR_CHECK(err_code);
    nrf_drv_gpiote_out_task_enable(BSP_LED_1);
    
/*初始化BSP_BUTTON_0的事件模式*/ 
   nrfx_gpiote_in_config_t  in_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(false);//下降沿触发中断
    in_config.pull = NRF_GPIO_PIN_PULLUP;//按键上拉,默认引脚是NOPULL
    err_code = nrf_drv_gpiote_in_init(BSP_BUTTON_0,&in_config,in_handle_event);//定义中断函数入口地址
    APP_ERROR_CHECK(err_code);
    nrf_drv_gpiote_in_event_enable(BSP_BUTTON_0,true);
}

int main(void)
{ 
 gpiote_init();
  while(1)                            
  {	 		
//    nrf_drv_gpiote_out_task_trigger(BSP_LED_0);
    nrf_delay_ms(1000);
  }
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值