重新学习ESP32(一)之点亮一个LED灯

前言

其实本篇文章才算学习单片机第一个要做的实验,通常称之为点灯说白了就是点亮一个LED灯,可是为什么都先学习点亮LED灯呢?我想主要是简单,而且可以让初学者真正的看到实验现象,也算是踏入了单片机世界的大门吧

废话不多说,下面开始我们的点灯程序,本篇文章会带你理顺ESP32开发的大体流程~

COPY例程

首先我们打开mingw32运行环境,然后输入以下命令,请确保你已经创建了projects文件夹。

cp -r $IDF_PATH/examples/get-started/blink/  ~/projects/  && cd projects

这里开发方式是SDK跟项目分离的,通过$IDF_PATH这个环境变量连接起来的,所以项目树是很简洁的,下一篇文章我们会从头开始创建一个项目而不是再copy例程,这里我们先copy例程为我们所用。

分析例程

下面我们打开main文件下的blink.c文件(这里可以在Windows下找到相应目录下的文件用编辑器打开,mingw32只作为我们编译工程的一个编译器用,当然也可以在Windows下复制相应的工程到别的目录)
我们可以看到代码的结构如下,下面我们来分析以下代码。

/*
 * 包含相应的头文件
 * stdio.h -> C语言标准库 
 * FreeRTOS.h -> 实时操作系统相关 -> esp-idf/components/freertos/include/freertos/FreeRTOS.h
 * task.h -> 任务处理相关   -> esp-idf/components/freertos/include/freertos/tsak.h
 * gpio.h -> GPIO处理相关  -> esp-idf/components/esp32/include/rom/gpio.h
 * sdkconfig.h -> SDK相关  -> blink/build/include/sdkconfig.h
*/
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "sdkconfig.h"
/* Can run 'make menuconfig' to choose the GPIO to blink,
   or you can edit the following line and set a number here.
*/
/*
 * CONFIG_BLINK_GPIO -> 可以通过make menuconfig 指定管脚
 * 也可以将 >CONFIG_BLINK_GPIO<改成某个指定的管脚
*/
#define BLINK_GPIO CONFIG_BLINK_GPIO
void blink_task(void *pvParameter)                      //创建的任务
{
    /* Configure the IOMUX register for pad BLINK_GPIO (some pads are
       muxed to GPIO on reset already, but some default to other
       functions and need to be switched to GPIO. Consult the
       Technical Reference for a list of pads and their default
       functions.)
    */
    gpio_pad_select_gpio(BLINK_GPIO);                  //这句的作用是有些管脚会复用,这个管脚作为GPIO用
    /* Set the GPIO as a push/pull output */
    gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT);  //设置管脚为输出模式
    while(1) {                                         //while循环 1 -> 条件在任何时候都成立,所以程序会一直在这个while循环里执行
        /* Blink off (output low) */
        gpio_set_level(BLINK_GPIO, 0);                 //让管脚输出低电平,0 -> 低电平
        vTaskDelay(1000 / portTICK_PERIOD_MS);         //延时任务 1s
        /* Blink on (output high) */
        gpio_set_level(BLINK_GPIO, 1);                 //让管脚输出低电平,1 -> 高电平          
        vTaskDelay(1000 / portTICK_PERIOD_MS);         //延时任务 1s
    }
}
void app_main()
{
    /* 函数原型 task.h -> 430L
	xTaskCreate(
			TaskFunction_t pvTaskCode,
			const char * const pcName,
			const uint32_t usStackDepth,
			void * const pvParameters,
			UBaseType_t uxPriority,
			TaskHandle_t * const pvCreatedTask)
	*/
    xTaskCreate(&blink_task,              //指向创建的任务的一个指针
    			"blink_task", 			  //创建的任务名称(函数名)
    			configMINIMAL_STACK_SIZE, //设置堆的大小
    			NULL,                     //任务参数的指针,这里为空
    			5,                        //任务的优先级
    			NULL);                    //创建任务的句柄
}

下载测试

分析完了我们来下载测试一下代码,首先我们先跟上一节一样设置一下端口号。

make menuconfig # 设置好端口号,其它的先不用管,这里CONFIG_BLINK_GPIO默认为5
make all # 编译
make flash # 下载

