我正在使用 esp32 创建一个项目来模拟交通灯。我有两个交通灯,当一个是红灯时,另一个是绿灯。一个灯应保持绿色 10 秒,然后变为红色,然后另一个灯将变为绿色。在这个项目中,我应该将其设置为监听按钮按下,如果按下,灯将保持绿色 20 秒。我做了一个名为buttonCheck的函数来检查按钮是否被按下。我使用 xTaskCreate 让它在灯运行时检查按钮按下情况,但当我创建任务时,任务后面的代码不起作用。
按钮检查功能:
void buttonCheck(void *parameters){
int *timer = (int *)parameters;
esp_rom_gpio_pad_select_gpio(GPIO_NUM_0);
gpio_set_direction(GPIO_NUM_0, GPIO_MODE_INPUT);
gpio_set_pull_mode(GPIO_NUM_0, GPIO_PULLUP_ONLY);
bool timeswitch = true;
vTaskDelay(500/portTICK_PERIOD_MS);
while(1){
if(gpio_get_level(GPIO_NUM_0) == 0 && timeswitch){
*timer = 2000;
timeswitch = false;
// vTaskDelay(500/portTICK_PERIOD_MS);
}
if(gpio_get_level(GPIO_NUM_0) == 0 && !timeswitch){
*timer = 10000;
timeswitch = true;
// vTaskDelay(500/portTICK_PERIOD_MS);
}
// vTaskDelay(10000/portTICK_PERIOD_MS);
}
}
我如何调用main中的函数以及后面的代码
xTaskCreate(buttonCheck, "BUTTONPRESSCHECK", 150, &timer, 14, NULL);
while (1) {
if (EWgreen) {
toRed(EWlight);
vTaskDelay(2000 / portTICK_PERIOD_MS);
toGreen(NSlight);
EWgreen = false;
}
else {
toRed(NSlight);
vTaskDelay(2000 / portTICK_PERIOD_MS);
toGreen(EWlight);
EWgreen = true;
}
vTaskDelay(timer / portTICK_PERIOD_MS);
}
函数确实起作用,并且任务执行。我是嵌入式应用程序的新手,因此在做了一些研究后,我尝试减少/增加堆栈大小并降低函数的优先级。这些并没有改变结果。我想在函数进入 while 循环之前插入一个 taskDelay,希望这能让控制器在创建任务后有更多时间到达代码。这也没有改变结果。任何帮助将不胜感激!
这是所有代码:
#include<stdio.h>
#include<freertos/FreeRTOS.h>
#include<freertos/task.h>
#include<driver/gpio.h>
struct ledstuff {
gpio_num_t red;
gpio_num_t yellow;
gpio_num_t green;
};
typedef struct ledstuff ledinfo;
void
toRed(ledinfo data)
{
gpio_set_level(data.green, 0);
gpio_set_level(data.yellow, 1);
vTaskDelay(2000 / portTICK_PERIOD_MS);
gpio_set_level(data.yellow, 0);
gpio_set_level(data.red, 1);
}
void
toGreen(ledinfo data)
{
gpio_set_level(data.red, 0);
gpio_set_level(data.yellow, 0);
gpio_set_level(data.green, 1);
}
void
trafficLights(void *params)
{
int *timer = (int *) params;
bool EWgreen = true;
ledinfo NSlight;
NSlight.red = GPIO_NUM_19;
NSlight.yellow = GPIO_NUM_18;
NSlight.green = GPIO_NUM_5;
ledinfo EWlight;
EWlight.red = GPIO_NUM_27;
EWlight.yellow = GPIO_NUM_26;
EWlight.green = GPIO_NUM_25;
gpio_set_level(NSlight.red, 1);
gpio_set_level(EWlight.green, 1);
vTaskDelay(3000 / portTICK_PERIOD_MS);
while (1) {
if (EWgreen) {
toRed(EWlight);
vTaskDelay(2000 / portTICK_PERIOD_MS);
toGreen(NSlight);
EWgreen = false;
}
else {
toRed(NSlight);
vTaskDelay(2000 / portTICK_PERIOD_MS);
toGreen(EWlight);
EWgreen = true;
}
vTaskDelay(*timer / portTICK_PERIOD_MS);
}
}
void
buttonCheck(void *parameters)
{
int *timer = (int *) parameters;
esp_rom_gpio_pad_select_gpio(GPIO_NUM_0);
gpio_set_direction(GPIO_NUM_0, GPIO_MODE_INPUT);
gpio_set_pull_mode(GPIO_NUM_0, GPIO_PULLUP_ONLY);
bool timeswitch = true;
vTaskDelay(500 / portTICK_PERIOD_MS);
while (1) {
if (gpio_get_level(GPIO_NUM_0) == 0 && timeswitch) {
*timer = 2000;
gpio_set_level(GPIO_NUM_18, 1);
timeswitch = false;
// vTaskDelay(500/portTICK_PERIOD_MS);
}
if (gpio_get_level(GPIO_NUM_0) == 0 && !timeswitch) {
*timer = 10000;
gpio_set_level(GPIO_NUM_18, 0);
timeswitch = true;
// vTaskDelay(500/portTICK_PERIOD_MS);
}
// vTaskDelay(10000/portTICK_PERIOD_MS);
}
}
void
app_main()
{
int timer = 10000;
bool EWgreen = true;
gpio_set_direction(18, GPIO_MODE_OUTPUT);
gpio_set_direction(19, GPIO_MODE_OUTPUT);
gpio_set_direction(5, GPIO_MODE_OUTPUT);
gpio_set_direction(27, GPIO_MODE_OUTPUT);
gpio_set_direction(26, GPIO_MODE_OUTPUT);
gpio_set_direction(25, GPIO_MODE_OUTPUT);
ledinfo NSlight;
NSlight.red = GPIO_NUM_19;
NSlight.yellow = GPIO_NUM_18;
NSlight.green = GPIO_NUM_5;
ledinfo EWlight;
EWlight.red = GPIO_NUM_27;
EWlight.yellow = GPIO_NUM_26;
EWlight.green = GPIO_NUM_25;
gpio_set_level(NSlight.red, 1);
gpio_set_level(EWlight.green, 1);
vTaskDelay(3000 / portTICK_PERIOD_MS);
xTaskCreate(buttonCheck, "BUTTONPRESSCHECK", 150, &timer, 14, NULL);
// xTaskCreate(trafficLights,"TRAFFICLIGHTS",400,&timer,5,NULL);
while (1) {
if (EWgreen) {
toRed(EWlight);
vTaskDelay(2000 / portTICK_PERIOD_MS);
toGreen(NSlight);
EWgreen = false;
}
else {
toRed(NSlight);
vTaskDelay(2000 / portTICK_PERIOD_MS);
toGreen(EWlight);
EWgreen = true;
}
vTaskDelay(timer / portTICK_PERIOD_MS);
}
}
以热门评论为序...
这是我100%需要的东西吗? – 瑞安·佩雷斯
是的...
pthread_create
)不同,在 freertos
下,xTaskCreate
不会 start 任务。vTaskStartScheduler
函数调用 main
来完成。main_task
)这是重构后的代码。我编辑了它,但它未编译也测试:
#include <stdio.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <driver/gpio.h>
struct ledstuff {
gpio_num_t red;
gpio_num_t yellow;
gpio_num_t green;
};
typedef struct ledstuff ledinfo;
void
toRed(ledinfo data)
{
gpio_set_level(data.green, 0);
gpio_set_level(data.yellow, 1);
vTaskDelay(2000 / portTICK_PERIOD_MS);
gpio_set_level(data.yellow, 0);
gpio_set_level(data.red, 1);
}
void
toGreen(ledinfo data)
{
gpio_set_level(data.red, 0);
gpio_set_level(data.yellow, 0);
gpio_set_level(data.green, 1);
}
void
trafficLights(void *params)
{
int *timer = (int *) params;
bool EWgreen = true;
ledinfo NSlight;
NSlight.red = GPIO_NUM_19;
NSlight.yellow = GPIO_NUM_18;
NSlight.green = GPIO_NUM_5;
ledinfo EWlight;
EWlight.red = GPIO_NUM_27;
EWlight.yellow = GPIO_NUM_26;
EWlight.green = GPIO_NUM_25;
gpio_set_level(NSlight.red, 1);
gpio_set_level(EWlight.green, 1);
vTaskDelay(3000 / portTICK_PERIOD_MS);
while (1) {
if (EWgreen) {
toRed(EWlight);
vTaskDelay(2000 / portTICK_PERIOD_MS);
toGreen(NSlight);
EWgreen = false;
}
else {
toRed(NSlight);
vTaskDelay(2000 / portTICK_PERIOD_MS);
toGreen(EWlight);
EWgreen = true;
}
vTaskDelay(*timer / portTICK_PERIOD_MS);
}
}
void
buttonCheck(void *parameters)
{
int *timer = (int *) parameters;
esp_rom_gpio_pad_select_gpio(GPIO_NUM_0);
gpio_set_direction(GPIO_NUM_0, GPIO_MODE_INPUT);
gpio_set_pull_mode(GPIO_NUM_0, GPIO_PULLUP_ONLY);
bool timeswitch = true;
vTaskDelay(500 / portTICK_PERIOD_MS);
while (1) {
if (gpio_get_level(GPIO_NUM_0) == 0 && timeswitch) {
*timer = 2000;
gpio_set_level(GPIO_NUM_18, 1);
timeswitch = false;
// vTaskDelay(500/portTICK_PERIOD_MS);
}
if (gpio_get_level(GPIO_NUM_0) == 0 && !timeswitch) {
*timer = 10000;
gpio_set_level(GPIO_NUM_18, 0);
timeswitch = true;
// vTaskDelay(500/portTICK_PERIOD_MS);
}
// vTaskDelay(10000/portTICK_PERIOD_MS);
}
}
#if 1
// NOTE/FIX: main code must be in its own task
void
main_task(void *vp)
{
int *timer = vp;
bool EWgreen = true;
while (1) {
if (EWgreen) {
toRed(EWlight);
vTaskDelay(2000 / portTICK_PERIOD_MS);
toGreen(NSlight);
EWgreen = false;
}
else {
toRed(NSlight);
vTaskDelay(2000 / portTICK_PERIOD_MS);
toGreen(EWlight);
EWgreen = true;
}
vTaskDelay(*timer / portTICK_PERIOD_MS);
}
}
void
app_main()
{
// NOTE/BUG(?) -- timer on the main stack _may_ not survive after starting
// tasks
#if 0
int timer = 10000;
#else
static int timer = 10000;
#endif
#if 0
bool EWgreen = true;
#endif
gpio_set_direction(18, GPIO_MODE_OUTPUT);
gpio_set_direction(19, GPIO_MODE_OUTPUT);
gpio_set_direction(5, GPIO_MODE_OUTPUT);
gpio_set_direction(27, GPIO_MODE_OUTPUT);
gpio_set_direction(26, GPIO_MODE_OUTPUT);
gpio_set_direction(25, GPIO_MODE_OUTPUT);
ledinfo NSlight;
NSlight.red = GPIO_NUM_19;
NSlight.yellow = GPIO_NUM_18;
NSlight.green = GPIO_NUM_5;
ledinfo EWlight;
EWlight.red = GPIO_NUM_27;
EWlight.yellow = GPIO_NUM_26;
EWlight.green = GPIO_NUM_25;
gpio_set_level(NSlight.red, 1);
gpio_set_level(EWlight.green, 1);
vTaskDelay(3000 / portTICK_PERIOD_MS);
xTaskCreate(buttonCheck, "BUTTONPRESSCHECK", 150, &timer, 14, NULL);
// xTaskCreate(trafficLights,"TRAFFICLIGHTS",400,&timer,5,NULL);
// NOTE/BUG: buttonCheck task will _not_ be started until vTaskStartScheduler
// is executed
#if 1
// NOTE/FIX: must create a main task (not sure about the timer parameter for
// this)
xTaskCreate(main_task, "main_task", 150, &timer, 14, NULL);
vTaskStartScheduler();
while (1);
#endif
// NOTE/BUG: this code will never be executed -- it must go into its own task
// (see main_task)
#if 0
while (1) {
if (EWgreen) {
toRed(EWlight);
vTaskDelay(2000 / portTICK_PERIOD_MS);
toGreen(NSlight);
EWgreen = false;
}
else {
toRed(NSlight);
vTaskDelay(2000 / portTICK_PERIOD_MS);
toGreen(EWlight);
EWgreen = true;
}
vTaskDelay(timer / portTICK_PERIOD_MS);
}
#endif
}
在上面的代码中,我使用
cpp
条件来表示旧代码与新代码:
#if 0
// old code
#else
// new code
#endif
#if 1
// new code
#endif
注意:这可以通过运行文件来清理
unifdef -k