物联网BLE裸机程序开发 -- (2)nRF52840配置GPIO输入检测按键

nRF52840配置GPIO输入检测按键

上一篇文章讲述了如何在nRF52840芯片上,把GPIO配置为输出模式,从而驱动LED,上一篇文章的内容请参看以下链接。

物联网BLE裸机程序开发 -- (1)nRF52840配置GPIO输出驱动LED

Nordic nRF52840芯片上的GPIO管脚,除了可以配置为输出驱动模式之外,还可以配置为输入检测模式,本章节将会讲述如何把nRF52840的GPIO配置为输入检测,并在主循环函数中不断查询按键状态,检测按键的动作,并翻转对应的LED状态。

软件开发前准备:

开发板:Nordic官方开发板nRF52840-DK(PCA10056)。

编译器:SEGGER Embedded Studio v4.22

SDK版本:nRF5_SDK_15.2.0_9412b96

 

1、在进行软件编写之前,先查看官方开发板(PCA10056)关于按键的原理图,如下图所示。

物联网BLE裸机程序开发 -- (2)nRF52840配置GPIO输入检测按键_第1张图片

从原理图可知,开发板上有4个按键,BUTTON1和BUTTON2有默认和可选这两种连接方式,我们选默认连接方式,四个按键分别连接在P0.11、P0.12、P0.24、P0.25这四个GPIO引脚。按键按下时,引脚会连接到GND。因此,四个GPIO引脚需要配置为上拉输入模式。

 

2、我们基于前面构建的“001_led_blinky”工程来进行软件开发。先复制一份工程,并重命名为“002_button_detect”,完成后打开工程,如下图所示。

物联网BLE裸机程序开发 -- (2)nRF52840配置GPIO输入检测按键_第2张图片

物联网BLE裸机程序开发 -- (2)nRF52840配置GPIO输入检测按键_第3张图片

 

3、新建一个“button_gpio.c”和“button_gpio.h”文件,并添加到工程里面,“button_gpio.h”的内容如下图所示。

#ifndef _BUTTON_GPIO_H_
#define _BUTTON_GPIO_H_

#include "nrf_gpio.h"
#include "nordic_common.h"

#define BUTTONS_NUMBER 4

#define BUTTON_1       NRF_GPIO_PIN_MAP(0,11)
#define BUTTON_2       NRF_GPIO_PIN_MAP(0,12)
#define BUTTON_3       NRF_GPIO_PIN_MAP(0,24)
#define BUTTON_4       NRF_GPIO_PIN_MAP(0,25)
#define BUTTON_PULL    NRF_GPIO_PIN_PULLUP

#define BUTTONS_ACTIVE_STATE 0

#define BUTTONS_LIST { BUTTON_1, BUTTON_2, BUTTON_3, BUTTON_4 }

bool get_button_state(uint32_t button_index);
void buttons_gpio_init(void);

#endif

使用NRF_GPIO_PIN_MAP() 宏进行引脚端口和编号之间的转换,BUTTONS_ACTIVE_STATE表示按键的触发电平,BUTTONS_LIST表示按键的编号列表。

 

4、关于“button_gpio.c”文件的内容,如下图所示。

#include "button_gpio.h"
#include 
#include 

static uint8_t m_button_list[BUTTONS_NUMBER] = BUTTONS_LIST;

bool get_button_state(uint32_t button_index) {
    ASSERT(button_index < BUTTONS_NUMBER);
    bool pin_set = nrf_gpio_pin_read(m_button_list[button_index]) ? true : false;
    return (pin_set == (BUTTONS_ACTIVE_STATE ? true : false));
}

void buttons_gpio_init(void) {
    uint32_t i;

    for (i = 0; i < BUTTONS_NUMBER; ++i){
        nrf_gpio_cfg_input(m_button_list[i], BUTTON_PULL);
    }
}

 

5、先来看一下buttons_gpio_init ()函数,这个函数是调用了nrf_gpio_cfg_input()函数来把按键的四个引脚配置为输出模式的,nrf_gpio_cfg_input()函数的原型,如下图所示。

__STATIC_INLINE void nrf_gpio_cfg_input(uint32_t pin_number, nrf_gpio_pin_pull_t pull_config)
{
    nrf_gpio_cfg(
        pin_number,
        NRF_GPIO_PIN_DIR_INPUT,
        NRF_GPIO_PIN_INPUT_CONNECT,
        pull_config,
        NRF_GPIO_PIN_S0S1,
        NRF_GPIO_PIN_NOSENSE);
}

由函数原型可知,函数的参数pin_number为引脚编号0 ~ 47,pull_config表示是否配置为上下拉或无上下拉。

 

6、对于nrf_gpio_cfg_input()函数,实际上是调用了nrf_gpio_cfg()函数进行配置,不难发现,除了pin_number和pull_config是用户自定义之外,其他参数均采用了默认值。因此,如果使用nrf_gpio_cfg_input()函数进行引脚配置,对应的GPIO会被配置为:输入方向、连接输入缓冲区、逻辑0和逻辑1标准驱动能力、关闭引脚电平感知。对于普通的引脚输入检测,使用默认参数即可。

 

7、再来看看get_button_state()函数,这个函数是用来获取按键状态的。实际上,这个函数是调用了nrf_gpio_pin_read()函数来获取引脚的状态,nrf_gpio_pin_read()的函数原型如下图所示。

__STATIC_INLINE uint32_t nrf_gpio_pin_read(uint32_t pin_number)
{
    NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number);

    return ((nrf_gpio_port_in_read(reg) >> pin_number) & 1UL);
}

继续跟踪nrf_gpio_port_in_read()函数,该函数是返回GPIO引脚的IN寄存器的值,函数的原型如下图所示。

__STATIC_INLINE uint32_t nrf_gpio_port_in_read(NRF_GPIO_Type const * p_reg)
{
    return p_reg->IN;
}

 

8、完成了按键的相关操作函数编写后,再来编写main.c文件,主函数int main(void)的内容如下图所示。

#include 
#include 
#include "nrf_delay.h"
#include "led_gpio.h"
#include "button_gpio.h"

int main(void)
{
    leds_gpio_init();
    buttons_gpio_init();

    while (true)
    {
        if(get_button_state(0)){
            nrf_delay_ms(200);
            if(get_button_state(0))set_led_toggle(0);
        }

        if(get_button_state(1)){
            nrf_delay_ms(200);
            if(get_button_state(1))set_led_toggle(1);
        }

        if(get_button_state(2)){
            nrf_delay_ms(200);
            if(get_button_state(2))set_led_toggle(2);
        }

        if(get_button_state(3)){
            nrf_delay_ms(200);
            if(get_button_state(3))set_led_toggle(3);
        }
    }
}

在主函数里面,首先调用了leds_gpio_init()和buttons_gpio_init(),进行LED和BUTTON的初始化。然后在主循环函数里面,不断检测四个按键,只要长按某一个按键,对应的LED灯就会以200ms的间隔进行闪烁。

 

9、连接好开发板,点击“Debug->Go”或按F5,即可编译程序并且把程序下载到开发板运行,程序的运行情况如以下视频所示。

https://www.bilibili.com/video/BV1Q541147iz/

 

10、源码下载链接:https://github.com/embediot/bluetooth_low_energy

 

物联网BLE裸机程序开发 -- (2)nRF52840配置GPIO输入检测按键_第4张图片

 

你可能感兴趣的:(物联网,BLE,应用开发)