基于VScode的ESP32开发学习(一):官方例程blink,周期闪烁led详解,优信esp32简单修改适配

代码正文

我将注释给修改了下,方便理解

/* Blink Example*/
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "led_strip.h"
#include "sdkconfig.h"

static const char *TAG = "example";

/* 
    使用项目配置面板(idf.py menuconfig)来设置GPIO使led闪烁
    或者编辑下行代码来设置GPIO号
*/
#define BLINK_GPIO CONFIG_BLINK_GPIO

static uint8_t s_led_state = 0;
/*
#ifdef CONFIG_BLINK_LED_RMT
static led_strip_t *pStrip_a;

static void blink_led(void)
{
    /* If the addressable LED is enabled */
    if (s_led_state) {
        /* Set the LED pixel using RGB from 0 (0%) to 255 (100%) for each color */
        pStrip_a->set_pixel(pStrip_a, 0, 16, 16, 16);
        /* Refresh the strip to send data */
        pStrip_a->refresh(pStrip_a, 100);
    } else {
        /* Set all LED off to clear all pixels */
        pStrip_a->clear(pStrip_a, 50);
    }
}

static void configure_led(void)
{
    ESP_LOGI(TAG, "Example configured to blink addressable LED!");
    /* LED strip initialization with the GPIO and pixels number*/
    pStrip_a = led_strip_init(CONFIG_BLINK_LED_RMT_CHANNEL, BLINK_GPIO, 1);
    /* Set all LED off to clear all pixels */
    pStrip_a->clear(pStrip_a, 50);
}
*/

#ifdef CONFIG_BLINK_LED_GPIO

static void blink_led(void)
{
    /*设置引脚电平,来控制亮灭*/
    gpio_set_level(BLINK_GPIO, s_led_state);
}

static void configure_led(void)
{
    ESP_LOGI(TAG, "Example configured to blink GPIO LED!");
    gpio_reset_pin(BLINK_GPIO);                 //设置为推挽输出模式
    gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT);           //设置引脚方向:输出
}

#endif

void app_main(void)
{

    configure_led();                //根据led具体型号进行配置

    while (1) {
        ESP_LOGI(TAG, "Turning the LED %s!", s_led_state == true ? "ON" : "OFF");
        blink_led();
        s_led_state = !s_led_state;             //改变状态
        vTaskDelay(CONFIG_BLINK_PERIOD / portTICK_PERIOD_MS);               //延时1s
    }
}

运行效果
在这里插入图片描述

剖析

整个代码实现的功能很简单,配置led所在GPIO,循环控制引脚输出高低电平以控制led亮灭,同时串口输出信息。

1.定义led所在GPIO

#define BLINK_GPIO CONFIG_BLINK_GPIO

不得不说vscode确实方便,可以很快捷的跳转到定义上
这里跳转找到CONFIG_BLINK_GPIO定义语句
在这里插入图片描述
可以看到,GPIO2是led所在引脚,值得一提的是我是用的优信电子家的esp32开发板,管脚布局和乐鑫esp32还是有些许出入的,我从优信家要来相关开发板数据手册和与原理图
在这里插入图片描述
原文是CONFIG_BLINK_GPIO 5
我修改为CONFIG_BLINK_GPIO 2
这算是最简单的移植吧

2.定义led状态变量

static uint8_t s_led_state = 0;

3.条件编译
接下来可以看到代码里的

#ifdef
代码段
#elif
代码段
#endif

条件编译的具体作用,请自行百度学习,总之是开发项目中方便调试的必备用法

/*
#ifdef CONFIG_BLINK_LED_RMT
static led_strip_t *pStrip_a;

static void blink_led(void)
{
    /* If the addressable LED is enabled */
    if (s_led_state) {
        /* Set the LED pixel using RGB from 0 (0%) to 255 (100%) for each color */
        pStrip_a->set_pixel(pStrip_a, 0, 16, 16, 16);
        /* Refresh the strip to send data */
        pStrip_a->refresh(pStrip_a, 100);
    } else {
        /* Set all LED off to clear all pixels */
        pStrip_a->clear(pStrip_a, 50);
    }
}

