GPIO的基本配置
1. GPIO输出方式的基本配置
以初始化LED灯为例,代码如下:
//初始化LED
void Led_Init(void)
{
//选择 IO
gpio_pad_select_gpio(LED_R);
//设置 IO 为输出
gpio_set_direction(LED_R, GPIO_MODE_OUTPUT);
//设置默认电平为0
gpio_set_level(LED_R, 0);
}
2. GPIO输入的基本逻辑
以初始化按钮为例:
配置gpio_config_t 结构体的方式
void btn_Init(void)
{
gpio_config_t btn;
btn.pin_bit_mask = 1 << BUTTON_PIN;
btn.mode = GPIO_MODE_INPUT;
btn.pull_up_en = GPIO_PULLUP_ENABLE;
btn.pull_down_en = GPIO_PULLDOWN_DISABLE;
btn.intr_type = GPIO_INTR_DISABLE;
gpio_config(&btn);
}
测试代码
按键点灯:
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "sdkconfig.h"
#define LED_R 2
#define BUTTON_PIN 14
void app_main(void)
{
{
gpio_pad_select_gpio(LED_R); // 选择GPIO口
gpio_set_direction(LED_R, GPIO_MODE_OUTPUT); // GPIO作为输出
gpio_set_level(LED_R, 0); // 默认低电平
}
gpio_config_t btn;
btn.pin_bit_mask = 1 << BUTTON_PIN;//将端口指向按键
btn.mode = GPIO_MODE_INPUT;//设置为输入模式
btn.pull_up_en = GPIO_PULLUP_ENABLE;//禁用上拉输入
btn.pull_down_en = GPIO_PULLDOWN_DISABLE;//禁用下拉输入
btn.intr_type = GPIO_INTR_DISABLE;//禁用中断
gpio_config(&btn);
int level = 0;
while (1)
{
if(gpio_get_level(BUTTON_PIN) == 0)
{
vTaskDelay(pdMS_TO_TICKS(10)); //防抖动
if (gpio_get_level(BUTTON_PIN) == 0)
{
while (gpio_get_level(BUTTON_PIN) == 0);
level = ! level;
gpio_set_level(LED_R,level);
}
}
vTaskDelay(pdMS_TO_TICKS(10)); //防止看门狗复位
}
}
三、GPIO中断的逻辑
设置按键中断初始化:
void btn_Init(void)
{
gpio_config_t btn;
btn.pin_bit_mask = 1 << BUTTON_PIN;
btn.mode = GPIO_MODE_INPUT;
btn.pull_up_en = GPIO_PULLUP_ENABLE;
btn.pull_down_en = GPIO_PULLDOWN_DISABLE;
btn.intr_type = GPIO_INTR_DISABLE;
gpio_config(&btn);
gpio_install_isr_service(1)//注册中断服务
gpio_isr_handler_add(BUTTON_PIN, btn_isr_handler, (void*) BUTTON_PIN); //设置中断回调函数
}
用中断控制LED灯
#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "driver/gpio.h"
#include "esp_spi_flash.h"
#include "freertos/queue.h"
#define LED_R 2
#define BUTTON_PIN 14
static QueueHandle_t queue = NULL;
static int level1 = 0;
void LED_Init(void)
{
gpio_pad_select_gpio(LED_R); // 选择GPIO口
gpio_set_direction(LED_R, GPIO_MODE_OUTPUT); // GPIO作为输出
gpio_set_level(LED_R, 0); // 默认低电平
}
void led_task(void)
{
uint32_t gpio_num;
while (1)
{
if (xQueueReceive(queue, &gpio_num, portMAX_DELAY))
{
if (gpio_get_level(gpio_num) == 0 && level1==0)
{
level1=1;
gpio_set_level(LED_R, 0);
esp_rom_printf("LED is OFF!\n");
}
else if(gpio_get_level(gpio_num) == 0 && level1==1)
{
level1=0;
gpio_set_level(LED_R, 1);
esp_rom_printf("LED is ON!\n");
}
}
}
}
static void IRAM_ATTR btn_isr_handler(void *arg)
{
uint32_t gpio_num = (uint32_t) arg;
xQueueSendFromISR(queue, &gpio_num, NULL);
}
void btn_Init(void)
{
gpio_config_t btn;
btn.pin_bit_mask = 1 << BUTTON_PIN;
btn.mode = GPIO_MODE_INPUT;
btn.pull_up_en = GPIO_PULLUP_ENABLE;
btn.pull_down_en = GPIO_PULLDOWN_DISABLE;
btn.intr_type = GPIO_INTR_NEGEDGE;
gpio_config(&btn);
gpio_install_isr_service(1); //注册中断服务函数
gpio_isr_handler_add(BUTTON_PIN, btn_isr_handler, (void *)BUTTON_PIN); //设置中断回调函数
queue = xQueueCreate(5, sizeof(int));
xTaskCreate(led_task, "led_task", 2048, NULL, 7, NULL);
}
void app_main(void)
{
LED_Init();
btn_Init();
}
总结
GPIO的输入、输出和中断的配置最简化和实际运用的例程