SumProject/applications/indicator_led.c
2025-03-15 16:07:17 +08:00

229 lines
7.0 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "indicator_led.h"
#include "rtdevice.h"
#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,
};
rt_thread_t led_blink_thread = RT_NULL;
rt_thread_t led_breath_thread = RT_NULL;
rt_thread_t led_reflash_thread = RT_NULL;
// 灯是否处于特定颜色还是闪烁状态
uint8_t LED_State[LED_NUM] = {LED_NOT_BLINKING};
// 灯闪烁颜色缓存
RGBColor_TypeDef LED_Color[LED_NUM] = {0};
// 灯闪烁(呼吸)颜色当前值
RGBColor_TypeDef LED_Tmp_Color = {0};
/**
* @brief 设置特定LED的颜色或开关
* @param LedId LED的序号(0~LED_NUM-1)
* @param Color 颜色/开关 LED_RED,LED_BLUE,LED_OFF,LED_ON(白色)……
*/
void LED_Set(uint16_t LedId, RGBColor_TypeDef Color)
{
LED_State[LedId] = LED_NOT_BLINKING;
Set_LEDColor(LedId, Color);
RGB_Reflash();
}
/**
* @brief 设置连续多个特定LED的颜色或开关
* @param LedId_begin LED的序号(0~LED_NUM-1)开始
* @param LedId_end LED的序号(0~LED_NUM-1)结束
* @param Color 颜色/开关 LED_RED,LED_BLUE,LED_OFF,LED_ON(白色)……
*/
void LED_SetMore(uint16_t LedId_begin, uint16_t LedId_end, RGBColor_TypeDef Color)
{
for (int LedId = LedId_begin; LedId <= LedId_end; LedId++)
{
LED_State[LedId] = LED_NOT_BLINKING;
Set_LEDColor(LedId, Color);
}
RGB_Reflash();
}
/**
* @brief 设置特定LED的闪烁
* @param LedId LED的序号(0~LED_NUM-1)
* @param Color 颜色 LED_RED,LED_BLUE……
*/
void LED_Blink(uint16_t LedId, RGBColor_TypeDef Color)
{
LED_State[LedId] = LED_IS_BLINKING;
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_BlinkMore(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_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;
}
}
/**
* @brief 灯的闪烁每0.5s判断各盏灯是否要翻转
*/
void led_blink_entry(void *parameter)
{
(void)parameter;
uint16_t LED_Blink_ON = 1, cnt_blink = 0;
while (1)
{
cnt_blink = 0;
for (int LedId = 0; LedId < LED_NUM; LedId++)
{
if (LED_State[LedId] == LED_IS_BLINKING)
{
cnt_blink++;
if (LED_Blink_ON)
{
Set_LEDColor(LedId, LED_Color[LedId]);
}
else
{
Set_LEDColor(LedId, LEDI_OFF);
}
}
}
LED_Blink_ON = !LED_Blink_ON;
if (cnt_blink)
RGB_Reflash();
rt_thread_mdelay(500);
}
}
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++;
}
void led_breath_entry(void *parameter)
{
(void)parameter;
float LED_Breath_Percentage = 255;
uint16_t LED_Breath_ON = 1, breath_num=0;
while (1)
{
breath_num = 0;
for (int LedId = 0; LedId < LED_NUM; LedId++)
{
if (LED_State[LedId] == LED_IS_BREATHING)
{
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);
}
}
breath_add(&LED_Breath_Percentage);
if (breath_num)
RGB_Reflash();
rt_thread_mdelay(LED_BREATH_MDELAY);
}
}
void led_reflash_entry(void *parameter)
{
(void)parameter;
while (1)
{
RGB_Reflash();
rt_thread_mdelay(500);
}
}
/**
* @brief LED的初始化
*/
int led_init(void)
{
led_blink_thread = rt_thread_create("ledblT", led_blink_entry, RT_NULL, 1024, 20, 20);
if (led_blink_thread == RT_NULL)
{
rt_kprintf("led blink control thread creat failed!\n");
return 0;
}
rt_thread_startup(led_blink_thread);
led_breath_thread = rt_thread_create("ledbrT", led_breath_entry, RT_NULL, 1024, 20, 20);
if (led_breath_thread == RT_NULL)
{
rt_kprintf("led breath control thread creat failed!\n");
return 0;
}
rt_thread_startup(led_breath_thread);
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;
}