本次开发是在Ubuntu下的,使用的模块是ESP12F,32Mbit的flash。程序基于ESP8266_RTOS_SDK-3.x的工程 。
复制hello_world文件并命名为led_key,修改hello_world_main.c为app_main.c;
然后将工作区保存在led_key文件夹下:
通过硬件原理图查询可得,ESP12F上自带的LED连在GPIO2上;所以首先宏定义LED的引脚编号:
#define GPIO_LED_NUM 2
然后定义一个gpio配置结构体
/* 定义一个gpio配置结构体 */
gpio_config_t gpio_config_structure;
对该结构体进行初始化,配置并使能
/* 初始化gpio配置结构体*/
gpio_config_structure.pin_bit_mask = (1ULL << GPIO_LED_NUM);/* 选择gpio2 */
gpio_config_structure.mode = GPIO_MODE_OUTPUT; /* 输出模式 */
gpio_config_structure.pull_up_en = 0; /* 不上拉 */
gpio_config_structure.pull_down_en = 0; /* 不下拉 */
gpio_config_structure.intr_type = GPIO_INTR_DISABLE; /* 禁止中断 */
/* 根据设定参数初始化并使能 */
gpio_config(&gpio_config_structure);
然后将其设为高电平,点亮该LED灯:
/* 输出低电平,点亮LED*/
gpio_set_level(GPIO_LED_NUM, 0);
我们编写一个while循环,让LED一秒闪烁一次
while(1)
{
gpio_set_level(GPIO_LED_NUM, 1); /* 熄灭 */
vTaskDelay(500 / portTICK_PERIOD_MS); /* 延时500ms*/
gpio_set_level(GPIO_LED_NUM, 0); /* 点亮 */
vTaskDelay(500 / portTICK_PERIOD_MS); /* 延时500ms*/
}
烧录,运行结果:
查看硬件原理图,BOOT按键连在GPIO0上,并且已经上拉;所以首先宏定义BOOT按键的引脚编号
#define GPIO_KEY_NUM 0
然后对gpio配置结构体进行初始化,配置并使能
/* 初始化gpio配置结构体*/
gpio_config_structure.pin_bit_mask = (1ULL << GPIO_KEY_NUM);/* 选择gpio0 */
gpio_config_structure.mode = GPIO_MODE_INPUT; /* 输入模式 */
gpio_config_structure.pull_up_en = 0; /* 不上拉 */
gpio_config_structure.pull_down_en = 0; /* 不下拉 */
gpio_config_structure.intr_type = GPIO_INTR_DISABLE; /* 禁止中断 */
/* 根据设定参数初始化并使能 */
gpio_config(&gpio_config_structure);
然后我们1s查询一次按键电平,并打印出来
while(1)
{
printf("Boot_key Level is : %d \n",gpio_get_level(GPIO_KEY_NUM)); /* 获取BOOT按键电平并打印 */
vTaskDelay(1000 / portTICK_PERIOD_MS); /* 延时1000ms*/
}
我们创建一个按键检测任务检测是否有按键按下,在主任务里执行LED的闪烁
首先我们查看一下这个freeRTOS的优先级可选范围,查询得知configMAX_PRIORITIES=15
,所以任务优先级可选范围为0~14
,且数字越大,优先级越高!
/* 定义按键检测任务的任务句柄*/
TaskHandle_t Key_Task_Handler;
/* 声明按键检测任务函数 */
void key_task(void *pvParameters);
然后在主任务里创建按键检测任务,
/* 创建按键检测任务 */
xTaskCreate((TaskFunction_t )key_task, /* 任务函数 */
(const char* )"key task", /* 任务名称*/
(uint16_t )2048, /* 任务堆栈大小,单位为字节*/
(void* )NULL, /* 传递给任务函数的参数*/
(UBaseType_t )10, /* 任务优先级,最高优先级为24 */
(TaskHandle_t* )Key_Task_Handler); /* 任务句柄,在不需要使用任务句柄时,可以填入NULL*/
然后我们实现按键检测任务函数,注意,portTICK_PERIOD_MS
的值为10,即RTOS的一个时间片为10ms,则使用vTaskDelay()函数进行延时,不能小于10ms
/* 按键检测任务函数 */
void key_task(void *pvParameters)
{
static int key_up = 1; /* 按键松开标志 */
while (1)
{
/* 检测按键是否按下 */
if (key_up && (gpio_get_level(GPIO_KEY_NUM) == 0) )
{
vTaskDelay(50 / portTICK_PERIOD_MS); /* 延时50ms消抖*/
key_up = 0;
if (gpio_get_level(GPIO_KEY_NUM) == 0)
{
/* 按键BOOT按下,按键按下处理*/
printf("BOOT Key pressed!\n");
}
}
else if(gpio_get_level(GPIO_KEY_NUM) == 1 )
{
key_up = 1; /* 按键已松开 */
}
vTaskDelay(100 / portTICK_PERIOD_MS);
}
}
/* 创建按键检测任务 */
xTaskCreate((TaskFunction_t )key_task, /* 任务函数 */
(const char* )"key task", /* 任务名称*/
(uint16_t )2048, /* 任务堆栈大小,单位为字节*/
(void* )NULL, /* 传递给任务函数的参数*/
(UBaseType_t )20, /* 任务优先级,最高优先级为24 */
(TaskHandle_t* )NULL); /* 任务句柄,在不需要使用任务句柄时,可以填入NULL*/
最后贴上整个app_main.c
的代码
#include
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
#include "driver/uart.h"
#include "driver/gpio.h"
#define GPIO_LED_NUM 2
#define GPIO_KEY_NUM 0
/* 定义按键检测任务的任务句柄*/
TaskHandle_t Key_Task_Handler;
/* 声明按键检测任务函数 */
void key_task(void *pvParameters);
void app_main(void)
{
/* 打印Hello world! */
printf("Hello world!\n");
/* 定义一个gpio配置结构体 */
gpio_config_t gpio_config_structure;
/* 初始化gpio配置结构体*/
gpio_config_structure.pin_bit_mask = (1ULL << GPIO_LED_NUM);/* 选择gpio2 */
gpio_config_structure.mode = GPIO_MODE_OUTPUT; /* 输出模式 */
gpio_config_structure.pull_up_en = 0; /* 不上拉 */
gpio_config_structure.pull_down_en = 0; /* 不下拉 */
gpio_config_structure.intr_type = GPIO_INTR_DISABLE; /* 禁止中断 */
/* 根据设定参数初始化并使能 */
gpio_config(&gpio_config_structure);
/* 初始化gpio配置结构体*/
gpio_config_structure.pin_bit_mask = (1ULL << GPIO_KEY_NUM);/* 选择gpio0 */
gpio_config_structure.mode = GPIO_MODE_INPUT; /* 输入模式 */
gpio_config_structure.pull_up_en = 0; /* 不上拉 */
gpio_config_structure.pull_down_en = 0; /* 不下拉 */
gpio_config_structure.intr_type = GPIO_INTR_DISABLE; /* 禁止中断 */
/* 根据设定参数初始化并使能 */
gpio_config(&gpio_config_structure);
/* 输出低电平,点亮LED*/
gpio_set_level(GPIO_LED_NUM, 0);
/* 创建按键检测任务 */
xTaskCreate((TaskFunction_t )key_task, /* 任务函数 */
(const char* )"key task", /* 任务名称*/
(uint16_t )2048, /* 任务堆栈大小,单位为字节*/
(void* )NULL, /* 传递给任务函数的参数*/
(UBaseType_t )10, /* 任务优先级,最高优先级为24 */
(TaskHandle_t* )Key_Task_Handler); /* 任务句柄,在不需要使用任务句柄时,可以填入NULL*/
while(1)
{
gpio_set_level(GPIO_LED_NUM, 1); /* 熄灭 */
vTaskDelay(500 / portTICK_PERIOD_MS); /* 延时500ms*/
gpio_set_level(GPIO_LED_NUM, 0); /* 点亮 */
vTaskDelay(500 / portTICK_PERIOD_MS); /* 延时500ms*/
}
#if 0
while(1)
{
printf("Boot_key Level is : %d \n",gpio_get_level(GPIO_KEY_NUM)); /* 获取BOOT按键电平并打印 */
vTaskDelay(1000 / portTICK_PERIOD_MS); /* 延时1000ms*/
gpio_set_level(GPIO_LED_NUM, 0); /* 熄灭 */
}
#endif
}
/* 按键检测任务函数 */
void key_task(void *pvParameters)
{
static int key_up = 1; /* 按键松开标志 */
while (1)
{
/* 检测按键是否按下 */
if (key_up && (gpio_get_level(GPIO_KEY_NUM) == 0) )
{
vTaskDelay(50 / portTICK_PERIOD_MS); /* 延时50ms消抖*/
key_up = 0;
if (gpio_get_level(GPIO_KEY_NUM) == 0)
{
/* 按键BOOT按下,按键按下处理*/
printf("BOOT Key pressed!\n");
}
}
else if(gpio_get_level(GPIO_KEY_NUM) == 1 )
{
key_up = 1; /* 按键已松开 */
}
vTaskDelay(100 / portTICK_PERIOD_MS);
}
}