2025-01-17 21:37:00 +08:00
|
|
|
|
#include "indicator_led.h"
|
2025-01-18 12:41:57 +08:00
|
|
|
|
#include "rtdevice.h"
|
|
|
|
|
|
2025-03-15 16:07:17 +08:00
|
|
|
|
#define LED_BREATH_PERIOD 4000
|
|
|
|
|
#define LED_BREATH_MDELAY 20
|
|
|
|
|
#define LED_BREATH_HALF_TIMES (LED_BREATH_PERIOD / LED_BREATH_MDELAY / 2)
|
|
|
|
|
const uint8_t gamma_table[256] = {
|
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
|
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
|
|
|
|
|
2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5,
|
|
|
|
|
5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 10, 10, 10,
|
|
|
|
|
11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17,
|
|
|
|
|
18, 18, 19, 19, 20, 20, 21, 21, 22, 23, 23, 24, 24, 25, 26, 26,
|
|
|
|
|
27, 28, 28, 29, 30, 30, 31, 32, 32, 33, 34, 35, 35, 36, 37, 38,
|
|
|
|
|
38, 39, 40, 41, 42, 42, 43, 44, 45, 46, 47, 48, 49, 49, 50, 51,
|
|
|
|
|
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
|
|
|
|
|
69, 70, 71, 72, 73, 74, 75, 76, 78, 79, 80, 81, 82, 84, 85, 86,
|
|
|
|
|
87, 89, 90, 91, 92, 94, 95, 96, 98, 99,100,102,103,104,106,107,
|
|
|
|
|
109,110,112,113,114,116,117,119,120,122,123,125,126,128,130,131,
|
|
|
|
|
133,134,136,138,139,141,143,144,146,148,149,151,153,154,156,158,
|
|
|
|
|
160,161,163,165,167,169,170,172,174,176,178,180,182,183,185,187,
|
|
|
|
|
189,191,193,195,197,199,201,203,205,207,209,211,213,215,218,220,
|
|
|
|
|
222,224,226,228,230,233,235,237,239,241,244,246,248,250,253,255,
|
|
|
|
|
};
|
2025-01-17 21:37:00 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rt_thread_t led_blink_thread = RT_NULL;
|
2025-01-18 00:46:10 +08:00
|
|
|
|
rt_thread_t led_breath_thread = RT_NULL;
|
2025-03-15 16:07:17 +08:00
|
|
|
|
rt_thread_t led_reflash_thread = RT_NULL;
|
2025-01-17 21:37:00 +08:00
|
|
|
|
|
2025-01-18 00:46:10 +08:00
|
|
|
|
// 灯是否处于特定颜色还是闪烁状态
|
2025-03-15 16:07:17 +08:00
|
|
|
|
uint8_t LED_State[LED_NUM] = {LED_NOT_BLINKING};
|
2025-01-17 21:37:00 +08:00
|
|
|
|
// 灯闪烁颜色缓存
|
2025-03-15 16:07:17 +08:00
|
|
|
|
RGBColor_TypeDef LED_Color[LED_NUM] = {0};
|
|
|
|
|
// 灯闪烁(呼吸)颜色当前值
|
|
|
|
|
RGBColor_TypeDef LED_Tmp_Color = {0};
|
|
|
|
|
|
2025-01-17 21:37:00 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief 设置特定LED的颜色或开关
|
2025-03-15 16:07:17 +08:00
|
|
|
|
* @param LedId LED的序号(0~LED_NUM-1)
|
2025-01-17 21:37:00 +08:00
|
|
|
|
* @param Color 颜色/开关 LED_RED,LED_BLUE,LED_OFF,LED_ON(白色)……
|
|
|
|
|
*/
|
|
|
|
|
void LED_Set(uint16_t LedId, RGBColor_TypeDef Color)
|
|
|
|
|
{
|
2025-03-15 16:07:17 +08:00
|
|
|
|
LED_State[LedId] = LED_NOT_BLINKING;
|
2025-01-17 21:37:00 +08:00
|
|
|
|
Set_LEDColor(LedId, Color);
|
|
|
|
|
RGB_Reflash();
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* @brief 设置连续多个特定LED的颜色或开关
|
2025-03-15 16:07:17 +08:00
|
|
|
|
* @param LedId_begin LED的序号(0~LED_NUM-1)开始
|
|
|
|
|
* @param LedId_end LED的序号(0~LED_NUM-1)结束
|
2025-01-17 21:37:00 +08:00
|
|
|
|
* @param Color 颜色/开关 LED_RED,LED_BLUE,LED_OFF,LED_ON(白色)……
|
|
|
|
|
*/
|
|
|
|
|
void LED_SetMore(uint16_t LedId_begin, uint16_t LedId_end, RGBColor_TypeDef Color)
|
|
|
|
|
{
|
2025-01-18 11:04:08 +08:00
|
|
|
|
for (int LedId = LedId_begin; LedId <= LedId_end; LedId++)
|
2025-01-17 21:37:00 +08:00
|
|
|
|
{
|
2025-03-15 16:07:17 +08:00
|
|
|
|
LED_State[LedId] = LED_NOT_BLINKING;
|
2025-01-17 21:53:03 +08:00
|
|
|
|
Set_LEDColor(LedId, Color);
|
2025-01-17 21:37:00 +08:00
|
|
|
|
}
|
|
|
|
|
RGB_Reflash();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief 设置特定LED的闪烁
|
2025-03-15 16:07:17 +08:00
|
|
|
|
* @param LedId LED的序号(0~LED_NUM-1)
|
2025-01-17 21:37:00 +08:00
|
|
|
|
* @param Color 颜色 LED_RED,LED_BLUE……
|
|
|
|
|
*/
|
|
|
|
|
void LED_Blink(uint16_t LedId, RGBColor_TypeDef Color)
|
|
|
|
|
{
|
2025-03-15 16:07:17 +08:00
|
|
|
|
LED_State[LedId] = LED_IS_BLINKING;
|
|
|
|
|
LED_Color[LedId] = Color;
|
2025-01-17 21:37:00 +08:00
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* @brief 设置连续多个特定LED的闪烁
|
2025-03-15 16:07:17 +08:00
|
|
|
|
* @param LedId_begin LED的序号(0~LED_NUM-1)开始
|
|
|
|
|
* @param LedId_end LED的序号(0~LED_NUM-1)结束
|
2025-01-17 21:37:00 +08:00
|
|
|
|
* @param Color 颜色 LED_RED,LED_BLUE……
|
|
|
|
|
*/
|
|
|
|
|
void LED_BlinkMore(uint16_t LedId_begin, uint16_t LedId_end, RGBColor_TypeDef Color)
|
|
|
|
|
{
|
2025-01-18 11:04:08 +08:00
|
|
|
|
for (int LedId = LedId_begin; LedId <= LedId_end; LedId++)
|
2025-01-17 21:37:00 +08:00
|
|
|
|
{
|
2025-03-15 16:07:17 +08:00
|
|
|
|
LED_State[LedId] = LED_IS_BLINKING;
|
|
|
|
|
LED_Color[LedId] = Color;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* @brief 设置特定LED的呼吸
|
|
|
|
|
* @param LedId LED的序号(0~LED_NUM-1)
|
|
|
|
|
* @param Color 颜色 LED_RED,LED_BLUE……
|
|
|
|
|
*/
|
|
|
|
|
void LED_Breath(uint16_t LedId, RGBColor_TypeDef Color)
|
|
|
|
|
{
|
|
|
|
|
LED_State[LedId] = LED_IS_BREATHING;
|
|
|
|
|
LED_Color[LedId] = Color;
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* @brief 设置连续多个特定LED的呼吸
|
|
|
|
|
* @param LedId_begin LED的序号(0~LED_NUM-1)开始
|
|
|
|
|
* @param LedId_end LED的序号(0~LED_NUM-1)结束
|
|
|
|
|
* @param Color 颜色 LED_RED,LED_BLUE……
|
|
|
|
|
*/
|
|
|
|
|
void LED_BreathMore(uint16_t LedId_begin, uint16_t LedId_end, RGBColor_TypeDef Color)
|
|
|
|
|
{
|
|
|
|
|
for (int LedId = LedId_begin; LedId <= LedId_end; LedId++)
|
|
|
|
|
{
|
|
|
|
|
LED_State[LedId] = LED_IS_BREATHING;
|
|
|
|
|
LED_Color[LedId] = Color;
|
2025-01-18 11:04:08 +08:00
|
|
|
|
}
|
2025-01-17 21:37:00 +08:00
|
|
|
|
}
|
|
|
|
|
/**
|
2025-03-15 16:07:17 +08:00
|
|
|
|
* @brief 灯的闪烁,每0.5s判断各盏灯是否要翻转
|
2025-01-17 21:37:00 +08:00
|
|
|
|
*/
|
|
|
|
|
void led_blink_entry(void *parameter)
|
|
|
|
|
{
|
2025-03-15 16:07:17 +08:00
|
|
|
|
(void)parameter;
|
|
|
|
|
uint16_t LED_Blink_ON = 1, cnt_blink = 0;
|
2025-01-17 21:37:00 +08:00
|
|
|
|
while (1)
|
|
|
|
|
{
|
2025-03-15 16:07:17 +08:00
|
|
|
|
cnt_blink = 0;
|
2025-01-17 21:37:00 +08:00
|
|
|
|
for (int LedId = 0; LedId < LED_NUM; LedId++)
|
|
|
|
|
{
|
2025-03-15 16:07:17 +08:00
|
|
|
|
if (LED_State[LedId] == LED_IS_BLINKING)
|
2025-01-17 21:37:00 +08:00
|
|
|
|
{
|
2025-03-15 16:07:17 +08:00
|
|
|
|
cnt_blink++;
|
2025-01-17 21:37:00 +08:00
|
|
|
|
if (LED_Blink_ON)
|
|
|
|
|
{
|
2025-03-15 16:07:17 +08:00
|
|
|
|
Set_LEDColor(LedId, LED_Color[LedId]);
|
2025-01-17 21:37:00 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2025-03-15 16:07:17 +08:00
|
|
|
|
Set_LEDColor(LedId, LEDI_OFF);
|
2025-01-17 21:37:00 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
LED_Blink_ON = !LED_Blink_ON;
|
2025-03-15 16:07:17 +08:00
|
|
|
|
if (cnt_blink)
|
|
|
|
|
RGB_Reflash();
|
2025-01-17 21:37:00 +08:00
|
|
|
|
rt_thread_mdelay(500);
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-01-18 00:46:10 +08:00
|
|
|
|
|
2025-03-15 16:07:17 +08:00
|
|
|
|
void breath_add(float *LED_Breath_Percentage)
|
|
|
|
|
{
|
|
|
|
|
static int breath_cnt = 0;
|
|
|
|
|
if(breath_cnt<=LED_BREATH_HALF_TIMES)
|
|
|
|
|
{
|
|
|
|
|
*LED_Breath_Percentage =gamma_table[(uint8_t)256.0*breath_cnt/LED_BREATH_HALF_TIMES];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
*LED_Breath_Percentage =gamma_table[(uint8_t)256.0*(LED_BREATH_HALF_TIMES*2-breath_cnt)/LED_BREATH_HALF_TIMES];
|
|
|
|
|
if (breath_cnt>=LED_BREATH_HALF_TIMES*2)
|
|
|
|
|
{
|
|
|
|
|
breath_cnt=0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
breath_cnt++;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-18 00:46:10 +08:00
|
|
|
|
void led_breath_entry(void *parameter)
|
|
|
|
|
{
|
2025-03-15 16:07:17 +08:00
|
|
|
|
(void)parameter;
|
|
|
|
|
float LED_Breath_Percentage = 255;
|
|
|
|
|
uint16_t LED_Breath_ON = 1, breath_num=0;
|
2025-01-18 00:46:10 +08:00
|
|
|
|
while (1)
|
|
|
|
|
{
|
2025-03-15 16:07:17 +08:00
|
|
|
|
breath_num = 0;
|
|
|
|
|
for (int LedId = 0; LedId < LED_NUM; LedId++)
|
2025-01-18 00:46:10 +08:00
|
|
|
|
{
|
2025-03-15 16:07:17 +08:00
|
|
|
|
if (LED_State[LedId] == LED_IS_BREATHING)
|
2025-01-18 00:46:10 +08:00
|
|
|
|
{
|
2025-03-15 16:07:17 +08:00
|
|
|
|
breath_num++;
|
|
|
|
|
LED_Tmp_Color.G = (uint8_t)LED_Color[LedId].G * LED_Breath_Percentage/255;
|
|
|
|
|
LED_Tmp_Color.R = (uint8_t)LED_Color[LedId].R * LED_Breath_Percentage/255;
|
|
|
|
|
LED_Tmp_Color.B = (uint8_t)LED_Color[LedId].B * LED_Breath_Percentage/255;
|
|
|
|
|
Set_LEDColor(LedId, LED_Tmp_Color);
|
2025-01-18 00:46:10 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2025-03-15 16:07:17 +08:00
|
|
|
|
breath_add(&LED_Breath_Percentage);
|
|
|
|
|
if (breath_num)
|
|
|
|
|
RGB_Reflash();
|
|
|
|
|
rt_thread_mdelay(LED_BREATH_MDELAY);
|
2025-01-18 00:46:10 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-15 16:07:17 +08:00
|
|
|
|
void led_reflash_entry(void *parameter)
|
2025-01-18 12:41:57 +08:00
|
|
|
|
{
|
2025-03-15 16:07:17 +08:00
|
|
|
|
(void)parameter;
|
|
|
|
|
while (1)
|
2025-01-18 12:41:57 +08:00
|
|
|
|
{
|
2025-03-15 16:07:17 +08:00
|
|
|
|
RGB_Reflash();
|
|
|
|
|
rt_thread_mdelay(500);
|
2025-01-18 12:41:57 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2025-01-18 11:04:08 +08:00
|
|
|
|
/**
|
2025-01-18 11:51:19 +08:00
|
|
|
|
* @brief LED的初始化
|
2025-03-15 16:07:17 +08:00
|
|
|
|
*/
|
2025-01-18 11:51:19 +08:00
|
|
|
|
int led_init(void)
|
2025-01-18 00:46:10 +08:00
|
|
|
|
{
|
2025-03-15 16:07:17 +08:00
|
|
|
|
|
|
|
|
|
led_blink_thread = rt_thread_create("ledblT", led_blink_entry, RT_NULL, 1024, 20, 20);
|
2025-01-18 11:51:19 +08:00
|
|
|
|
if (led_blink_thread == RT_NULL)
|
|
|
|
|
{
|
|
|
|
|
rt_kprintf("led blink control thread creat failed!\n");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2025-03-15 16:07:17 +08:00
|
|
|
|
rt_thread_startup(led_blink_thread);
|
|
|
|
|
|
|
|
|
|
led_breath_thread = rt_thread_create("ledbrT", led_breath_entry, RT_NULL, 1024, 20, 20);
|
2025-01-18 00:46:10 +08:00
|
|
|
|
if (led_breath_thread == RT_NULL)
|
|
|
|
|
{
|
|
|
|
|
rt_kprintf("led breath control thread creat failed!\n");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
rt_thread_startup(led_breath_thread);
|
2025-03-15 16:07:17 +08:00
|
|
|
|
|
|
|
|
|
led_reflash_thread = rt_thread_create("ledreT", led_reflash_entry, RT_NULL, 1024, 20, 20);
|
|
|
|
|
if (led_reflash_thread == RT_NULL)
|
|
|
|
|
{
|
|
|
|
|
rt_kprintf("led reflash control thread creat failed!\n");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
rt_thread_startup(led_reflash_thread);
|
|
|
|
|
return 0;
|
2025-01-17 21:37:00 +08:00
|
|
|
|
}
|