From b85b15df17668e933d43af5f72fa8a8ccab20833 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E7=90=AA?= Date: Mon, 27 Jul 2026 22:54:20 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=A8=A1=E5=BC=8F=E5=88=87?= =?UTF-8?q?=E6=8D=A2=E6=9F=94=E5=92=8C=E8=BF=87=E6=B8=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/ble/ble_peripheral/app/src/Mode.c | 32 ++++--- .../ble_peripheral/app/src/light_transition.c | 83 +++++++++++++++++-- .../ble_peripheral/app/src/light_transition.h | 2 + 3 files changed, 100 insertions(+), 17 deletions(-) diff --git a/project/example/ble/ble_peripheral/app/src/Mode.c b/project/example/ble/ble_peripheral/app/src/Mode.c index 012041e..c925f08 100644 --- a/project/example/ble/ble_peripheral/app/src/Mode.c +++ b/project/example/ble/ble_peripheral/app/src/Mode.c @@ -21,6 +21,7 @@ uint8_t direction = 1; // uint8_t choose_mode_falsg=0; //ģʽֵ uint8_t choose_mode_bh=0; //ģʽ±ä»¯ +static uint8_t mode_entry_initialized; uint16_t Color_table_static[3][2]={ {100,0}, // warm light @@ -113,31 +114,32 @@ void set_mode(){ break; case 6: //ů¹âÌø±ä - W_PWM=Color_table[0][0]; - C_PWM=Color_table[0][1]; + W_PWM=0; + C_PWM=0; driveMode=1;//Çл»ÎªÅ¯¹âµÄµ×²ãÊä³ö - direction=1;//ºôÎü·½Ïò»Ö¸´Ä¬ÈÏÖµ + direction=0;//ºôÎü·½Ïò»Ö¸´Ä¬ÈÏÖµ Mode=mode2; break; case 7: //ÖÐÐÔ¹âÌø±ä - W_PWM=Color_table[1][0]; - C_PWM=Color_table[1][1]; + W_PWM=0; + C_PWM=0; driveMode=0;//Çл»ÎªÖÐÐÔ¹âµÄµ×²ãÊä³ö + direction=0; Mode=mode2; break; case 8: //Àä¹âÌø±ä - W_PWM=Color_table[2][0]; - C_PWM=Color_table[2][1]; + W_PWM=0; + C_PWM=0; driveMode=2;//Çл»ÎªÖÐÐÔ¹âµÄµ×²ãÊä³ö - direction=1;//ºôÎü·½Ïò»Ö¸´Ä¬ÈÏÖµ + direction=0;//ºôÎü·½Ïò»Ö¸´Ä¬ÈÏÖµ Mode=mode2; break; case 9: //ů¹âÖÐÐÔ¹âÀä½»ÌæÌø±ä£¬ÏÈ´Óů¹âÌø±ä - W_PWM=Color_table[0][0]; - C_PWM=Color_table[0][1]; + W_PWM=0; + C_PWM=0; driveMode=1;//Çл»ÎªÅ¯¹âµÄµ×²ãÊä³ö direction=1;//ºôÎü·½Ïò»Ö¸´Ä¬ÈÏÖµ Mode=mode2; @@ -147,6 +149,15 @@ void set_mode(){ Mode=mode0; break; } + if(mode_entry_initialized) + { + Light_Transition_BeginModeChange(); + startTimer(&timer1,1); + } + else + { + mode_entry_initialized=1; + } } } void Mode0(){ //³£Á¿ @@ -353,6 +364,7 @@ pfunc modefunctin[] = { //ģʽ Mode3, }; void choice_mode(){ + if(Light_Transition_ModeActive) return; if (!timer1.active && timer1.count == 0){ if(Mode==mode0){ startTimer(&timer1,1); diff --git a/project/example/ble/ble_peripheral/app/src/light_transition.c b/project/example/ble/ble_peripheral/app/src/light_transition.c index 450b49e..4ad7784 100644 --- a/project/example/ble/ble_peripheral/app/src/light_transition.c +++ b/project/example/ble/ble_peripheral/app/src/light_transition.c @@ -3,11 +3,13 @@ #include "light_transition.h" volatile uint8_t Light_Transition_FadeActive; +volatile uint8_t Light_Transition_ModeActive; volatile uint32_t Light_Transition_W_Output_Q12; volatile uint32_t Light_Transition_C_Output_Q12; #define BRIGHTNESS_SMOOTH_SHIFT 4U #define OUTPUT_SMOOTH_SHIFT 4U +#define MODE_TRANSITION_TICKS 40U #define LIGHT_OUTPUT_SCALE 1000U #define BREATH_MIN_OUTPUT (LIGHT_OUTPUT_SCALE / 100U) #define DUAL_MIN_STABLE_CHANNEL_OUTPUT 102U @@ -81,6 +83,9 @@ static uint16_t power_fade_progress_q12; static uint16_t power_fade_remainder; static uint8_t power_fade_direction; static uint8_t transition_sync_pending; +static uint16_t mode_transition_start_w; +static uint16_t mode_transition_start_c; +static uint8_t mode_transition_tick; static uint16_t brightness_scale_for_level(uint8_t level) { @@ -142,6 +147,35 @@ static uint16_t approach_target(uint16_t current, uint16_t target) return current - step; } +static uint16_t interpolate_mode_output(uint16_t start, uint16_t target, + uint8_t tick) +{ + uint32_t delta; + + if(tick >= MODE_TRANSITION_TICKS) return target; + if(target >= start) + { + delta = (uint32_t)(target - start) * tick; + return (uint16_t)(start + + ((delta + (MODE_TRANSITION_TICKS / 2U)) / + MODE_TRANSITION_TICKS)); + } + + delta = (uint32_t)(start - target) * tick; + return (uint16_t)(start - + ((delta + (MODE_TRANSITION_TICKS / 2U)) / + MODE_TRANSITION_TICKS)); +} + +static uint16_t effect_gamma_output(uint16_t level) +{ + if(level == 0U) return 0U; + if(level > 100U) level = 100U; + return (uint16_t)( + ((uint32_t)brightness_gamma_q12[level - 1U] * + LIGHT_OUTPUT_SCALE + 2048U) >> 12); +} + static uint16_t power_fade_scale(uint16_t progress_q12) { uint32_t position; @@ -220,6 +254,14 @@ void Light_Transition_SyncBrightness(uint8_t level) transition_sync_pending = 1U; } +void Light_Transition_BeginModeChange(void) +{ + mode_transition_start_w = W_PWM_duty; + mode_transition_start_c = C_PWM_duty; + mode_transition_tick = 0U; + Light_Transition_ModeActive = 1U; +} + void Light_Transition_Task(void) { uint8_t powered_on = deviceStatus != POWEROFF; @@ -236,6 +278,9 @@ void Light_Transition_Task(void) uint32_t scaled_c_q12; uint8_t power_transitioning; + if(!powered_on) + Light_Transition_ModeActive = 0U; + /* * Keep APP brightness tracking while off. Power fading is a separate * envelope, so on/off duration does not change with the saved brightness. @@ -251,12 +296,24 @@ void Light_Transition_Task(void) powered_on ? (power_fade_progress_q12 < POWER_FADE_Q12_MAX) : (power_fade_progress_q12 != 0U); - target_w = - (uint16_t)(((uint32_t)W_PWM * brightness_scale * - (LIGHT_OUTPUT_SCALE / 100U) + 2048U) >> 12); - target_c = - (uint16_t)(((uint32_t)C_PWM * brightness_scale * - (LIGHT_OUTPUT_SCALE / 100U) + 2048U) >> 12); + if(Mode == mode1) + { + target_w = (uint16_t)( + ((uint32_t)effect_gamma_output(W_PWM) * + brightness_scale + 2048U) >> 12); + target_c = (uint16_t)( + ((uint32_t)effect_gamma_output(C_PWM) * + brightness_scale + 2048U) >> 12); + } + else + { + target_w = + (uint16_t)(((uint32_t)W_PWM * brightness_scale * + (LIGHT_OUTPUT_SCALE / 100U) + 2048U) >> 12); + target_c = + (uint16_t)(((uint32_t)C_PWM * brightness_scale * + (LIGHT_OUTPUT_SCALE / 100U) + 2048U) >> 12); + } /* * Keep the weaker mixed-light direction at the measured stable threshold. @@ -307,7 +364,19 @@ void Light_Transition_Task(void) target_c = BREATH_MIN_OUTPUT; } - if((Mode == mode2 && powered_on) || power_transitioning || + if(Light_Transition_ModeActive && powered_on && !power_transitioning) + { + mode_transition_tick++; + W_PWM_duty = + interpolate_mode_output(mode_transition_start_w, target_w, + mode_transition_tick); + C_PWM_duty = + interpolate_mode_output(mode_transition_start_c, target_c, + mode_transition_tick); + if(mode_transition_tick >= MODE_TRANSITION_TICKS) + Light_Transition_ModeActive = 0U; + } + else if((Mode == mode2 && powered_on) || power_transitioning || transition_sync_pending) { W_PWM_duty = target_w; diff --git a/project/example/ble/ble_peripheral/app/src/light_transition.h b/project/example/ble/ble_peripheral/app/src/light_transition.h index 29baf41..7505998 100644 --- a/project/example/ble/ble_peripheral/app/src/light_transition.h +++ b/project/example/ble/ble_peripheral/app/src/light_transition.h @@ -4,6 +4,7 @@ #include extern volatile uint8_t Light_Transition_FadeActive; +extern volatile uint8_t Light_Transition_ModeActive; extern volatile uint32_t Light_Transition_W_Output_Q12; extern volatile uint32_t Light_Transition_C_Output_Q12; @@ -12,5 +13,6 @@ extern volatile uint32_t Light_Transition_C_Output_Q12; void Light_Transition_Task(void); void Light_Transition_SyncBrightness(uint8_t level); +void Light_Transition_BeginModeChange(void); #endif