本文针对ESP8266的RTOS_SDK开发编译流程出现的报错进行了一些解决,并且完成了按键控制LED功能
环境准备
硬件环境准备
-
esp8266(焊接排针)
-
独立按键
-
杜邦线
软件环境准备
参考这位大佬:环境搭建教程
-
ESP8266_RTOS_SDK
-
AiThinkerIDE_V1.5.2
注意事项
- 出现 mintty.exe 报错
是未安装python环境问题,打开CMD窗口检查python是否安装.
- program “g++” not found in PATH和program “gcc” not found in PATH
c/c++环境未安装,安装mingw64后解决
- 图形配置界面闪退
打开CMD窗口检查python版本,由于AiThinkerIDE_V1.5.2内置了python版本为2.7,所以需要将cmd中运行的版本与ide安装的一致
- 编译后蓝屏
更换电脑解决
软件开发流程
当环境搭建好后,可以进行代码编写开发
创建自定义工程
复制工程并且修改为想要的名称,我这里由于是测试GPIO故修改为GPIO_test
修改编译路径
编写功能代码
参考例程以及sdk文档:
- GPIO-led功能
添加头文件
#include "driver/gpio.h"
添加宏定义
// led_gpio
#define GPIO_LED_IO_NUM 2 //gpio2
Led初始化
void user_init(void)
{
//led
gpio_config_t io_conf;
io_conf.pin_bit_mask = (1ULL<<GPIO_LED_IO_NUM);
io_conf.mode = GPIO_MODE_OUTPUT;
io_conf.intr_type = GPIO_INTR_DISABLE;
io_conf.pull_down_en = 0;
io_conf.pull_up_en = 0;
gpio_config(&io_conf);
}
主循环添加
user_init();
while(1)
{
gpio_set_level(GPIO_LED_IO_NUM,0);
vTaskDelay(1000 / portTICK_PERIOD_MS);
gpio_set_level(GPIO_LED_IO_NUM,1);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
编译下载可看到led闪烁
- GPIO-按键功能
添加头文件
#include "driver/gpio.h"
#include "driver/hw_timer.h"
添加宏定义(根据外接按键来)
//key_gpio
#define GPIO_KEY_IO_S1 16 //gpio16
#define GPIO_KEY_IO_S2 5
#define GPIO_KEY_IO_S3 4
#define GPIO_KEY_IO_S4 0
定义按键结构体
struct keys
{
unsigned char judge_sta; //判断按键按键按下的动作到了第几步
unsigned char key_sta; //如果按键被按下,为0
unsigned char key_flag; //如果确认被按下,为1
} ;
struct keys key[5]={0};
定义按键扫描定时器函数以及按键处理任务
//任务定义
void key_task(void *pvParameters);
void key_hw_timer_callback1(void *arg); //扫描消抖
按键初始化
void user_init(void)
{
//led
gpio_config_t io_conf;
io_conf.pin_bit_mask = (1ULL<<GPIO_LED_IO_NUM);
io_conf.mode = GPIO_MODE_OUTPUT;
io_conf.intr_type = GPIO_INTR_DISABLE;
io_conf.pull_down_en = 0;
io_conf.pull_up_en = 0;
gpio_config(&io_conf);
//key
io_conf.pin_bit_mask = ( (1ULL<<GPIO_KEY_IO_S1) | (1ULL<<GPIO_KEY_IO_S2) | (1ULL<<GPIO_KEY_IO_S3) |(1ULL<<GPIO_KEY_IO_S4) );
io_conf.mode = GPIO_MODE_INPUT;
io_conf.intr_type = GPIO_INTR_DISABLE;
io_conf.pull_down_en = 0;
io_conf.pull_up_en = 1;
gpio_config(&io_conf);
}
主函数调用初始化
//timer
hw_timer_init(key_hw_timer_callback1, NULL);
hw_timer_alarm_us(10000, TEST_RELOAD);//10000us=10ms 触发一次
//task
xTaskCreate(key_task,"key_task",512,NULL,10,NULL);
实现按键扫描以及消抖
void key_hw_timer_callback1(void *arg)
{
key[1].key_sta = gpio_get_level(GPIO_KEY_IO_S1);
key[2].key_sta = gpio_get_level(GPIO_KEY_IO_S2);
key[3].key_sta = gpio_get_level(GPIO_KEY_IO_S3);
key[4].key_sta = gpio_get_level(GPIO_KEY_IO_S4);
for(int i=1;i<=4;i++)
{
switch (key[i].judge_sta)
{
case 0:
{
if(key[i].key_sta==0) key[i].judge_sta = 1; //第一次判断是否按下
}
break;
case 1:
{
if(key[i].key_sta==0) //进入下一次定时器扫描,按键还是按下状态,那么就确认为按下,以此来消抖
{
key[i].judge_sta = 2;
key[i].key_flag = 1;
}
else //否则就是抖动,本次不算按键被按下
key[i].judge_sta = 0;
}
break;
case 2:
{
if(key[i].key_sta==1) key[i].judge_sta = 0; //判断是否松手,松手后按键状态重置
}
break;
}
}
}
实现按键处理函数
void key_task(void *pvParameters)
{
printf("KET TASK CREATE\n");
while(1)
{
if(key[1].key_flag)
{
gpio_set_level(GPIO_LED_IO_NUM,0);
key[1].key_flag=0;
}
if(key[2].key_flag)
{
gpio_set_level(GPIO_LED_IO_NUM,1);
key[2].key_flag=0;
}
if(key[3].key_flag)
{
gpio_set_level(GPIO_LED_IO_NUM,0);
key[3].key_flag=0;
}
if(key[4].key_flag)
{
gpio_set_level(GPIO_LED_IO_NUM,1);
key[4].key_flag=0;
}
vTaskDelay(10 / portTICK_PERIOD_MS);
}
}
编译下载得到,按下按键操控led亮灭
注意事项
- 每个任务中必须添加vTaskDelay()函数,否则程序无法跳转空闲函数进行任务切换,且会触发看门狗重启,具体详情见RTOS内核
编译下载
- 编译程序
- 下载程序
出现这个说明正在编译
注意事项
- 下载时需要将串口关闭,否则下载失败
源代码
user_main.c
/* GPIO Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
#include "driver/gpio.h"
#include "driver/hw_timer.h"
//timer
#define TEST_ONE_SHOT 0 // testing will be done without auto reload (one-shot)
#define TEST_RELOAD 1 // testing will be done with auto reload
// led_gpio
#define GPIO_LED_IO_NUM 2
//key_gpio
#define GPIO_KEY_IO_S1 16
#define GPIO_KEY_IO_S2 5
#define GPIO_KEY_IO_S3 4
#define GPIO_KEY_IO_S4 0
//任务定义
void key_task(void *pvParameters);
void key_hw_timer_callback1(void *arg);
struct keys
{
unsigned char judge_sta; //判断按键按键按下的动作到了第几步
unsigned char key_sta; //如果按键被按下,为0
unsigned char key_flag; //如果确认被按下,为1
} ;
struct keys key[5]={0};
void user_init(void)
{
//led
gpio_config_t io_conf;
io_conf.pin_bit_mask = (1ULL<<GPIO_LED_IO_NUM);
io_conf.mode = GPIO_MODE_OUTPUT;
io_conf.intr_type = GPIO_INTR_DISABLE;
io_conf.pull_down_en = 0;
io_conf.pull_up_en = 0;
gpio_config(&io_conf);
//key
io_conf.pin_bit_mask = ( (1ULL<<GPIO_KEY_IO_S1) | (1ULL<<GPIO_KEY_IO_S2) | (1ULL<<GPIO_KEY_IO_S3) |(1ULL<<GPIO_KEY_IO_S4) );
io_conf.mode = GPIO_MODE_INPUT;
io_conf.intr_type = GPIO_INTR_DISABLE;
io_conf.pull_down_en = 0;
io_conf.pull_up_en = 1;
gpio_config(&io_conf);
}
void app_main()
{
printf("Hello world!\n");
user_init();
//timer
hw_timer_init(key_hw_timer_callback1, NULL);
hw_timer_alarm_us(10000, TEST_RELOAD);
//task
xTaskCreate(key_task,"key_task",512,NULL,10,NULL);
printf("task end!\n");
while(1)
{
gpio_set_level(GPIO_LED_IO_NUM,0);
vTaskDelay(1000 / portTICK_PERIOD_MS);
gpio_set_level(GPIO_LED_IO_NUM,1);
vTaskDelay(1000 / portTICK_PERIOD_MS);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
printf("while end!\n");
fflush(stdout);
}
void key_task(void *pvParameters)
{
printf("KET TASK CREATE\n");
while(1)
{
if(key[1].key_flag)
{
gpio_set_level(GPIO_LED_IO_NUM,0);
key[1].key_flag=0;
}
if(key[2].key_flag)
{
gpio_set_level(GPIO_LED_IO_NUM,1);
key[2].key_flag=0;
}
if(key[3].key_flag)
{
gpio_set_level(GPIO_LED_IO_NUM,0);
key[3].key_flag=0;
}
if(key[4].key_flag)
{
gpio_set_level(GPIO_LED_IO_NUM,1);
key[4].key_flag=0;
}
vTaskDelay(10 / portTICK_PERIOD_MS);
}
}
void key_hw_timer_callback1(void *arg)
{
key[1].key_sta = gpio_get_level(GPIO_KEY_IO_S1);
key[2].key_sta = gpio_get_level(GPIO_KEY_IO_S2);
key[3].key_sta = gpio_get_level(GPIO_KEY_IO_S3);
key[4].key_sta = gpio_get_level(GPIO_KEY_IO_S4);
for(int i=1;i<=4;i++)
{
switch (key[i].judge_sta)
{
case 0:
{
if(key[i].key_sta==0) key[i].judge_sta = 1; //第一次判断是否按下
}
break;
case 1:
{
if(key[i].key_sta==0) //进入下一次定时器扫描,按键还是按下状态,那么就确认为按下,以此来消抖
{
key[i].judge_sta = 2;
key[i].key_flag = 1;
}
else //否则就是抖动,本次不算按键被按下
key[i].judge_sta = 0;
}
break;
case 2:
{
if(key[i].key_sta==1) key[i].judge_sta = 0; //判断是否松手,松手后按键状态重置
}
break;
}
}
}
标签:sta,ESP8266,IO,void,RTOS,key,GPIO,gpio,SDK
From: https://blog.csdn.net/LUOkb_/article/details/144552798