下载完成后,我们还需要把硬件电路搭建好,比较简单,直接给大家上个图,我这里串联了一个1K的电阻限流。
blink_gif
怎么样?是不是看见LED开始闪烁起来了恭喜你,成功驱动管脚输出高低电平,那我们输出高低电平有什么用呢?难道只可以用来点灯吗?
其实用处可大了,你可以控制很多很多东西,比如灯,继电器,三色灯,三极管等很多东西
在单片机的世界里,高低电平是最基础的的知识,也是最核心的知识~可以说,所有的功能最终都是0跟1的功劳。

修改代码

那么我们假如想让别的管脚控制LED的闪烁怎么办呢?又或者改变LED闪烁的频率?
我们只需要更改三个地方就可以改成别的管脚还能加快LED的闪烁频率!比如说我们让18号管脚没隔0.5s闪烁一次。

#define BLINK_GPIO 18   //CONFIG_BLINK_GPIO -> 18
vTaskDelay(500 / portTICK_PERIOD_MS); //500 -> 500

然后我们编译后重新下载一次,不要忘了将电阻接到18管脚上,是不是闪烁速度变快了呢~

一些GPIO的操作函数

下面我们看一下关于GPIO口操作的一些函数:

//GPIO配置,配置GPIO的模式,上拉,下拉,中断
esp_err_t gpio_config(constgpio_config_t *pGPIOConfig );
//复位管脚为初始状态
esp_err_t gpio_reset_pin(gpio_num_t gpio_num );
//设置GPIO的中断触发类型,常见的有上升沿触发,下降沿触发,低电平触发,高电平触发
esp_err_t gpio_set_intr_type(gpio_num_t gpio_num, gpio_int_type_t intr_type);
//GPIO中断使能
esp_err_t gpio_intr_enable(gpio_num_t gpio_num);
//取消GPIO的中断触发
esp_err_t gpio_intr_disable(gpio_num_t gpio_num);
//设置GPIO的电平, 0 -> 电平, 1 -> 高电平
esp_err_t gpio_set_level(gpio_num_t gpio_num, uint32_t level);
//获取GPIO的电平,返回值 0 -> 低电平,1 -> 高电平
int gpio_get_level(gpio_num_t gpio_num)
//设置GPIO的模式,常见有输入、输出、推挽、浮空、输入输出
esp_err_t gpio_set_direction(gpio_num_t gpio_num, gpio_mode_t mode);
//设置GPIO的上下拉
esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull);
//使能GPIO的唤醒功能
esp_err_t gpio_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type);
//取消GPIO的唤醒功能
esp_err_t gpio_wakeup_disable(gpio_num_t gpio_num);
//注册GPIO的中断处理程序
esp_err_t gpio_isr_register(void (*fn)(void *), void *arg, int intr_alloc_flags, gpio_isr_handle_t *handle, );
//GPIO上拉使能
esp_err_t gpio_pullup_en(gpio_num_t gpio_num);
//GPIO上拉取消
esp_err_t gpio_pullup_dis(gpio_num_t gpio_num);
//GPIO下拉使能
esp_err_t gpio_pulldown_en(gpio_num_t gpio_num);
//GPIO下拉取消
esp_err_t gpio_pulldown_dis(gpio_num_t gpio_num);
//注册GPIO ISR 服务函数
esp_err_t gpio_install_isr_service(int intr_alloc_flags);
//取消GPIO ISR 服务函数
void gpio_uninstall_isr_service();
//为某一个引脚增加ISR服务函数
esp_err_t gpio_isr_handler_add(gpio_num_t gpio_num, gpio_isr_t isr_handler, void *args);
//移除某个引脚的ISR服务函数
esp_err_t gpio_isr_handler_remove(gpio_num_t gpio_num);

还有一部分没有列出来,可以去官方的文档去看一下,很多我也还没用过,后面我们将会继续深入学习这些函数怎么使用。
官方的GPIO文档:点这里

欢迎访问我的主页,我会不定期更新一些文章,也欢迎留言哦~
唯有爱与科技不可辜负

请我喝一罐冰阔乐 (^o^)/