打造一个通用性MCU架构,支持CX32/AT32/NRF51/NRF52等。 OS支持RTX4/RTX5/FreeRtos。 采用VsCode+GCC组合,VsCode+KEIL5,超强开发方式。 QQ群:524408033

LiSun

打造一个通用性MCU架构,支持CX32/AT32/NRF51/NRF52等。 OS支持RTX4/RTX5/FreeRtos。 采用VsCode+GCC组合,VsCode+KEIL5,超强开发方式。 QQ群:524408033

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

GPIO

The general purpose I/O is organized as one port with up to 32 I/Os (dependent on package) enabling access and control of up to 32 pins through one port. Each GPIO can be accessed individually with the following user configurable features:

  • Input/output direction
  • Output drive strength
  • Internal pull-up and pull-down resistors
  • Wake-up from high or low level triggers on all pins
  • Trigger interrupt on all pins
  • All pins can be used by the PPI task/event system. The maximum number of pins that can be interfaced through the PPI at the same time is limited by the number of GPIOTE channels.
  • All pins can be individually configured to carry serial interface or quadrature demodulator signals.

通用的I/O组织为一个端口多达32个I/O(依赖于包),允许通过一个端口访问和控制多达32个引脚。 每个GPIO都可以通过以下用户可配置的特性单独访问:

  • 输入/输出方向
  • 输出驱动强度
  • 内部上拉和下拉电阻
  • 从所有引脚的高或低电平触发器唤醒
    触发所有引脚中断
  • 所有引脚都可以被PPI任务/事件系统使用。 同时可以通过PPI接口的最大引脚数量受GPIOTE通道数量的限制。
  • 所有引脚都可以单独配置,以携带串行接口或正交解调器信号。

官方手册下载:
https://infocenter.nordicsemi.com/pdf/nRF51802_PS_v1.2.pdf
https://infocenter.nordicsemi.com/pdf/nRF51822_PS_v3.4.pdf
https://infocenter.nordicsemi.com/pdf/nRF51422_PS_v3.3.pdf

/********************************************************************************
* @file    bsp_gpio.c
* @author  jianqiang.xue
* @version V1.0.0
* @date    2021-04-09
* @brief   gpio初始化
********************************************************************************/

/* Includes ------------------------------------------------------------------*/
#include <stdint.h>

#include "RTE_Components.h"
#include CMSIS_device_header
#include "nrf_gpio.h"
#include "nrf_drv_gpiote.h"

#include "sdk_common.h"

#include "bsp_exti.h"
#include "bsp_gpio.h"

/* Private Includes ----------------------------------------------------------*/
#include "business_gpio.h"
#include "business_function.h"

/* Private Variables ---------------------------------------------------------*/
/* Private Function Prototypes -----------------------------------------------*/
static nrf_gpiote_polarity_t get_exti_event(bsp_gpio_exti_int_event_t exti_type)
{
    if (BSP_GPIO_EXTI_INT_LOWFALL == exti_type)
    {
        return NRF_GPIOTE_POLARITY_HITOLO;
    }
    else if (BSP_GPIO_EXTI_INT_HIGHRISE == exti_type)
    {
        return NRF_GPIOTE_POLARITY_LOTOHI;
    }
    else if (BSP_GPIO_EXTI_INT_FALLRISE == exti_type)
    {
        return NRF_GPIOTE_POLARITY_TOGGLE;
    }
    else
    {
        return NRF_GPIOTE_POLARITY_TOGGLE;
    }
}

static nrf_gpio_pin_pull_t get_nrf_pull(bsp_gpio_pin_pull_t pull)
{
    if (pull == BSP_GPIO_PIN_PULLUP)
    {
        return NRF_GPIO_PIN_PULLUP;
    }
    else if(pull == BSP_GPIO_PIN_PULLDOWN)
    {
        return NRF_GPIO_PIN_PULLDOWN;
    }
    else
    {
        return NRF_GPIO_PIN_NOPULL;
    }
}

/* Public Function Prototypes ------------------------------------------------*/
/**
 * @brief  [反初始化] 关闭指定引脚功能(恢复为浮空输入)
 * @note   NULL
 * @param  *gpiox: NULL
 * @param  pin: 引脚号
 * @retval None
 */
void bsp_gpio_deinit(void *gpiox, uint8_t pin)
{
    nrf_gpio_cfg_default(pin);
}

