我目的为了让一个LED通过闪烁快慢来显示程序运行的多种状态,专门封装了led_ctl库。由于自带的延时函数会造成程序阻塞,需要led闪烁的代码就放在FreeRTOS任务里面,简单的灯开灯关和电平反转放在任务外面需要就直接调用,但是任务里面一段快速闪烁LED的代码(电平反转间隔20ms)在while循环执行5000ms后,灯开灯关函数就不起作用了,20ms改为50ms就正常,一直找不到原因贴上代码希望大家指正
main.c
#include FreeRTOS.h>
#include
#include
#include
#include "led_ctl.h"
void app_main(void)
{
// 初始化(低电平触发)
led_Init();
// 灯开(正常执行,延时5000ms)
led_on();
vTaskDelay(5000 / portTICK_PERIOD_MS);
// 闪灯(反转电平每20ms一次,延时5000ms)
led_ctl(LED_GYRO_CALIBRATION);
vTaskDelay(5000 / portTICK_PERIOD_MS);
// 灯开(不起作用,延时5000ms)
led_on();
vTaskDelay(5000 / portTICK_PERIOD_MS);
// 灯关(不起作用,延时5000ms)
led_off();
vTaskDelay(5000 / portTICK_PERIOD_MS);
}
led_ctl.h
#ifndef _LED_CTL_H_
#define _LED_CTL_H_
#define LED_STATUS_PIN GPIO_NUM_2
typedef enum
{
LED_IDLE,
LED_WL_DISCONNECT,
LED_GYRO_CALIBRATION,
LED_FLIGHT
} led_status_e;
bool led_isInit(void);
void led_Init(void);
void led_on(void);
void led_off(void);
void led_reverse(void);
void led_ctl(led_status_e ledStatus);
#endif
led_ctl.c
#include FreeRTOS.h>
#include
#include
#include "led_ctl.h"
static bool isInit = false;
static uint32_t led_ctl_val;
static uint32_t led_status_level;
static void led_ctl_task(void *args)
{
while (true)
{
switch (led_ctl_val)
{
case 0:
led_off();
led_ctl_val = -1;
break;
case 1:
led_status_level = 1;
led_reverse();
vTaskDelay(200 / portTICK_PERIOD_MS);
led_reverse();
vTaskDelay(200 / portTICK_PERIOD_MS);
break;
case 2:
led_status_level = 1;
led_reverse();
vTaskDelay(20 / portTICK_PERIOD_MS);
led_reverse();
vTaskDelay(20 / portTICK_PERIOD_MS);
break;
case 3:
led_status_level = 1;
led_reverse();
vTaskDelay(20 / portTICK_PERIOD_MS);
led_reverse();
vTaskDelay(1980 / portTICK_PERIOD_MS);
break;
default:
vTaskDelay(10 / portTICK_PERIOD_MS);
break;
}
}
vTaskDelete(NULL);
}
bool led_isInit(void)
{
return isInit;
}
void led_Init(void)
{
led_ctl_val = -1;
led_status_level = 1;
gpio_set_direction(LED_STATUS_PIN, GPIO_MODE_OUTPUT);
gpio_set_level(LED_STATUS_PIN, led_status_level);
if (isInit == false)
{
xTaskCreatePinnedToCore(led_ctl_task, "led_ctl_task", 2048, NULL, 0, NULL, 0);
isInit = true;
}
}
void led_on(void)
{
led_ctl_val = -1;
led_status_level = 0;
gpio_set_level(LED_STATUS_PIN, led_status_level);
}
void led_off(void)
{
led_ctl_val = -1;
led_status_level = 1;
gpio_set_level(LED_STATUS_PIN, led_status_level);
}
void led_reverse(void)
{
if (led_status_level == 0)
{
led_status_level = 1;
}
else
{
led_status_level = 0;
}
gpio_set_level(LED_STATUS_PIN, led_status_level);
}
void led_ctl(led_status_e ledStatus)
{
switch (ledStatus)
{
case LED_IDLE:
led_ctl_val = 0;
break;
case LED_WL_DISCONNECT:
led_ctl_val = 1;
break;
case LED_GYRO_CALIBRATION:
led_ctl_val = 2;
break;
case LED_FLIGHT:
led_ctl_val = 3;
break;
default:
break;
}
}
和代码应该没有多少关系,闪烁的原理也是开和关的动作,你在闪烁之后再去使用开灯的方法之前先调用关灯的方法,用来重置状态,然后再去执行开灯方法,试一试吧。