1.硬件
1.1 开发板型号:ESP32-WROOM-32
1.2 需要外接一个RGB灯(共阳)
2.软件
2.1 控制的GPIO口:
使用创建新例程的例程,添加LED组件后,对应配置G2,G4,G5 这3个IO口,如下:
// 宏定义RGB-LED对应的GPIO口
#define BLINK_GPIO_R 2
#define BLINK_GPIO_G 4
#define BLINK_GPIO_B 5
2.1 初始化GPIO方式:
①第一种:单独IO初始化:
// GPIO初始化
gpio_reset_pin(BLINK_GPIO_R ); //#define BLINK_GPIO_R 2
// 设置GPIO口的模式为输出模式
gpio_set_direction(BLINK_GPIO_R , GPIO_MODE_OUTPUT);//配置模式
②同一模式,可以统一初始化,只需要操作初始化一次:
#define GPIO_OUTPUT_IO_0 18
#define GPIO_OUTPUT_IO_1 19
#define GPIO_OUTPUT_PIN_SEL ((1ULL<<GPIO_OUTPUT_IO_0) | (1ULL<<GPIO_OUTPUT_IO_1))
void led_init(void)
{
//zero-initialize the config structure.
gpio_config_t io_conf = {};
//disable interrupt
io_conf.intr_type = GPIO_INTR_DISABLE;
//set as output mode
io_conf.mode = GPIO_MODE_OUTPUT;
//bit mask of the pins that you want to set,e.g.GPIO18/19
io_conf.pin_bit_mask = GPIO_OUTPUT_PIN_SEL;
//disable pull-down mode
io_conf.pull_down_en = 0;
//disable pull-up mode
io_conf.pull_up_en = 0;
//configure GPIO with the given settings
gpio_config(&io_conf);
}
3.编写led.c和led.h文件如下:
编写led.c如下:
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "sdkconfig.h"
#include "led.h"
// 宏定义RGB-LED对应的GPIO口
#define BLINK_GPIO_R 2
#define BLINK_GPIO_G 4
#define BLINK_GPIO_B 5
// LED 结构体
typedef struct
{
int led_num; // GPIO
int delay_time; // 闪烁的间隔时间
int led_state; // LED当前的状态
} led_t;
// 定义rgb-led的初始化结构体,作为任务的传递参数
// tips:笔者运行是,结构体需要定义成全局变量才能正常运行
led_t led_rgb_init_r = {
.led_num = BLINK_GPIO_R,
.delay_time = 1000,
.led_state = 1,
};
led_t led_rgb_init_g = {
.led_num = BLINK_GPIO_G,
.delay_time = 2000,
.led_state = 1,
};
led_t led_rgb_init_b = {
.led_num = BLINK_GPIO_B,
.delay_time = 3000,
.led_state = 1,
};
// 用于接收Task得到空闲堆栈空间大小的返回值
UBaseType_t rbgTaski;
// 任务句柄,本例用于得到任务的空闲堆栈空间大小
TaskHandle_t rgbTaskHandle_r;
TaskHandle_t rgbTaskHandle_g;
TaskHandle_t rgbTaskHandle_b;
void led_init(void)
{
// 创建任务,传入之前定义的结构体参数
xTaskCreate(blink_led_Task, "LED_R", 2048, (void *)&led_rgb_init_r, 1, &rgbTaskHandle_r);
xTaskCreate(blink_led_Task, "LED_G", 2048, (void *)&led_rgb_init_g, 1, &rgbTaskHandle_g);
xTaskCreate(blink_led_Task, "LED_B", 2048, (void *)&led_rgb_init_b, 1, &rgbTaskHandle_b);
}
void led_prog(void)
{
// 得到任务的空闲堆栈大小
// 返回值越趋近于0,说明剩余空间越小
// 如果返回值为0或者可能为负,即堆栈溢出,会导致系统重启
// 不确定的时候可以先设置为一个较大的值,然后调试再适当调整
rbgTaski = uxTaskGetStackHighWaterMark(rgbTaskHandle_r);
// 打印得到的堆栈空间的大小
printf("rbgTaski = %d\t", rbgTaski);
rbgTaski = uxTaskGetStackHighWaterMark(rgbTaskHandle_g);
printf("rbgTaski = %d\t", rbgTaski);
rbgTaski = uxTaskGetStackHighWaterMark(rgbTaskHandle_b);
printf("rbgTaski = %d\n", rbgTaski);
}
// led闪烁函数的任务
void blink_led_Task(void *pvParam)
{
// 定义一个LED的结构体变量
led_t *led_rgb;
// 强制转换成对应的结构体类型
led_rgb = (led_t *)pvParam;
// GPIO初始化
gpio_reset_pin(led_rgb->led_num);
// 设置GPIO口的模式为输出模式
gpio_set_direction(led_rgb->led_num, GPIO_MODE_OUTPUT);
while (1)
{
// 设置GPIO的电平
gpio_set_level(led_rgb->led_num, led_rgb->led_state);
// 打印提示信息
// printf("The GPIO%d is %d.\n", led_rgb->led_num, led_rgb->led_state);
// 电平翻转
led_rgb->led_state = !(led_rgb->led_state);
//printf("The GPIO is \n");
// 延时一段时间
vTaskDelay((led_rgb->delay_time) / portTICK_PERIOD_MS);
}
}
编写led.h文件
void led_init(void);
void led_prog(void);
void blink_led_Task(void *pvParam);
编写mian.c 函数
#include <stdio.h>
#include "led.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
void app_main(void)
{
int cnt = 0;
led_init();
while (1)
{
led_prog();
printf("cnt: %d\n", cnt);
vTaskDelay(3000 / portTICK_PERIOD_MS);
}
}
4.编译与下载
编译下载后,RGB灯闪烁,完成!