/**
 * @brief  [初始化] 引脚设置为输出模式
 * @note   NULL
 * @param  *gpiox: NULL
 * @param  pin: 引脚号
 * @param  out_mode:  BSP_GPIO_PIN_OUT_OD 开漏输出, BSP_GPIO_PIN_OUT_PP 推免输出, BSP_GPIO_PIN_AF_OD 复用开漏, BSP_GPIO_PIN_AF_PP 复用推免
 * @retval None
 */
void bsp_gpio_init_output(void *gpiox, uint8_t pin, bsp_gpio_pin_out_t out_mode)
{
    nrf_gpio_cfg_output(pin);
}

/**
 * @brief  [初始化] 引脚设置为输入模式
 * @note   NULL
 * @param  *gpiox: NULL
 * @param  pin: 引脚号
 * @param  pull: BSP_GPIO_PIN_NOPULL 无上下拉, BSP_GPIO_PIN_PULLUP 上拉输入, BSP_GPIO_PIN_PULLDOWN 下拉输入
 * @retval None
 */
void bsp_gpio_init_input(void *gpiox, uint8_t pin, bsp_gpio_pin_pull_t pull)
{
    nrf_gpio_cfg_input(pin, get_nrf_pull(pull));
}

extern void gpiote_event_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action);
/**
  * @brief  [初始化] 引脚设置为[输入+中断]模式
  * @param  gpiox           -- NULL
  * @param  pin             -- 引脚号
  * @param  irqn            -- NULL
  * @param  exti_type       -- BSP_GPIO_EXTI_INT_LEVEL 电平触发, BSP_GPIO_EXTI_INT_EDGE 边沿触发
  * @param  exti_event      -- BSP_GPIO_EXTI_INT_LOWFALL 低电平触发(下降沿), BSP_GPIO_EXTI_INT_HIGHRISE 高电平触发(上降沿), BSP_GPIO_EXTI_INT_FALLRISE 高低电平触发或任意电平变化
  * @param  pull            -- BSP_GPIO_PIN_NOPULL 无上下拉, BSP_GPIO_PIN_PULLUP 上拉输入, BSP_GPIO_PIN_PULLDOWN 下拉输入
  */
void bsp_gpio_init_input_exit(void *gpiox, uint8_t pin, uint8_t irqn,
                              bsp_gpio_exti_int_type_t exti_type,
                              bsp_gpio_exti_int_event_t exti_event,
                              bsp_gpio_pin_pull_t pull)
{
    static bool flag = 0;
    ret_code_t err_code;

    if (flag == 0)
    {
        err_code = nrf_drv_gpiote_init();
        APP_ERROR_CHECK(err_code);
        flag = 1;
    }

    nrf_drv_gpiote_in_config_t config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(exti_type);
    config.pull = get_nrf_pull(pull);
    config.sense = get_exti_event(exti_event);
    err_code = nrf_drv_gpiote_in_init(pin, &config, gpiote_event_handler);
    APP_ERROR_CHECK(err_code);
    nrf_drv_gpiote_in_event_enable(pin, true);
}

/**
 * @brief  设置引脚电平状态
 * @note   NULL
 * @param  *gpiox: NULL
 * @param  pin: 引脚号
 * @param  state: BSP_GPIO_PIN_RESET 低电平, BSP_GPIO_PIN_SET 高电平
 * @retval None
 */
void bsp_gpio_set_pin(void *gpiox, uint8_t pin, bsp_gpio_pin_state_t state)
{
    if (state)
    {
        nrf_gpio_pin_set(pin);
    }
    else
    {
        nrf_gpio_pin_clear(pin);
    }
}

/**
 * @brief  翻转引脚电平状态
 * @note   NULL
 * @param  *gpiox: NULL
 * @param  pin: 引脚号
 * @retval None
 */
void bsp_gpio_set_toggle(void *gpiox, uint8_t pin)
{
    nrf_gpio_pin_toggle(pin);
}

/**
 * @brief  得到指定gpio状态
 * @note   NULL
 * @param  *gpiox: NULL
 * @param  pin: 引脚号
 * @retval 0 -- 低电平, 1 -- 高电平
 */
bool bsp_gpio_get_state(void *gpiox, uint8_t pin)
{
    return (bool)nrf_gpio_pin_read(pin);
}

/**
 * @brief  将指定引脚复用为ADC引脚(复用模拟输入)
 * @note   NULL
 * @param  *gpiox: NULL
 * @param  pin: 引脚号
 * @retval None
 */
void bsp_gpio_init_adc(void *gpiox, uint8_t pin)
{
}

