ESPIDF-GPIO

管脚配置

1
esp_err_t gpio_config(const gpio_config_t *pGPIOConfig)

Configure GPIO’s Mode, pull-up, PullDown, IntrType
pGPIOConfig 为配置管脚的结构体指针

找到 gpio_config_t 如下所示:

1
2
3
4
5
6
7
typedef struct {
uint64_t pin_bit_mask; /*!< GPIO pin: set with bit mask, each bit maps to a GPIO */
gpio_mode_t mode; /*!< GPIO mode: set input/output mode */
gpio_pullup_t pull_up_en; /*!< GPIO pull-up */
gpio_pulldown_t pull_down_en; /*!< GPIO pull-down */
gpio_int_type_t intr_type; /*!< GPIO interrupt type */
} gpio_config_t;

pin_bit_mask

pin_bit_mask 设置的是管脚号,每一位对应相应的引脚,因为是 uint64_t 类型,应该用 ULL (unsigned long long),假设要配置的引脚号是 num,则:

1
io.pin_bit_mask = 1ULL << num;

mode

mode 配置的是输入/输出状态。

1
2
3
4
5
6
7
8
typedef enum {
GPIO_MODE_DISABLE = GPIO_MODE_DEF_DISABLE, /*!< GPIO mode : disable input and output */
GPIO_MODE_INPUT = GPIO_MODE_DEF_INPUT, /*!< GPIO mode : input only */
GPIO_MODE_OUTPUT = GPIO_MODE_DEF_OUTPUT, /*!< GPIO mode : output only mode */
GPIO_MODE_OUTPUT_OD = ((GPIO_MODE_DEF_OUTPUT) | (GPIO_MODE_DEF_OD)), /*!< GPIO mode : output only with open-drain mode */
GPIO_MODE_INPUT_OUTPUT_OD = ((GPIO_MODE_DEF_INPUT) | (GPIO_MODE_DEF_OUTPUT) | (GPIO_MODE_DEF_OD)), /*!< GPIO mode : output and input with open-drain mode*/
GPIO_MODE_INPUT_OUTPUT = ((GPIO_MODE_DEF_INPUT) | (GPIO_MODE_DEF_OUTPUT)), /*!< GPIO mode : output and input mode */
} gpio_mode_t;

pull_up_en & pull_down_en

使能上拉/下拉电阻。

1
2
3
4
5
6
7
8
9
typedef enum {
GPIO_PULLUP_DISABLE = 0x0, /*!< Disable GPIO pull-up resistor */
GPIO_PULLUP_ENABLE = 0x1, /*!< Enable GPIO pull-up resistor */
} gpio_pullup_t;

typedef enum {
GPIO_PULLDOWN_DISABLE = 0x0, /*!< Disable GPIO pull-down resistor */
GPIO_PULLDOWN_ENABLE = 0x1, /*!< Enable GPIO pull-down resistor */
} gpio_pulldown_t;

intr_type

中断触发方式。

1
2
3
4
5
6
7
8
9
typedef enum {
GPIO_INTR_DISABLE = 0, /*!< Disable GPIO interrupt */
GPIO_INTR_POSEDGE = 1, /*!< GPIO interrupt type : rising edge */
GPIO_INTR_NEGEDGE = 2, /*!< GPIO interrupt type : falling edge */
GPIO_INTR_ANYEDGE = 3, /*!< GPIO interrupt type : both rising and falling edge */
GPIO_INTR_LOW_LEVEL = 4, /*!< GPIO interrupt type : input low level trigger */
GPIO_INTR_HIGH_LEVEL = 5, /*!< GPIO interrupt type : input high level trigger */
GPIO_INTR_MAX,
} gpio_int_type_t;

设置电平

1
esp_err_t gpio_set_level(gpio_num_t gpio_num, uint32_t level)

gpio_num 为引脚号,level 为输出电平。
0:低电平 1:高电平

读取电平

1
int gpio_get_level(gpio_num_t gpio_num)

外部中断

首先打开 GPIO 全局中断服务。

1
esp_err_t gpio_install_isr_service(int intr_alloc_flags)

参数 intr_alloc_flags – Flags used to allocate the interrupt.
在 “esp_intr_alloc.h” 中有更多信息。

1
2
3
4
5
6
7
8
9
10
11
12
//Keep the LEVELx values as they are here; they match up with (1<<level)
#define ESP_INTR_FLAG_LEVEL1 (1<<1) ///< Accept a Level 1 interrupt vector (lowest priority)
#define ESP_INTR_FLAG_LEVEL2 (1<<2) ///< Accept a Level 2 interrupt vector
#define ESP_INTR_FLAG_LEVEL3 (1<<3) ///< Accept a Level 3 interrupt vector
#define ESP_INTR_FLAG_LEVEL4 (1<<4) ///< Accept a Level 4 interrupt vector
#define ESP_INTR_FLAG_LEVEL5 (1<<5) ///< Accept a Level 5 interrupt vector
#define ESP_INTR_FLAG_LEVEL6 (1<<6) ///< Accept a Level 6 interrupt vector
#define ESP_INTR_FLAG_NMI (1<<7) ///< Accept a Level 7 interrupt vector (highest priority)
#define ESP_INTR_FLAG_SHARED (1<<8) ///< Interrupt can be shared between ISRs
#define ESP_INTR_FLAG_EDGE (1<<9) ///< Edge-triggered interrupt
#define ESP_INTR_FLAG_IRAM (1<<10) ///< ISR can be called if cache is disabled
#define ESP_INTR_FLAG_INTRDISABLED (1<<11) ///< Return with this interrupt disabled

然后初始化GPIO,设置需要的触发方式。
IO初始化之后,注册中断服务函数并添加进芯片全局中断服务。当IO上产生对应的事件后,就会触发注册的函数。

1
esp_err_t gpio_isr_handler_add(gpio_num_t gpio_num, gpio_isr_t isr_handler, void *args)

例如

1
2
3
4
5
6
7
8
9
static void IRAM_ATTR isr_handler(void* arg)
{
// 中断服务函数
}

void app_main()
{
gpio_isr_handler_add(22,isr_handler,NULL); // 注册中断服务函数
}

如果某个时刻我们想将某个IO中断关闭可以使用下面的函数

1
esp_err_t gpio_isr_handler_remove(gpio_num_t gpio_num);