2.esp32s3-GPIO输入输出
·
再开始一个单片机的学习之前,如果无从下手,可以先从他人视频或者官方文档找灵感。
官方文档编程指南:
GPIO & RTC GPIO - ESP32-S3 - — ESP-IDF 编程指南 v5.5.1 文档
一、外设初始化:
1.gpio_config()初始化对应IO口输入输出等模式
结构体参数赋值:
/**
* @brief Configuration parameters of GPIO pad for gpio_config function
*/
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 */
#if SOC_GPIO_SUPPORT_PIN_HYS_FILTER
gpio_hys_ctrl_mode_t hys_ctrl_mode; /*!< GPIO hysteresis: hysteresis filter on slope input */
#endif
} gpio_config_t;
不同于32,我们需要在CMakeLists文件中进行配置
ESP-IDF 是 组件(component)系统,用 CMake 管理,需要显示声明依赖
如果用到了 driver/gpio.h 要加上REQUIRES driver ;意思是 我这个代码要用到 driver 这个库,请把它加进工程。
二、实现代码逻辑
//设置电平
esp_err_t gpio_set_level(gpio_num_t gpio_num, uint32_t level)
{
GPIO_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "GPIO output gpio_num error", ESP_ERR_INVALID_ARG);
gpio_hal_set_level(gpio_context.gpio_hal, gpio_num, level);
return ESP_OK;
}
//获取电平
int gpio_get_level(gpio_num_t gpio_num)
{
return gpio_hal_get_level(gpio_context.gpio_hal, gpio_num);
}
需要注意的是:
main函数最后要加 vTaskDelay(10 / portTICK_PERIOD_MS) 进行延时操作
freertos要求每个线程任务必须都要有阻塞 :
(1)方便各个任务切换 (2)延时是最简单的任务阻塞
ESP-IDF框架内部默认打开了看门狗
添加多个文件的时候,必须要修改CmakeLists
三、通过线程创建来控制按键开关灯
#include <stdio.h>
#include <inttypes.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_chip_info.h"
#include "esp_flash.h"
#include "esp_system.h"
#include "driver/gpio.h"
#define LED_PIN GPIO_NUM_1 // LED连接的GPIO引脚
#define KEY_PIN GPIO_NUM_40 // 按键连接的GPIO引脚
// 任务函数:控制LED闪烁
void led_task(void *pvParameters)
{
while(1)
{
gpio_set_level(LED_PIN, 1);
vTaskDelay(1000 / portTICK_PERIOD_MS); // 延时1秒
gpio_set_level(LED_PIN, 0);
vTaskDelay(1000 / portTICK_PERIOD_MS); // 延时1秒
}
}
void app_main(void)
{
printf("\n*****************\nIO TEST Demo!\n*****************\n");
// 配置LED引脚
gpio_config_t led_conf = {
.pin_bit_mask = (1ULL << LED_PIN),
.mode = GPIO_MODE_OUTPUT,
.pull_up_en = GPIO_PULLUP_ENABLE,
.pull_down_en = GPIO_PULLDOWN_DISABLE,
.intr_type = GPIO_INTR_DISABLE
};
gpio_config(&led_conf);
// 配置按键引脚(启用内部上拉,未按下时为高电平)
gpio_config_t key_conf = {
.pin_bit_mask = (1ULL << KEY_PIN),
.mode = GPIO_MODE_INPUT,
.pull_up_en = GPIO_PULLUP_ENABLE,
.pull_down_en = GPIO_PULLDOWN_DISABLE,
.intr_type = GPIO_INTR_DISABLE
};
gpio_config(&key_conf);
xTaskCreate(
led_task, // 任务函数
"led_task", // 任务名称
2048, // 任务栈大小(字节)
NULL, // 任务参数
5, // 任务优先级
NULL // 任务句柄
);
while(1)
{
// 读取按键状态
if(gpio_get_level(KEY_PIN) == 0) // 按键按下时为低电平
{
if (gpio_get_level(KEY_PIN) == 0) // 再次确认
{
// 等待释放
while (gpio_get_level(KEY_PIN) == 0)
{
vTaskDelay(10 / portTICK_PERIOD_MS); // 不要忙等
}
vTaskDelay(20/ portTICK_PERIOD_MS); // 去抖释放
printf("Key pressed\n");
}
}
vTaskDelay(10 / portTICK_PERIOD_MS);
}
}
更多推荐
所有评论(0)