vs code 创建esp-idf工程-添加自定义组件
- 使用espressif插件创建hello world工程,并以此为模板,继续下面学习。模板创建成功后,复制模板工程开始下一个led示例,而不是每次都使用插件创建example工程。
- esp-idf内置FreeRTOS,因此实际项目肯定会使用到FreeRTOS内容,本文还将使用task方式实现led功能。
一、创建模板工程
-
打开vscode 进入espressif插件,CTRL + shift + P打开命令面板,选择ESP-IDF 展示项目
-
选择模板工程,并创建项目,选择目录,不可中文路径!
-
配置工程 下载端口和目标芯片,并设置sdk相关内容,hello world 默认主频160MHz,flash大小2M。
-
编译下载打印
二、复制模板创建LED示例
1、复制工程
- 复制刚刚创建的模板工程,命名led,无需复制build文件夹
- src放置gpio_led.c文件,include放置gpio_led.h文件
2、编写cmake文件
- 编写led文件夹下的cmake文件
- 注意esp-idf v5.0开始,将一些组件不再设置为通用组件,cmake文件内需要“REQUIRES xxx”,详情请看乐鑫官方文档
idf_component_register(SRCS "src/gpio_led.c"
REQUIRES driver
INCLUDE_DIRS "include")
esp-idf5.0开始,注意cmake以下信息,否则编译报错driver/gpio.h no such file
3、编写GPIO_LED组件代码
- gpio_led.c文件编写相关代码
- gpio_set_direction只是设置输入或输出,其它GPIO参数都是默认
- gpio_config可以详细配置,可以将GPIO同时设置输出输入
#include "gpio_led.h"
void gpio_led_init(gpio_num_t led_io_num, uint32_t level)
{
/*
gpio_reset_pin(led_io_num);
gpio_set_direction(led_io_num, GPIO_MODE_OUTPUT);
led_set(led_io_num, level);
*/
gpio_config_t io_conf; //gpio配置句柄
io_conf.intr_type = GPIO_INTR_DISABLE; //IO中断类型:禁止中断
io_conf.mode = GPIO_MODE_INPUT_OUTPUT; //IO模式:输入输出
io_conf.pin_bit_mask = (1ULL<<led_io_num); //配置管脚编号
io_conf.pull_down_en = 0; //下拉禁止
io_conf.pull_up_en = 0; //上拉禁止
gpio_config(&io_conf); //初始化
gpio_set_level(led_io_num, level); //上电初始化默认输出
}
void gpio_led_on(gpio_num_t led_io_num)
{
gpio_set_level(led_io_num, 1);
}
void gpio_led_off(gpio_num_t led_io_num)
{
gpio_set_level(led_io_num, 0);
}
void gpio_led_blink(gpio_num_t led_io_num)
{
uint8_t level = 0;
level = gpio_get_level(led_io_num);
gpio_set_level(led_io_num, !level);
}
uint8_t gpio_led_get_status(gpio_num_t led_io_num)
{
return gpio_get_level(led_io_num);
}
- gpio_led.h文件代码
#ifndef __GPIO_LED_H__
#define __GPIO_LED_H__
#include "driver/gpio.h"
void gpio_led_init(gpio_num_t led_io_num, uint32_t level);
void gpio_led_on(gpio_num_t led_io_num);
void gpio_led_off(gpio_num_t led_io_num);
void gpio_led_blink(gpio_num_t led_io_num);
uint8_t gpio_led_get_status(gpio_num_t led_io_num);
#endif
4、编写main.c代码
#include <stdio.h>
#include <inttypes.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "gpio_led.h"
#define DEMO_LED_GPIO_NUM 40 //开发板IO40
void app_main(void)
{
printf("led example start\n");
printf("led init OFF\n");
gpio_led_init(DEMO_LED_GPIO_NUM,0);
while (1)
{
gpio_led_blink(DEMO_LED_GPIO_NUM);
printf("led state is %s\n",(gpio_led_get_status(DEMO_LED_GPIO_NUM)) ? "on" : "off");
vTaskDelay(500 / portTICK_PERIOD_MS);
}
}
5、编译下载打印
I (326) gpio: GPIO[40]| InputEn: 1| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 是ESP_LOGI输出的。
三、FreeRTOS创建LED任务
- 只需要改写main.c代码即可
#define DEMO_LED_GPIO_NUM 40
static void led_task(void* arg)
{
while (1)
{
gpio_led_blink(DEMO_LED_GPIO_NUM);
printf("led state is %s\n",(gpio_led_get_status(DEMO_LED_GPIO_NUM)) ? "on" : "off");
vTaskDelay(500 / portTICK_PERIOD_MS);
}
}
void app_main(void)
{
printf("led example start\n");
printf("led init OFF\n");
gpio_led_init(DEMO_LED_GPIO_NUM,0);
xTaskCreate(led_task, "led_task", 2048, NULL, 3, NULL);//使用printf,需要更多堆栈空间,否则可能导致堆栈溢出,设备重启
}