static void configure_led(void)
{
    ESP_LOGI(TAG, "Example configured to blink addressable LED!");
    /* LED strip initialization with the GPIO and pixels number*/
    pStrip_a = led_strip_init(CONFIG_BLINK_LED_RMT_CHANNEL, BLINK_GPIO, 1);
    /* Set all LED off to clear all pixels */
    pStrip_a->clear(pStrip_a, 50);
}
*/

这里我们跳转看看定义,发现没有定义,也就是说该例程里它注定不会生效
在这里插入图片描述
从字面意思来说,CONFIG_BLINK_LED_RMT
远程配置led闪烁?

实际上从下面代码的注释不难看出
在这里插入图片描述
如果条件编译通过,我们可以配置led的RGB比例,来发出不同颜色的光。

那么这段注定不会生效的代码的作用也很明了了:
如果外设led用的是支持RGB的led,我们可以用该预编译里的功能,但实际上开发板上配置的蓝光led并不支持RGB功能,所以CONFIG_BLINK_LED_RMT没有被定义,此段预编译不会生效,为了方便理解,代码也就被我注释掉了。

继续看下一段代码

#ifdef CONFIG_BLINK_LED_GPIO

static void blink_led(void)
{
    /*设置引脚电平,来控制亮灭*/
    gpio_set_level(BLINK_GPIO, s_led_state);
}

static void configure_led(void)
{
    ESP_LOGI(TAG, "Example configured to blink GPIO LED!");
    gpio_reset_pin(BLINK_GPIO);                 //设置为推挽输出模式
    gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT);           //设置引脚方向:输出
}

#endif

跳转定义,我们看到CONFIG_BLINK_LED_GPIO是被定义为1的
在这里插入图片描述
所以这段预编译代码会生效
里面函数的功能,我已经注释了,很容易理解
就是用来配置led所在引脚的

至于推挽输出模式
参考:开漏输出(open drain)与推挽输出(push pull)学习详解及某个踩到的坑分享

4.主函数

void app_main(void)
{

    configure_led();                //根据led具体型号进行配置

    while (1) {
        ESP_LOGI(TAG, "Turning the LED %s!", s_led_state == true ? "ON" : "OFF");
        blink_led();
        s_led_state = !s_led_state;             //改变状态
        vTaskDelay(CONFIG_BLINK_PERIOD / portTICK_PERIOD_MS);               //延时1s
    }
}

相关功能我也有注释
里面有几句代码写法值得学习

这句里的条件运算符就用的很好

ESP_LOGI(TAG, "Turning the LED %s!", s_led_state == true ? "ON" : "OFF");

这里的延时函数也很巧妙

vTaskDelay(CONFIG_BLINK_PERIOD / portTICK_PERIOD_MS);               //延时1s

我们跳转CONFIG_BLINK_PERIOD的定义,可以看到设为1000
在这里插入图片描述
再看portTICK_PERIOD_MS
在这里插入图片描述
这个TickType_t是int(根据OS字长决定是32位还是16位)的别名,嵌入式开发常识了,不过我还是提一句

那么这个1000/configTICK_RATE_HZ
configTICK_RATE_HZ又是什么呢?
继续跳转
在这里插入图片描述
原来是时钟速率设为1000hz

及portTICK_PERIOD_MS=1000/configTICK_RATE_HZ=1ms
所以vTaskDelay(CONFIG_BLINK_PERIOD / portTICK_PERIOD_MS);
等价于vTaskDelay(1000/1000)=vTaskDelay(1)=1s

结束,该例程剖析完毕

后言

记录这篇博客的时候,感觉自己写的太细了,像在灌水,不过回想起自己刚入门嵌入式时的各种困惑,还是决定偏新手向一点,也算回顾知识点了。

修改GPIO引脚定义在头文件里改不行,会被配置文件重置
需要修改配置文件里的定义
在这里插入图片描述

sdkconfig文件使用参考

  • 11
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值