/**
 * @brief  初始化i2c引脚
 * @note   NULL
 * @param  *gpiox: NULL
 * @param  pin: 引脚号
 * @param  arf: 复用值
 * @retval None
 */
void bsp_gpio_init_i2c(void *gpiox, uint8_t pin, uint8_t arf)
{
}

/**
 * @brief  初始化uart引脚
 * @note   NULL
 * @param  *gpiox: NULL
 * @param  pin: 引脚号
 * @param  arf: 复用值
 * @retval None
 */
void bsp_gpio_init_uart(void *gpiox, uint8_t pin, uint8_t arf)
{
}

/**
 * @brief  初始化tim_ch引脚
 * @note   NULL
 * @param  *gpiox: NULL
 * @param  pin: 引脚号
 * @param  arf: 复用值
 * @retval None
 */
void bsp_gpio_init_tim(void *gpiox, uint8_t pin, uint8_t arf)
{
}

/********************************************************************************
* @file    bsp_gpio.h
* @author  jianqiang.xue
* @version V1.0.0
* @date    2021-04-09
* @brief   GPIO控制
********************************************************************************/

#ifndef __BSP_GPIO_H
#define __BSP_GPIO_H

/* Includes ------------------------------------------------------------------*/
#include <stdint.h>
#include <stdbool.h>

/* Public enum ---------------------------------------------------------------*/
/**
 * @brief  GPIO Bit SET and Bit RESET enumeration
 */
typedef enum
{
    BSP_GPIO_PIN_RESET = 0U,
    BSP_GPIO_PIN_SET
} bsp_gpio_pin_state_t;

typedef enum
{
    BSP_GPIO_PIN_NOPULL = 0U,
    BSP_GPIO_PIN_PULLUP,
    BSP_GPIO_PIN_PULLDOWN
} bsp_gpio_pin_pull_t;

typedef enum
{
    BSP_GPIO_PIN_OUT_OD = 0U,
    BSP_GPIO_PIN_OUT_PP,
    BSP_GPIO_PIN_AF_OD,
    BSP_GPIO_PIN_AF_PP
} bsp_gpio_pin_out_t;

typedef enum
{
    BSP_GPIO_EXTI_INT_LEVEL = 0U,     // 电平触发
    BSP_GPIO_EXTI_INT_EDGE,           // 边沿触发
} bsp_gpio_exti_int_type_t;

typedef enum
{
    BSP_GPIO_EXTI_INT_LOWFALL = 0U,   // 低电平触发(下降沿)
    BSP_GPIO_EXTI_INT_HIGHRISE,       // 高电平触发(上降沿)
    BSP_GPIO_EXTI_INT_FALLRISE        // 高低电平触发或任意电平变化
} bsp_gpio_exti_int_event_t;

/* Public Function Prototypes ------------------------------------------------*/

// 常规引脚初始化

void bsp_gpio_deinit(void *gpiox, uint8_t pin);
void bsp_gpio_init_output(void *gpiox, uint8_t pin, bsp_gpio_pin_out_t out_mode);
void bsp_gpio_init_input(void *gpiox, uint8_t pin, bsp_gpio_pin_pull_t pull);
void bsp_gpio_init_input_exit(void *gpiox, uint8_t pin, uint8_t irqn, bsp_gpio_exti_int_type_t exti_type, bsp_gpio_exti_int_event_t exti_event, bsp_gpio_pin_pull_t pull);

// 外设引脚初始化

void bsp_gpio_init_adc(void *gpiox, uint8_t pin);
void bsp_gpio_init_i2c(void *gpiox, uint8_t pin, uint8_t arf);
void bsp_gpio_init_uart(void *gpiox, uint8_t pin, uint8_t arf);
void bsp_gpio_init_tim(void *gpiox, uint8_t pin, uint8_t arf);

// 引脚控制和状态获取

void bsp_gpio_set_pin(void *gpiox, uint8_t pin, bsp_gpio_pin_state_t state);
void bsp_gpio_set_toggle(void *gpiox, uint8_t pin);
bool bsp_gpio_get_state(void *gpiox, uint8_t pin);

#endif

posted on 2022-08-13 11:00  xuejianqiang  阅读(29)  评论(0编辑  收藏  举报
打造一个通用性MCU架构,支持CX32/AT32/NRF51/NRF52等。 OS支持RTX4/RTX5/FreeRtos。 采用VsCode+GCC组合,VsCode+KEIL5,超强开发方式。 QQ群:524408033